View | Details | Raw Unified | Return to bug 1295 | Differences between
and this patch

Collapse All | Expand All

(-)channels.c (+42 lines)
Lines 1131-1136 channel_decode_socks5(Channel *c, fd_set Link Here
1131
	return 1;
1131
	return 1;
1132
}
1132
}
1133
1133
1134
/* ARGSUSED */
1135
static int
1136
channel_decode_transparent(Channel *c, fd_set *readset, fd_set *writeset)
1137
{
1138
	int ret;
1139
	struct sockaddr *sa;
1140
1141
	if ((sa = lookup_transparent_sock(c->sock)) == NULL)
1142
		return -1;
1143
1144
	switch (sa->sa_family) {
1145
	case AF_INET:
1146
		c->host_port = ntohs(((struct sockaddr_in *)sa)->sin_port);
1147
		break;
1148
	case AF_INET6:
1149
		c->host_port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
1150
		break;
1151
	default:
1152
		debug("channel %d: transparent proxy of address family %d "
1153
		    "not supported", c->self, sa->sa_family);
1154
		return -1;
1155
	}
1156
1157
	ret = getnameinfo(sa, sizeof(*sa), c->path, sizeof(c->path), NULL, 0,
1158
	    NI_NUMERICHOST|NI_NUMERICSERV);
1159
	if (ret == -1) {
1160
		error("channel_decode_transparent: getnameinfo: %s",
1161
		   (ret != EAI_SYSTEM) ? gai_strerror(ret) : strerror(errno));
1162
		return -1;
1163
	}
1164
1165
	debug2("channel %d: dynamic request: transparent host %s port %u",
1166
	    c->self, c->path, c->host_port);
1167
	c->delayed = 0;
1168
	c->type = SSH_CHANNEL_OPENING;
1169
	port_open_helper(c, "direct-tcpip");
1170
	return 0;
1171
}
1172
1134
/* dynamic port forwarding */
1173
/* dynamic port forwarding */
1135
static void
1174
static void
1136
channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
1175
channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
Lines 1139-1144 channel_pre_dynamic(Channel *c, fd_set * Link Here
1139
	u_int have;
1178
	u_int have;
1140
	int ret;
1179
	int ret;
1141
1180
1181
	if (channel_decode_transparent(c, readset, writeset) == 0)
1182
		return;
1183
1142
	have = buffer_len(&c->input);
1184
	have = buffer_len(&c->input);
1143
	c->delayed = 0;
1185
	c->delayed = 0;
1144
	debug2("channel %d: pre_dynamic: have %d", c->self, have);
1186
	debug2("channel %d: pre_dynamic: have %d", c->self, have);
(-)configure.ac (+29 lines)
Lines 518-523 main() { if (NSVersionOfRunTimeLibrary(" Link Here
518
		AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
518
		AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
519
		    [Prepend the address family to IP tunnel traffic])
519
		    [Prepend the address family to IP tunnel traffic])
520
	fi
520
	fi
521
	# transparent dynamic port forwarding
522
	AC_CHECK_HEADERS([linux/netfilter_ipv4.h], [], [],
523
	    [ #include <limits.h> ])
524
	AC_CHECK_DECL(SO_ORIGINAL_DST,
525
	    [
526
		TRANSPROXY=netfilter
527
		AC_DEFINE(TRANSPARENT_PROXY_NETFILTER, 1,
528
		    [Transparent redirection support via netfilter])
529
	    ], [],
530
	    [AC_LANG_SOURCE([[
531
#include <limits.h>
532
#include <linux/netfilter_ipv4.h>
533
	    ]])])
521
	;;
534
	;;
522
mips-sony-bsd|mips-sony-newsos4)
535
mips-sony-bsd|mips-sony-newsos4)
523
	AC_DEFINE(NEED_SETPGRP, 1, [Need setpgrp to acquire controlling tty])
536
	AC_DEFINE(NEED_SETPGRP, 1, [Need setpgrp to acquire controlling tty])
Lines 562-567 mips-sony-bsd|mips-sony-newsos4) Link Here
562
	AC_DEFINE(SSH_TUN_OPENBSD, 1, [Open tunnel devices the OpenBSD way])
575
	AC_DEFINE(SSH_TUN_OPENBSD, 1, [Open tunnel devices the OpenBSD way])
563
	AC_DEFINE(SYSLOG_R_SAFE_IN_SIGHAND, 1,
576
	AC_DEFINE(SYSLOG_R_SAFE_IN_SIGHAND, 1,
564
	    [syslog_r function is safe to use in in a signal handler])
577
	    [syslog_r function is safe to use in in a signal handler])
578
	AC_CHECK_HEADERS([net/pfvar.h], [
579
		TRANSPROXY=pf
580
		AC_DEFINE(TRANSPARENT_PROXY_PF, 1,
581
		    [Transparent redirection support via pf])
582
	    ], [], [AC_LANG_SOURCE([[
583
#include <sys/types.h>
584
#include <sys/socket.h>
585
#include <sys/ioctl.h>
586
#include <sys/fcntl.h>
587
#include <net/if.h>
588
#include <netinet/in.h>
589
#include <net/pfvar.h>
590
	    ]])])
565
	;;
591
	;;
566
*-*-solaris*)
592
*-*-solaris*)
567
	if test "x$withval" != "xno" ; then
