From 7ebf441270fba2c9f6c8d15647cab6faad746359 Mon Sep 17 00:00:00 2001 From: jbasney Date: Wed, 26 Jul 2006 21:29:48 +0000 Subject: [PATCH] merge new file to gpt branch --- openssh/README.tun | 132 ++++++++++++++ openssh/contrib/suse/sysconfig.ssh | 9 + openssh/openbsd-compat/bsd-asprintf.c | 95 ++++++++++ openssh/openbsd-compat/port-tun.c | 252 ++++++++++++++++++++++++++ openssh/openbsd-compat/port-tun.h | 33 ++++ 5 files changed, 521 insertions(+) create mode 100644 openssh/README.tun create mode 100644 openssh/contrib/suse/sysconfig.ssh create mode 100644 openssh/openbsd-compat/bsd-asprintf.c create mode 100644 openssh/openbsd-compat/port-tun.c create mode 100644 openssh/openbsd-compat/port-tun.h diff --git a/openssh/README.tun b/openssh/README.tun new file mode 100644 index 0000000..d814f39 --- /dev/null +++ b/openssh/README.tun @@ -0,0 +1,132 @@ +How to use OpenSSH-based virtual private networks +------------------------------------------------- + +OpenSSH contains support for VPN tunneling using the tun(4) network +tunnel pseudo-device which is available on most platforms, either for +layer 2 or 3 traffic. + +The following brief instructions on how to use this feature use +a network configuration specific to the OpenBSD operating system. + +(1) Server: Enable support for SSH tunneling + +To enable the ssh server to accept tunnel requests from the client, you +have to add the following option to the ssh server configuration file +(/etc/ssh/sshd_config): + + PermitTunnel yes + +Restart the server or send the hangup signal (SIGHUP) to let the server +reread it's configuration. + +(2) Server: Restrict client access and assign the tunnel + +The OpenSSH server simply uses the file /root/.ssh/authorized_keys to +restrict the client to connect to a specified tunnel and to +automatically start the related interface configuration command. These +settings are optional but recommended: + + tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... reyk@openbsd.org + +(3) Client: Configure the local network tunnel interface + +Use the hostname.if(5) interface-specific configuration file to set up +the network tunnel configuration with OpenBSD. For example, use the +following configuration in /etc/hostname.tun0 to set up the layer 3 +tunnel on the client: + + inet 192.168.5.1 255.255.255.252 192.168.5.2 + +OpenBSD also supports layer 2 tunneling over the tun device by adding +the link0 flag: + + inet 192.168.1.78 255.255.255.0 192.168.1.255 link0 + +Layer 2 tunnels can be used in combination with an Ethernet bridge(4) +interface, like the following example for /etc/bridgename.bridge0: + + add tun0 + add sis0 + up + +(4) Client: Configure the OpenSSH client + +To establish tunnel forwarding for connections to a specified +remote host by default, use the following ssh client configuration for +the privileged user (in /root/.ssh/config): + + Host sshgateway + Tunnel yes + TunnelDevice 0:any + PermitLocalCommand yes + LocalCommand sh /etc/netstart tun0 + +A more complicated configuration is possible to establish a tunnel to +a remote host which is not directly accessible by the client. +The following example describes a client configuration to connect to +the remote host over two ssh hops in between. It uses the OpenSSH +ProxyCommand in combination with the nc(1) program to forward the final +ssh tunnel destination over multiple ssh sessions. + + Host access.somewhere.net + User puffy + Host dmzgw + User puffy + ProxyCommand ssh access.somewhere.net nc dmzgw 22 + Host sshgateway + Tunnel Ethernet + TunnelDevice 0:any + PermitLocalCommand yes + LocalCommand sh /etc/netstart tun0 + ProxyCommand ssh dmzgw nc sshgateway 22 + +The following network plan illustrates the previous configuration in +combination with layer 2 tunneling and Ethernet bridging. + ++--------+ ( ) +----------------------+ +| Client |------( Internet )-----| access.somewhere.net | ++--------+ ( ) +----------------------+ + : 192.168.1.78 | + :............................. +-------+ + Forwarded ssh connection : | dmzgw | + Layer 2 tunnel : +-------+ + : | + : | + : +------------+ + :......| sshgateway | + | +------------+ +--- real connection Bridge -> | +----------+ +... "virtual connection" [ X ]--------| somehost | +[X] switch +----------+ + 192.168.1.25 + +(5) Client: Connect to the server and establish the tunnel + +Finally connect to the OpenSSH server to establish the tunnel by using +the following command: + + ssh sshgateway + +It is also possible to tell the client to fork into the background after +the connection has been successfully established: + + ssh -f sshgateway true + +Without the ssh configuration done in step (4), it is also possible +to use the following command lines: + + ssh -fw 0:1 sshgateway true + ifconfig tun0 192.168.5.1 192.168.5.2 netmask 255.255.255.252 + +Using OpenSSH tunnel forwarding is a simple way to establish secure +and ad hoc virtual private networks. Possible fields of application +could be wireless networks or administrative VPN tunnels. + +Nevertheless, ssh tunneling requires some packet header overhead and +runs on top of TCP. It is still suggested to use the IP Security +Protocol (IPSec) for robust and permanent VPN connections and to +interconnect corporate networks. + + Reyk Floeter + +$OpenBSD: README.tun,v 1.3 2005/12/08 18:34:10 reyk Exp $ diff --git a/openssh/contrib/suse/sysconfig.ssh b/openssh/contrib/suse/sysconfig.ssh new file mode 100644 index 0000000..c6a37e5 --- /dev/null +++ b/openssh/contrib/suse/sysconfig.ssh @@ -0,0 +1,9 @@ +## Path: Network/Remote access/SSH +## Description: SSH server settings +## Type: string +## Default: "" +## ServiceRestart: sshd +# +# Options for sshd +# +SSHD_OPTS="" diff --git a/openssh/openbsd-compat/bsd-asprintf.c b/openssh/openbsd-compat/bsd-asprintf.c new file mode 100644 index 0000000..5ca01f8 --- /dev/null +++ b/openssh/openbsd-compat/bsd-asprintf.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2004 Darren Tucker. + * + * Based originally on asprintf.c from OpenBSD: + * Copyright (c) 1997 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifndef HAVE_VASPRINTF + +#ifndef VA_COPY +# ifdef HAVE_VA_COPY +# define VA_COPY(dest, src) va_copy(dest, src) +# else +# ifdef HAVE___VA_COPY +# define VA_COPY(dest, src) __va_copy(dest, src) +# else +# define VA_COPY(dest, src) (dest) = (src) +# endif +# endif +#endif + +#define INIT_SZ 128 + +int vasprintf(char **str, const char *fmt, va_list ap) +{ + int ret = -1; + va_list ap2; + char *string, *newstr; + size_t len; + + VA_COPY(ap2, ap); + if ((string = malloc(INIT_SZ)) == NULL) + goto fail; + + ret = vsnprintf(string, INIT_SZ, fmt, ap2); + if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */ + *str = string; + } else if (ret == INT_MAX) { /* shouldn't happen */ + goto fail; + } else { /* bigger than initial, realloc allowing for nul */ + len = (size_t)ret + 1; + if ((newstr = realloc(string, len)) == NULL) { + free(string); + goto fail; + } else { + va_end(ap2); + VA_COPY(ap2, ap); + ret = vsnprintf(newstr, len, fmt, ap2); + if (ret >= 0 && (size_t)ret < len) { + *str = newstr; + } else { /* failed with realloc'ed string, give up */ + free(newstr); + goto fail; + } + } + } + va_end(ap2); + return (ret); + +fail: + *str = NULL; + errno = ENOMEM; + va_end(ap2); + return (-1); +} +#endif + +#ifndef HAVE_ASPRINTF +int asprintf(char **str, const char *fmt, ...) +{ + va_list ap; + int ret; + + *str = NULL; + va_start(ap, fmt); + ret = vasprintf(str, fmt, ap); + va_end(ap); + + return ret; +} +#endif diff --git a/openssh/openbsd-compat/port-tun.c b/openssh/openbsd-compat/port-tun.c new file mode 100644 index 0000000..3192161 --- /dev/null +++ b/openssh/openbsd-compat/port-tun.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2005 Reyk Floeter + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include "log.h" +#include "misc.h" +#include "bufaux.h" + +/* + * This is the portable version of the SSH tunnel forwarding, it + * uses some preprocessor definitions for various platform-specific + * settings. + * + * SSH_TUN_LINUX Use the (newer) Linux tun/tap device + * SSH_TUN_COMPAT_AF Translate the OpenBSD address family + * SSH_TUN_PREPEND_AF Prepend/remove the address family + */ + +/* + * System-specific tunnel open function + */ + +#if defined(SSH_TUN_LINUX) +#include +#include + +int +sys_tun_open(int tun, int mode) +{ + struct ifreq ifr; + int fd = -1; + const char *name = NULL; + + if ((fd = open("/dev/net/tun", O_RDWR)) == -1) { + debug("%s: failed to open tunnel control interface: %s", + __func__, strerror(errno)); + return (-1); + } + + bzero(&ifr, sizeof(ifr)); + + if (mode == SSH_TUNMODE_ETHERNET) { + ifr.ifr_flags = IFF_TAP; + name = "tap%d"; + } else { + ifr.ifr_flags = IFF_TUN; + name = "tun%d"; + } + ifr.ifr_flags |= IFF_NO_PI; + + if (tun != SSH_TUNID_ANY) { + if (tun > SSH_TUNID_MAX) { + debug("%s: invalid tunnel id %x: %s", __func__, + tun, strerror(errno)); + goto failed; + } + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), name, tun); + } + + if (ioctl(fd, TUNSETIFF, &ifr) == -1) { + debug("%s: failed to configure tunnel (mode %d): %s", __func__, + mode, strerror(errno)); + goto failed; + } + + if (tun == SSH_TUNID_ANY) + debug("%s: tunnel mode %d fd %d", __func__, mode, fd); + else + debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd); + + return (fd); + + failed: + close(fd); + return (-1); +} +#endif /* SSH_TUN_LINUX */ + +#ifdef SSH_TUN_FREEBSD +#include +#include +#include + +int +sys_tun_open(int tun, int mode) +{ + struct ifreq ifr; + char name[100]; + int fd = -1, sock, flag; + const char *tunbase = "tun"; + + if (mode == SSH_TUNMODE_ETHERNET) { +#ifdef SSH_TUN_NO_L2 + debug("%s: no layer 2 tunnelling support", __func__); + return (-1); +#else + tunbase = "tap"; +#endif + } + + /* Open the tunnel device */ + if (tun <= SSH_TUNID_MAX) { + snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun); + fd = open(name, O_RDWR); + } else if (tun == SSH_TUNID_ANY) { + for (tun = 100; tun >= 0; tun--) { + snprintf(name, sizeof(name), "/dev/%s%d", + tunbase, tun); + if ((fd = open(name, O_RDWR)) >= 0) + break; + } + } else { + debug("%s: invalid tunnel %u\n", __func__, tun); + return (-1); + } + + if (fd < 0) { + debug("%s: %s open failed: %s", __func__, name, + strerror(errno)); + return (-1); + } + + /* Turn on tunnel headers */ + flag = 1; +#if defined(TUNSIFHEAD) && !defined(SSH_TUN_PREPEND_AF) + if (mode != SSH_TUNMODE_ETHERNET && + ioctl(fd, TUNSIFHEAD, &flag) == -1) { + debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd, + strerror(errno)); + close(fd); + } +#endif + + debug("%s: %s mode %d fd %d", __func__, name, mode, fd); + + /* Set the tunnel device operation mode */ + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun); + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + goto failed; + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + goto failed; + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; + + close(sock); + return (fd); + + failed: + if (fd >= 0) + close(fd); + if (sock >= 0) + close(sock); + debug("%s: failed to set %s mode %d: %s", __func__, name, + mode, strerror(errno)); + return (-1); +} +#endif /* SSH_TUN_FREEBSD */ + +/* + * System-specific channel filters + */ + +#if defined(SSH_TUN_FILTER) +#define OPENBSD_AF_INET 2 +#define OPENBSD_AF_INET6 24 + +int +sys_tun_infilter(struct Channel *c, char *buf, int len) +{ +#if defined(SSH_TUN_PREPEND_AF) + char rbuf[CHAN_RBUF]; + struct ip *iph; +#endif + u_int32_t *af; + char *ptr = buf; + +#if defined(SSH_TUN_PREPEND_AF) + if (len <= 0 || len > (int)(sizeof(rbuf) - sizeof(*af))) + return (-1); + ptr = (char *)&rbuf[0]; + bcopy(buf, ptr + sizeof(u_int32_t), len); + len += sizeof(u_int32_t); + af = (u_int32_t *)ptr; + + iph = (struct ip *)(ptr + sizeof(u_int32_t)); + switch (iph->ip_v) { + case 6: + *af = AF_INET6; + break; + case 4: + default: + *af = AF_INET; + break; + } +#endif + +#if defined(SSH_TUN_COMPAT_AF) + if (len < (int)sizeof(u_int32_t)) + return (-1); + + af = (u_int32_t *)ptr; + if (*af == htonl(AF_INET6)) + *af = htonl(OPENBSD_AF_INET6); + else + *af = htonl(OPENBSD_AF_INET); +#endif + + buffer_put_string(&c->input, ptr, len); + return (0); +} + +u_char * +sys_tun_outfilter(struct Channel *c, u_char **data, u_int *dlen) +{ + u_char *buf; + u_int32_t *af; + + *data = buffer_get_string(&c->output, dlen); + if (*dlen < sizeof(*af)) + return (NULL); + buf = *data; + +#if defined(SSH_TUN_PREPEND_AF) + *dlen -= sizeof(u_int32_t); + buf = *data + sizeof(u_int32_t); +#elif defined(SSH_TUN_COMPAT_AF) + af = ntohl(*(u_int32_t *)buf); + if (*af == OPENBSD_AF_INET6) + *af = htonl(AF_INET6); + else + *af = htonl(AF_INET); +#endif + + return (buf); +} +#endif /* SSH_TUN_FILTER */ diff --git a/openssh/openbsd-compat/port-tun.h b/openssh/openbsd-compat/port-tun.h new file mode 100644 index 0000000..86d9272 --- /dev/null +++ b/openssh/openbsd-compat/port-tun.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Reyk Floeter + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PORT_TUN_H +#define _PORT_TUN_H + +#include "channels.h" + +#if defined(SSH_TUN_LINUX) || defined(SSH_TUN_FREEBSD) +# define CUSTOM_SYS_TUN_OPEN +int sys_tun_open(int, int); +#endif + +#if defined(SSH_TUN_COMPAT_AF) || defined(SSH_TUN_PREPEND_AF) +# define SSH_TUN_FILTER +int sys_tun_infilter(struct Channel *, char *, int); +u_char *sys_tun_outfilter(struct Channel *, u_char **, u_int *); +#endif + +#endif -- 2.45.1