593
	if test "x$withval" != "xno" ; then
Lines 3989-3994 echo " TCP Wrappers support Link Here
3989
echo "              MD5 password support: $MD5_MSG"
4015
echo "              MD5 password support: $MD5_MSG"
3990
echo "                   libedit support: $LIBEDIT_MSG"
4016
echo "                   libedit support: $LIBEDIT_MSG"
3991
echo "  Solaris process contract support: $SPC_MSG"
4017
echo "  Solaris process contract support: $SPC_MSG"
4018
if test ! -z "$TRANSPROXY" ; then
4019
echo "         Transparent proxy support: $TRANSPROXY"
4020
fi
3992
echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
4021
echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
3993
echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
4022
echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
3994
echo "                  BSD Auth support: $BSD_AUTH_MSG"
4023
echo "                  BSD Auth support: $BSD_AUTH_MSG"
(-)misc.c (+80 lines)
Lines 27-32 Link Here
27
#include "includes.h"
27
#include "includes.h"
28
28
29
#include <sys/types.h>
29
#include <sys/types.h>
30
#include <sys/fcntl.h>
30
#include <sys/ioctl.h>
31
#include <sys/ioctl.h>
31
#include <sys/socket.h>
32
#include <sys/socket.h>
32
#include <sys/param.h>
33
#include <sys/param.h>
Lines 39-44 Link Here
39
40
40
#include <netinet/in.h>
41
#include <netinet/in.h>
41
#include <netinet/tcp.h>
42
#include <netinet/tcp.h>
43
#ifdef TRANSPARENT_PROXY_PF
44
# include <net/if.h>
45
# include <net/pfvar.h>
46
#endif
42
47
43
#include <errno.h>
48
#include <errno.h>
44
#include <fcntl.h>
49
#include <fcntl.h>
Lines 262-267 a2tun(const char *s, int *remote) Link Here
262
	return (tun);
267
	return (tun);
263
}
268
}
264
269
270
/*
271
 * Look up a transparently redirected socket's original address.
272
 * Returns sockaddr pointer representing original address or NULL if
273
 * if not redirected.
274
 */
275
struct sockaddr *
276
lookup_transparent_sock(int fd)
277
{
278
#if defined(TRANSPARENT_PROXY_NETFILTER)
279
	return netfilter_lookup_transparent_sock(fd);
280
#elif defined(TRANSPARENT_PROXY_PF)
281
	int devfd, ret;
282
	struct pfioc_natlook nl;
283
	static struct sockaddr la;
284
	struct sockaddr sa;
285
	struct sockaddr_in *sa_in, *la_in;
286
	socklen_t slen = sizeof(sa), llen = sizeof(la);
287
288
	/* get local addrinfo */
289
	if (getsockname(fd, &la, &llen) == -1) {
290
		error("lookup_transparent_sock: getsockname: %s",
291
		    strerror(errno));
292
		return NULL;
293
	}
294
295
	/* get remote addrinfo */
296
	if (getpeername(fd, &sa, &slen) == -1) {
297
		error("lookup_transparent_sock: getpeername: %s",
298
		    strerror(errno));
299
		return NULL;
300
	}
301
302
	memset(&nl, 0, sizeof(nl));
303
	nl.direction = PF_OUT;
304
	nl.af = sa.sa_family;
305
	nl.proto = IPPROTO_TCP;
306
	switch (sa.sa_family) {
307
	case AF_INET:
308
		la_in = (struct sockaddr_in *)&la;
309
		sa_in = (struct sockaddr_in *)&sa;
310
		nl.saddr.v4.s_addr = sa_in->sin_addr.s_addr;
311
		nl.sport = sa_in->sin_port;
312
		nl.daddr.v4.s_addr = la_in->sin_addr.s_addr;
313
		nl.dport = la_in->sin_port;
314
		break;
315
	case AF_INET6:
316
		return NULL;	/* TODO */
317
	default:
318
		return NULL;
319
	}
320
321
	/* lookup redirected connection */
322
	if ((devfd = open("/dev/pf", O_RDWR)) == -1) {
323
		debug("lookup_transparent_sock: could not open /dev/pf: %s",
324
		    strerror(errno));
325
		return NULL;
326
	}
327
	ret = ioctl(devfd, DIOCNATLOOK, &nl);
328
	close(devfd);
329
	if (ret == -1) {
330
		if (errno != ENOENT)
331
			error("lookup_transparent_sock: pf lookup failed: %s",
332
			    strerror(errno));
333
		return NULL;
334
	}
335
336
	/* copy translated values and return */
337
	la_in->sin_addr.s_addr = nl.rdaddr.v4.s_addr;
338
	la_in->sin_port = nl.rdport;
339
	return &la;
340
#else
341
	return NULL;
342
#endif
343
}
344
265
#define SECONDS		1
345
#define SECONDS		1
266
#define MINUTES		(SECONDS * 60)
346
#define MINUTES		(SECONDS * 60)
267
#define HOURS		(MINUTES * 60)
347
#define HOURS		(MINUTES * 60)
(-)misc.h (+2 lines)
Lines 87-90 char *read_passphrase(const char *, int) Link Here
87
int	 ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
87
int	 ask_permission(const char *, ...) __attribute__((format(printf, 1, 2)));
88
int	 read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
88
int	 read_keyfile_line(FILE *, const char *, char *, size_t, u_long *);
89
89
90
struct sockaddr *lookup_transparent_sock(int);
91
90
#endif /* _MISC_H */
92
#endif /* _MISC_H */
(-)openbsd-compat/port-linux.c (-2 / +45 lines)
Lines 18-24 Link Here
18
 */
18
 */
19
19
20
/*
20
/*
21
 * Linux-specific portability code - just SELinux support at present
21
 * Linux-specific portability code.
22
 */
22
 */
23
23
24
#include "includes.h"
24
#include "includes.h"
Lines 27-35 Link Here
27
#include <stdarg.h>
27
#include <stdarg.h>
28
#include <string.h>
28
#include <string.h>
29
29
30
#include "port-linux.h"
31
32
#ifdef TRANSPARENT_PROXY_NETFILTER
33
# include <limits.h>
34
# include <linux/netfilter_ipv4.h>
35
#endif
36
30
#ifdef WITH_SELINUX
37
#ifdef WITH_SELINUX
31
#include "log.h"
38
#include "log.h"
32
#include "port-linux.h"
33
39
34
#include <selinux/selinux.h>
40
#include <selinux/selinux.h>
35
#include <selinux/flask.h>
41
#include <selinux/flask.h>
Lines 167-169 ssh_selinux_setup_pty(char *pwname, cons Link Here
167
	debug3("%s: done", __func__);
173
	debug3("%s: done", __func__);
168
}
174
}
169
#endif /* WITH_SELINUX */
175
#endif /* WITH_SELINUX */
176
177
#if defined(TRANSPARENT_PROXY_NETFILTER)
178
/*
179
 * Look up a transparently redirected socket's original address.
180
 * Returns sockaddr pointer representing original address or NULL if
181
 * if not redirected.
182
 */
183
struct sockaddr *
184
netfilter_lookup_transparent_sock(int fd)
185
{
186
	static struct sockaddr oa;	/* original destination address */
187
	struct sockaddr sa;		/* redirected destination address */
188
	struct sockaddr_in *oa_in, *sa_in;
189
	socklen_t olen, slen;
190
191
	slen = olen = sizeof(struct sockaddr);
192
	if (getsockopt(fd, SOL_IP, SO_ORIGINAL_DST, &oa, &olen) == -1 ||
193
	    getsockname(fd, &sa, &slen) == -1  || oa.sa_family != sa.sa_family)
194
		return NULL;
195
196
	switch (oa.sa_family) {
197
	case AF_INET:
198
		oa_in = (struct sockaddr_in *)&oa;
199
		sa_in = (struct sockaddr_in *)&sa;
200
		if (oa_in->sin_addr.s_addr == INADDR_ANY ||
201
		    oa_in->sin_addr.s_addr == INADDR_NONE ||
202
		    (oa_in->sin_family == sa_in->sin_family &&
203
		    oa_in->sin_addr.s_addr == sa_in->sin_addr.s_addr &&
204
		    oa_in->sin_port == sa_in->sin_port))
205
			return NULL;
206
		return &oa;
207
	case AF_INET6:
208
		return NULL; /* XXX */
209
	}
210
	return NULL;
211
}
212
#endif
(-)openbsd-compat/port-linux.h (+4 lines)
Lines 24-27 void ssh_selinux_setup_pty(char *, const Link Here
24
void ssh_selinux_setup_exec_context(char *);
24
void ssh_selinux_setup_exec_context(char *);
25
#endif
25
#endif
26
26
27
#ifdef TRANSPARENT_PROXY_NETFILTER
28
struct sockaddr *netfilter_lookup_transparent_sock(int);
29
#endif
30
27
#endif /* ! _PORT_LINUX_H */
31
#endif /* ! _PORT_LINUX_H */

Return to bug 1295