aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x._CHANGELOGbin1505 -> 0 bytes
-rwxr-xr-x._LICENSEbin167 -> 0 bytes
-rwxr-xr-x._READMEbin1505 -> 0 bytes
-rwxr-xr-x._ptunnel.8bin167 -> 0 bytes
-rwxr-xr-x._ptunnel.cbin167 -> 0 bytes
-rwxr-xr-x._ptunnel.hbin167 -> 0 bytes
-rw-r--r--.pc/.quilt_patches1
-rw-r--r--.pc/.quilt_series1
-rw-r--r--.pc/.version1
-rwxr-xr-x.pc/add_hardening_flags.diff/Makefile55
-rw-r--r--.pc/applied-patches4
-rwxr-xr-x.pc/fix_minus_chars_in_man.patch/ptunnel.8123
-rwxr-xr-x.pc/fix_typo.diff/README118
-rwxr-xr-x.pc/makefile-debian-prefix.patch/Makefile55
-rwxr-xr-xMakefile6
-rw-r--r--base64.c109
-rw-r--r--base64.h8
-rw-r--r--options.c226
-rw-r--r--options.h60
-rwxr-xr-xptunnel.c16
-rwxr-xr-xptunnel.h77
-rw-r--r--utils.h6
22 files changed, 462 insertions, 404 deletions
diff --git a/._CHANGELOG b/._CHANGELOG
deleted file mode 100755
index c99a132..0000000
--- a/._CHANGELOG
+++ /dev/null
Binary files differ
diff --git a/._LICENSE b/._LICENSE
deleted file mode 100755
index 1fdbfdc..0000000
--- a/._LICENSE
+++ /dev/null
Binary files differ
diff --git a/._README b/._README
deleted file mode 100755
index 86f9c18..0000000
--- a/._README
+++ /dev/null
Binary files differ
diff --git a/._ptunnel.8 b/._ptunnel.8
deleted file mode 100755
index 2cbd7e8..0000000
--- a/._ptunnel.8
+++ /dev/null
Binary files differ
diff --git a/._ptunnel.c b/._ptunnel.c
deleted file mode 100755
index 63e1130..0000000
--- a/._ptunnel.c
+++ /dev/null
Binary files differ
diff --git a/._ptunnel.h b/._ptunnel.h
deleted file mode 100755
index 63e1130..0000000
--- a/._ptunnel.h
+++ /dev/null
Binary files differ
diff --git a/.pc/.quilt_patches b/.pc/.quilt_patches
deleted file mode 100644
index 6857a8d..0000000
--- a/.pc/.quilt_patches
+++ /dev/null
@@ -1 +0,0 @@
-debian/patches
diff --git a/.pc/.quilt_series b/.pc/.quilt_series
deleted file mode 100644
index c206706..0000000
--- a/.pc/.quilt_series
+++ /dev/null
@@ -1 +0,0 @@
-series
diff --git a/.pc/.version b/.pc/.version
deleted file mode 100644
index 0cfbf08..0000000
--- a/.pc/.version
+++ /dev/null
@@ -1 +0,0 @@
-2
diff --git a/.pc/add_hardening_flags.diff/Makefile b/.pc/add_hardening_flags.diff/Makefile
deleted file mode 100755
index 01612d7..0000000
--- a/.pc/add_hardening_flags.diff/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# Makefile for the pingtunnel utility
-# (c) 2004-2009 Daniel Stoedle, daniels@cs.uit.no
-# ptunnel.exe target added by Mike Miller, mike@mikeage.net
-
-CC = gcc
-CFLAGS = -Wall -g
-LDOPTS = -lpthread -lpcap
-PT_OBJS = ptunnel.o md5.o
-
-WIN32_CC = mingw32-gcc
-WIN32_CFLAGS = -g -Wall -DWIN32 -I"c:\Program Files\WpdPack\Include"
-WIN32_LDOPTS = -lwpcap -lwsock32 -L"c:\Program Files\WpdPack\Lib"
-WIN32_PT_OBJS = ptunnel.obj md5.obj
-
-prefix = /usr
-bindir = $(prefix)/bin
-mandir = $(prefix)/share/man/man8
-
-all: ptunnel
-
-dist:
- rm -rf PingTunnel/
- mkdir PingTunnel
- cp ptunnel.c ptunnel.h Makefile.dist PingTunnel/
- mv PingTunnel/Makefile.dist PingTunnel/Makefile
-
-
-install: ptunnel
- install -d $(bindir)/
- install -d $(mandir)/
- install ./ptunnel $(bindir)/ptunnel
- install ./ptunnel.8 $(mandir)/ptunnel.8
-
-ptunnel: $(PT_OBJS)
- $(CC) -o $@ $^ $(LDOPTS) `[ -e /usr/include/selinux/selinux.h ] && echo -lselinux`
-
-ptunnel.exe: $(WIN32_PT_OBJS)
- $(CC) -o $@ $^ $(WIN32_LDOPTS)
-
-clean:
- -rm -f *.o ptunnel
- -rm -f *.obj ptunnel.exe
- -rm -f .depend
-
-depend: .depend
-.depend:
- $(CC) $(CFLAGS) -MM *.c > $@
-
-%.o:%.c
- $(CC) $(CFLAGS) `[ -e /usr/include/selinux/selinux.h ] && echo -DHAVE_SELINUX` -c -o $@ $<
-
-%.obj:%.c
- $(WIN32_CC) $(WIN32_CFLAGS) -c -o $@ $<
-
--include .depend
diff --git a/.pc/applied-patches b/.pc/applied-patches
deleted file mode 100644
index 9a8f77a..0000000
--- a/.pc/applied-patches
+++ /dev/null
@@ -1,4 +0,0 @@
-add_hardening_flags.diff
-fix_typo.diff
-fix_minus_chars_in_man.patch
-makefile-debian-prefix.patch
diff --git a/.pc/fix_minus_chars_in_man.patch/ptunnel.8 b/.pc/fix_minus_chars_in_man.patch/ptunnel.8
deleted file mode 100755
index dff91e5..0000000
--- a/.pc/fix_minus_chars_in_man.patch/ptunnel.8
+++ /dev/null
@@ -1,123 +0,0 @@
-.TH ptunnel 8 "September 5, 2011" "Version 0.72" "Yellow Lemon Software"
-.SH NAME
-ptunnel \- tunnel TCP connections over ICMP echo request/reply packets.
-.SH SYNOPSIS
-.B ptunnel
-\-p proxy_address \-lp listen_port \-da destination_address \-dp dest_port [\-c network_device] [\-v verbosity] [-f file] [-udp] [-syslog]
-
-.B ptunnel
-[\-c network_device] [\-v verbosity] [\-f file] [\-udp] [\-syslog] [\-daemon file]
-
-.B ptunnel
-[\-u] [\-x password] [\-setuid user] [\-setgid group] [\-chroot dir] [\-setcon context]
-
-.B ptunnel
-\-h
-.SH DESCRIPTION
-ptunnel is an application that allows you to reliably tunnel TCP connections to a remote host using ICMP echo request and reply packets, commonly known as ping requests and replies. At first glance, this might seem like a rather useless thing to do, but it can actually come in handy in some cases. The following example illustrates the main motivation in creating ptunnel:
-.PP
-Setting: You're on the go, and stumble across an open wireless network. The network gives you an IP address, but won't let you send TCP or UDP packets out to the rest of the internet, for instance to check your mail. What to do? By chance, you discover that the network will allow you to ping any computer on the rest of the internet. With ptunnel, you can utilize this feature to check your mail, or do other things that require TCP.
-.SH OPTIONS
-.TP
-.SH Client options:
-.TP
-.B \-p proxy_address
-Specify the host on which the proxy is running.
-.TP
-.B \-lp listen_port
-Specifies the port on which the client will listen for incoming TCP connections.
-.TP
-.B \-da destination_addr
-Specifies the address to which you want your packets tunneled after reaching the proxy when in client mode, or restricts the destination packets can be forwarded to when in server mode.
-.TP
-.B \-dp destination_port
-Specifies/restrict the port that the proxy should tunnel the TCP connection to.
-.TP
-.SH Shared options:
-.TP
-.B \-c network_device
-Specify the network interface to capture packets from. Note that packet capturing isn't always necessary, but you should try this if you experience problems with ptunnel.
-.TP
-.B \-v verbosity
-Controls the verbosity level. -1 is no output, 0 shows errors only, 1 shows info messages, 2 gives more output, 3 provides even more output, level 4 displays debug info and level 5 displays absolutely everything, including the nasty details of sends and receives.
-.TP
-.B \-udp
-Enables tunneling over UDP port 53 (DNS) instead of using ICMP. This will only work if your proxy can accept incoming traffic on port 53, and the client is able to send data to the proxy on port 53. Note that this option does not wrap ptunnel's data in DNS-compliant packets. This option must be given on both the proxy and client side for things to work correctly.
-.TP
-.B \-syslog (Not available on Windows.)
-Changes logging to use the built-in syslog fascility.
-.TP
-.B \-daemon file (Not available on Windows.)
-Run in background, writing PID in file.
-.TP
-.B \-u
-Attempts to run ptunnel without privileges. This doesn't usually work! On UNIX systems please consider using the following three options instead:
-.TP
-.B \-setuid user (Not available on Windows.)
-When started in privileged mode, drop down to user's rights as soon as possible.
-.TP
-.B \-setgid group (Not available on Windows.)
-When started in privileged mode, drop down to group's rights as soon as possible.
-.TP
-.B \-chroot dir (Not available on Windows.)
-When started in privileged mode, restrict file access to the specified directory.
-.TP
-.B \-setcon context (Not available on Windows.)
-Set SELinux context when all there is left to do are network I/O operations.
-In order to be able to combine with -chroot you will have to `mount --bind /proc /chrootdir/proc`
-.TP
-.B \-x password
-Specifies a password or passphrase to use. This will allow you to protect the proxy from use by others who don't know the password. It needs to be specified on both proxy and client.
-.TP
-.B \-f file
-Specifies a log file. If you specify -syslog, syslog is always used instead.
-.TP
-.B \-h
-Displays brief usage information.
-
-.SH EXAMPLES
-The following assumes that ptunnel is run as root, both on the proxy and client. To tunnel ssh connections from the client machine via a proxy running on proxy.pingtunnel.com to the computer login.domain.com, the following command line would be used:
-.TP
-.B ptunnel \-p proxy.pingtunnel.com \-lp 8000 \-da login.domain.com \-dp 22
-.PP
-An ssh connection to login.domain.com can now be established as follows:
-.TP
-.B ssh \-p 8000 localhost
-.PP
-If ssh complains about potential man-in-the-middle attacks, simply remove the offending key from the known_hosts file. The warning/error is expected if you have previously ssh'd to your local computer (i.e., ssh localhost), or you have used ptunnel to forward ssh connections to different hosts.
-
-Of course, for all of this to work, you need to start the proxy on your proxy-computer (proxy.pingtunnel.com). Doing this is very simple:
-
-.B ptunnel
-
-If you find that the proxy isn't working, you will need to enable packet capturing on the main network device. Currently this device is assumed to be an ethernet-device (i.e., ethernet or wireless). Packet capturing is enabled by giving the -c switch, and supplying the device name to capture packets on (for instance eth0 or en1). The same goes for the client. On Mac OS X, packet capturing must always be enabled (both for proxy and client), as resent packets won't be received otherwise.
-
-To protect yourself from others using your proxy, you can protect access to it with a password using the <tt>-x</tt> switch. The password is never sent in the clear, but keep in mind that it may be visible from tools like top or ps, which can display the command line used to start an application.
-
-.SH EXIT STATUS
-.B ptunnel
-does not exit until forced to do so by an interrupt (Ctrl-C) or if it crashes.
-.SH BUGS
-.B ptunnel
-currently does not handle packet capturing on network interfaces other than ethernet or wireless correctly.
-.SH AUTHORS AND CONTRIBUTORS
-Daniel Stoedle (daniels@cs.uit.no)
-
-Windows port: Mike Miller (mike@mikeage.net)
-
-SELinux support: Sebastien Raveau (sebastien.raveau@epita.fr)
-
-Patches: Joe McKenzie, Steffen Wendzel and StalkR.
-
-.SH LICENSE
-.B ptunnel
-is licensed under the BSD License.
-.SH AVAILABILITY
-.TP
-The ptunnel homepage is currently located here:
-http://www.cs.uit.no/~daniels/PingTunnel/
-.TP
-The freshmeat project page is located here:
-http://freshmeat.net/projects/ptunnel/
-.PP
-Please take the time to rate ptunnel if you find it useful. Thanks!
diff --git a/.pc/fix_typo.diff/README b/.pc/fix_typo.diff/README
deleted file mode 100755
index 985464a..0000000
--- a/.pc/fix_typo.diff/README
+++ /dev/null
@@ -1,118 +0,0 @@
-PingTunnel Read Me
-==================
-
-What is ptunnel?
-----------------
-Ptunnel is an application that allows you to reliably tunnel TCP connections
-to a remote host using ICMP echo request and reply packets, commonly known as
-ping requests and replies.
-
-
-Contact details
----------------
-You can the author, Daniel Stoedle, here:
- <daniels@cs.uit.no>
-The official ptunnel website is located here:
- <http://www.cs.uit.no/~daniels/PingTunnel/>
-The Windows port was created by Mike Miller:
- <mike@mikeage.net>
-
-
-Compiling
----------
-To compile ptunnel, simply run make. If everything goes well, you should end up
-with a binary called ptunnel. This serves as both the client and proxy. You can
-optionally install it using "make install". On Windows, run "make ptunnel.exe"
-to compile the Windows binary. You will need mingw installed, as well as the
-WinPcap library. WinPcap is available here:
- <http://www.winpcap.org/install/bin/WpdPack_4_0_2.zip>
-
-
-Running
--------
-Ptunnel works best when running as root, and usually requires running as root.
-Again, from the website:
-
-Client: ./ptunnel -p <proxy address> -lp <listen port> -da <destination address>
- -dp <dest port> [-c <network device>] [-v <verbosity>] [-u]
- [-x password]
-Proxy: ./ptunnel [-c <network device>] [-v <verbosity>] [-u] [-x password]
-
-The -p switch sets the address of the host on which the proxy is running. A
-quick test to see if the proxy will work is simply to try pinging this host -
-if you get replies, you should be able to make the tunnel work.
-
-The -lp, -da and -dp switches set the local listening port, destination address
-and destination port. For instance, to tunnel ssh connections from the client
-machine via a proxy running on proxy.pingtunnel.com to the computer
-login.domain.com, the following command line would be used:
-
-sudo ./ptunnel -p proxy.pingtunnel.com -lp 8000 -da login.domain.com -dp 22
-
-An ssh connection to login.domain.com can now be established as follows:
-
-ssh -p 8000 localhost
-
-If ssh complains about potential man-in-the-middle attacks, simply remove the
-offending key from the known_hosts file. The warning/error is expected if you
-have previously ssh'd to your local computer (i.e., ssh localhost), or you have
-used ptunnel to forward ssh connections to different hosts.
-
-Of course, for all of this to work, you need to start the proxy on your
-proxy-computer (we'll call it proxy.pingtunnel.com here). Doing this is very
-simple:
-
-sudo ./ptunnel
-
-If you find that the proxy isn't working, you will need to enable packet
-capturing on the main network device. Currently this device is assumed to be
-an ethernet-device (i.e., ethernet or wireless). Packet capturing is enabled by
-giving the -c switch, and supplying the device name to capture packets on (for
-instance eth0 or en1). The same goes for the client. On versions of Mac OS X
-prior to 10.4 (Tiger), packet capturing must always be enabled (both for proxy
-and client), as resent packets won't be received otherwise.
-
-To protect yourself from others using your proxy, you can protect access to it
-with a password using the <tt>-x</tt> switch. The password is never sent in
-the clear, but keep in mind that it may be visible from tools like top or ps,
-which can display the command line used to start an application.
-
-Finally, the -u switch will attempt to run the proxy in unprivileged mode (i.e.,
-no need for root access), and the -v switch controls the amount of output from
-ptunnel. -1 indicates no output, 0 shows errors only, 1 shows info messages, 2
-gives more output, 3 provides even more output, level 4 displays debug info and
-level 5 displays absolutely everything, including the nasty details of sends and
-receives. The -f switch allows output to be saved to a logfile.
-
-Security features: Please see the ptunnel man-page for instructions.
-
-
-Supported operating systems
----------------------------
-Ptunnel supports most operating systems with libpcap, the usual POSIX functions
-and a BSD sockets compatible API. In particular, it has been tested on Linux
-Fedora Core 2 and Mac OS X 10.3.6 and above. As of version 0.7, ptunnel can also
-be compiled on Windows, courtesy of Mike Miller, assuming mingw and WinPcap is
-installed.
-
-
-Credits and contributors
-------------------------
-Thanks to L. Peter Deutsch for his open-source MD5 implementation, included with
-ptunnel, but also available here:
-http://sourceforge.net/projects/libmd5-rfc/
-
-Many thanks also to Mike Miller <mike@mikeage.net> for his work on creating a
-Windows port of ptunnel.
-
-Thanks to Sebastien Raveau <sebastien.raveau@epita.fr> for implementing various
-security features and SELinux support.
-
-Also thanks to Joe McKenzie, Steffen Wendzel and StalkR for contributing patches to
-ptunnel.
-
-License
--------
-Ping Tunnel is Copyright (c) 2004-2011, Daniel Stoedle <daniels@cs.uit.no>,
-Yellow Lemon Software. All rights reserved. Ping Tunnel is licensed under the
-BSD License. Please see the LICENSE file for details.
diff --git a/.pc/makefile-debian-prefix.patch/Makefile b/.pc/makefile-debian-prefix.patch/Makefile
deleted file mode 100755
index e9c1b7a..0000000
--- a/.pc/makefile-debian-prefix.patch/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-# Makefile for the pingtunnel utility
-# (c) 2004-2009 Daniel Stoedle, daniels@cs.uit.no
-# ptunnel.exe target added by Mike Miller, mike@mikeage.net
-
-CC = gcc
-CFLAGS = -Wall -g
-LDOPTS = -lpthread -lpcap
-PT_OBJS = ptunnel.o md5.o
-
-WIN32_CC = mingw32-gcc
-WIN32_CFLAGS = -g -Wall -DWIN32 -I"c:\Program Files\WpdPack\Include"
-WIN32_LDOPTS = -lwpcap -lwsock32 -L"c:\Program Files\WpdPack\Lib"
-WIN32_PT_OBJS = ptunnel.obj md5.obj
-
-prefix = /usr
-bindir = $(prefix)/bin
-mandir = $(prefix)/share/man/man8
-
-all: ptunnel
-
-dist:
- rm -rf PingTunnel/
- mkdir PingTunnel
- cp ptunnel.c ptunnel.h Makefile.dist PingTunnel/
- mv PingTunnel/Makefile.dist PingTunnel/Makefile
-
-
-install: ptunnel
- install -d $(bindir)/
- install -d $(mandir)/
- install ./ptunnel $(bindir)/ptunnel
- install ./ptunnel.8 $(mandir)/ptunnel.8
-
-ptunnel: $(PT_OBJS)
- $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(LDOPTS) `[ -e /usr/include/selinux/selinux.h ] && echo -lselinux`
-
-ptunnel.exe: $(WIN32_PT_OBJS)
- $(CC) -o $@ $^ $(WIN32_LDOPTS)
-
-clean:
- -rm -f *.o ptunnel
- -rm -f *.obj ptunnel.exe
- -rm -f .depend
-
-depend: .depend
-.depend:
- $(CC) $(CFLAGS) $(CPPFLAGS) -MM *.c > $@
-
-%.o:%.c
- $(CC) $(CFLAGS) $(CPPFLAGS) `[ -e /usr/include/selinux/selinux.h ] && echo -DHAVE_SELINUX` -c -o $@ $<
-
-%.obj:%.c
- $(WIN32_CC) $(WIN32_CFLAGS) -c -o $@ $<
-
--include .depend
diff --git a/Makefile b/Makefile
index a958119..c105b7f 100755
--- a/Makefile
+++ b/Makefile
@@ -3,14 +3,14 @@
# ptunnel.exe target added by Mike Miller, mike@mikeage.net
CC = gcc
-CFLAGS = -Wall -g
+CFLAGS = -Wall -g -fstrict-aliasing
LDOPTS = -lpthread -lpcap
-PT_OBJS = ptunnel.o md5.o
+PT_OBJS = options.o ptunnel.o md5.o base64.o
WIN32_CC = mingw32-gcc
WIN32_CFLAGS = -g -Wall -DWIN32 -I"c:\Program Files\WpdPack\Include"
WIN32_LDOPTS = -lwpcap -lwsock32 -L"c:\Program Files\WpdPack\Lib"
-WIN32_PT_OBJS = ptunnel.obj md5.obj
+WIN32_PT_OBJS = options.obj ptunnel.obj md5.obj base64.obj
prefix = $(DESTDIR)/usr
bindir = $(prefix)/sbin
diff --git a/base64.c b/base64.c
new file mode 100644
index 0000000..7a25808
--- /dev/null
+++ b/base64.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "base64.h"
+
+
+#if 0
+static const char hextab[] = "0123456789ABCDEF";
+
+void print_hexstr(unsigned char *buf, size_t siz) {
+ char *out = (char *) calloc(3, siz+1);
+ unsigned char high, low;
+
+ for (size_t i = 0; i < siz; ++i) {
+ high = (buf[i] & 0xF0) >> 4;
+ low = buf[i] & 0x0F;
+
+ out[i ] = hextab[high];
+ out[i+1] = hextab[low];
+ out[i+2] = ' ';
+ }
+
+ printf("%s\n", out);
+ free(out);
+}
+#endif
+
+
+static void build_decoding_table(void);
+
+static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'};
+static char *decoding_table = NULL;
+static int mod_table[] = {0, 2, 1};
+
+
+char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
+ *output_length = 4 * ((input_length + 2) / 3);
+
+ char *encoded_data = (char *) calloc(*output_length, sizeof(char));
+ if (encoded_data == NULL) return NULL;
+
+ for (size_t i = 0, j = 0; i < input_length; i += 3, j += 4) {
+
+ uint32_t octet_a = i < input_length ? (unsigned char)data[i] : 0;
+ uint32_t octet_b = i < input_length ? (unsigned char)data[i+1] : 0;
+ uint32_t octet_c = i < input_length ? (unsigned char)data[i+2] : 0;
+ uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
+
+ encoded_data[j] = encoding_table[(triple >> 3 * 6) & 0x3F];
+ encoded_data[j+1] = encoding_table[(triple >> 2 * 6) & 0x3F];
+ encoded_data[j+2] = encoding_table[(triple >> 1 * 6) & 0x3F];
+ encoded_data[j+3] = encoding_table[(triple >> 0 * 6) & 0x3F];
+ }
+
+ for (int i = 0; i < mod_table[input_length % 3]; i++)
+ encoded_data[*output_length - 1 - i] = '=';
+
+ return encoded_data;
+}
+
+unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
+ if (decoding_table == NULL) build_decoding_table();
+ if (input_length % 4 != 0) return NULL;
+
+ *output_length = input_length / 4 * 3;
+ if (data[input_length - 1] == '=') (*output_length)--;
+ if (data[input_length - 2] == '=') (*output_length)--;
+
+ unsigned char *decoded_data = (unsigned char *) calloc(*output_length, sizeof(char));
+ if (decoded_data == NULL) return NULL;
+
+ for (size_t i = 0, j = 0; i < input_length; i += 4, j += 3) {
+ uint32_t sextet_a = data[i] == '=' ? 0 & i : decoding_table[(size_t)data[i]];
+ uint32_t sextet_b = data[i] == '=' ? 0 & (i+1) : decoding_table[(size_t)data[i+1]];
+ uint32_t sextet_c = data[i] == '=' ? 0 & (i+2) : decoding_table[(size_t)data[i+2]];
+ uint32_t sextet_d = data[i] == '=' ? 0 & (i+3) : decoding_table[(size_t)data[i+3]];
+
+ uint32_t triple = (sextet_a << 3 * 6)
+ + (sextet_b << 2 * 6)
+ + (sextet_c << 1 * 6)
+ + (sextet_d << 0 * 6);
+
+ if (j < *output_length) decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
+ if (j < *output_length) decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
+ if (j < *output_length) decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
+ }
+
+ return decoded_data;
+}
+
+static void build_decoding_table(void) {
+ decoding_table = (char *) calloc(256, sizeof(*decoding_table));
+
+ for (int i = 0; i < 64; i++)
+ decoding_table[(unsigned char) encoding_table[i]] = i;
+}
+
+void base64_cleanup(void) {
+ free(decoding_table);
+}
diff --git a/base64.h b/base64.h
new file mode 100644
index 0000000..e240f8b
--- /dev/null
+++ b/base64.h
@@ -0,0 +1,8 @@
+#ifndef BASE64_H
+#define BASE64_H 1
+
+void base64_cleanup(void);
+char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length);
+unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length);
+
+#endif
diff --git a/options.c b/options.c
new file mode 100644
index 0000000..ceee3c7
--- /dev/null
+++ b/options.c
@@ -0,0 +1,226 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <string.h>
+#include <getopt.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "options.h"
+#include "utils.h"
+
+enum option_type {
+ OPT_BOOL, OPT_DEC32, OPT_HEX32, OPT_STR
+};
+
+struct option_usage {
+ const char *short_help;
+ int required;
+ enum option_type otype;
+ union {
+ int32_t num;
+ uint32_t unum;
+ const char *str;
+ };
+ const char *long_help;
+};
+
+static const struct option_usage usage[] = {
+ {"magic", 0, OPT_HEX32, {.unum = 0xdeadc0de},
+ "Set ptunnel magic hexadecimal number. (32-bit unsigned)\n"
+ "This will be prefixed in all ICMP packets\n"
+ "and can be used to bypass Cisco IPS\n"
+ "This value has to be the same on the server and client!\n"
+ },
+ {"address:port", 1, OPT_STR, {.unum = 0},
+ "Set address of peer running packet forwarder. This causes\n"
+ "ptunnel to operate in forwarding mode - the absence of this\n"
+ "option causes ptunnel to operate in proxy mode.\n"
+ },
+ {"port", 1, OPT_DEC32, {.num = 1234},
+ "Set TCP listening port (only used when operating in forward mode)\n"
+ },
+ {"address:port", 1, OPT_STR, {.str = "127.0.0.1:22"},
+ "Set remote proxy destination address:port if client\n"
+ "Restrict to only this destination address:port if server\n"
+ },
+ {"connections", 0, OPT_DEC32, {.num = 4},
+ "Set maximum number of concurrent tunnels\n"
+ },
+ {"level", 0, OPT_DEC32, {.num = 1},
+ "Verbosity level (-1 to 4, where -1 is no output, and 4 is all output)\n"
+ },
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Enable libpcap on the given device.\n"
+ },
+ {"file", 0, OPT_STR, {.str = "/var/log/ptunnel.log"},
+ "Specify a file to log to, rather than printing to standard out.\n"
+ },
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Client only. Enables continuous output of statistics (packet loss, etc.)\n"
+ },
+#ifndef WIN32
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Run in background, the PID will be written in the file supplied as argument\n"
+ },
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Output debug to syslog instead of standard out.\n"
+ },
+#endif
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Toggle use of UDP instead of ICMP. Proxy will listen on port 53 (must be root).\n"
+ },
+ {"password", 0, OPT_STR, {.str = NULL},
+ "Set password (must be same on client and proxy)\n"
+ "If no password is set, you will be asked during runtime.\n"
+ },
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Run proxy in unprivileged mode. This causes the proxy to forward\n"
+ "packets using standard echo requests, instead of crafting custom echo replies.\n"
+ "Unprivileged mode will only work on some systems, and is in general less reliable\n"
+ "than running in privileged mode.\n"
+ },
+#ifndef WIN32
+ {"user", 0, OPT_STR, {.str = "nobody"},
+ "When started in privileged mode, drop down to user's rights as soon as possible\n"
+ },
+ {"group", 0, OPT_STR, {.str = "nogroup"},
+ "When started in privileged mode, drop down to group's rights as soon as possible\n"
+ },
+ {"directory", 0, OPT_STR, {.str = "/var/lib/ptunnel"},
+ "When started in privileged mode, restrict file access to the specified directory\n"
+ },
+ {NULL, 0, OPT_BOOL, {.unum = 0},
+ "Set SELinux context when all there is left to do are network I/O operations\n"
+ "To combine with -chroot you will have to `mount --bind /proc /chrootdir/proc`\n"
+ },
+#endif
+ {NULL,0,OPT_BOOL,{.unum=0},NULL}
+};
+
+static struct option long_options[] = {
+ {"magic", required_argument, 0, 'm'},
+ {"proxy", required_argument, 0, 'p'},
+ {"listen", required_argument, 0, 'l'},
+ {"remote", required_argument, 0, 'r'},
+ {"connections", required_argument, 0, 'c'},
+ {"verbosity", required_argument, 0, 'v'},
+ {"libpcap", no_argument, 0, 0 },
+ {"logfile", required_argument, 0, 'o'},
+ {"statistics", no_argument, 0, 's'},
+#ifndef WIN32
+ {"daemon", no_argument, 0, 'd'},
+ {"syslog", no_argument, 0, 0 },
+#endif
+ {"udp", no_argument, 0, 0 },
+ {"passwd", optional_argument, 0, 'x'},
+ {"unprivileged", no_argument, 0, 0 },
+ {"user", required_argument, 0, 'u'},
+ {"group", required_argument, 0, 'g'},
+ {"chroot", optional_argument, 0, 0 },
+ {"setcon", no_argument, 0, 'e'},
+ {NULL,0,0,0}
+};
+
+static void print_multiline(const char *prefix, const char *multiline) {
+ const char sep[] = "\n";
+ const char *start, *end;
+
+ start = multiline;
+ do {
+ if (start) {
+ end = strstr(start, sep);
+ if (end) {
+ printf("%s%.*s\n", prefix, (int)(end-start), start);
+ start = end + strlen(sep);
+ }
+ }
+ } while (start && end);
+}
+
+static void print_long_help(unsigned index, int required_state) {
+ const char spaces[] = " ";
+
+ if (usage[index].required != required_state)
+ return;
+ if (!long_options[index].name)
+ return;
+
+ if (isalpha(long_options[index].val)) {
+ printf("%.*s-%c --%s\n", 4, spaces, long_options[index].val, long_options[index].name);
+ } else {
+ printf("%.*s--%s\n", 4, spaces, long_options[index].name);
+ }
+
+ if (usage[index].long_help) {
+ print_multiline(&spaces[4], usage[index].long_help);
+ }
+
+ switch (usage[index].otype) {
+ case OPT_BOOL:
+ break;
+ case OPT_DEC32:
+ printf("%s(default: %d)\n", spaces, usage[index].num);
+ break;
+ case OPT_HEX32:
+ printf("%s(default: 0x%X)\n", spaces, usage[index].unum);
+ break;
+ case OPT_STR:
+ if (usage[index].str)
+ printf("%s(default: %s)\n", spaces, usage[index].str);
+ break;
+ }
+}
+
+static void print_short_help(unsigned index, int required_state) {
+ const char *ob = (required_state == 0 ? "[" : "");
+ const char *cb = (required_state == 0 ? "]" : "");
+
+ if (usage[index].required != required_state)
+ return;
+ if (!long_options[index].name)
+ return;
+
+ if (!usage[index].short_help && isalpha(long_options[index].val)) {
+ printf(" %s-%c%s", ob, long_options[index].val, cb);
+ }
+ else if (!usage[index].short_help) {
+ printf(" %s--%s%s", ob, long_options[index].name, cb);
+ }
+ else if (isalpha(long_options[index].val)) {
+ printf(" %s-%c <%s>%s", ob, long_options[index].val, usage[index].short_help, cb);
+ }
+ else {
+ printf(" %s--%s <%s>%s", ob, long_options[index].name, usage[index].short_help, cb);
+ }
+}
+
+void print_usage(const char *arg0) {
+ unsigned i;
+
+ assert( ARRAY_SIZE(long_options) == ARRAY_SIZE(usage) );
+
+ printf("ptunnel-ng v%d.%.2d.\n\nUsage: %s", 12, 22, arg0);
+ /* print (short)help argument line */
+ for (i = 0; i < ARRAY_SIZE(usage); ++i) {
+ print_short_help(i, 1);
+ }
+ for (i = 0; i < ARRAY_SIZE(usage); ++i) {
+ print_short_help(i, 0);
+ }
+
+ printf("%s", "\n\n");
+ /* print (long)help lines */
+ for (i = 0; i < ARRAY_SIZE(usage); ++i) {
+ print_long_help(i, 1);
+ }
+ for (i = 0; i < ARRAY_SIZE(usage); ++i) {
+ print_long_help(i, 0);
+ }
+
+_exit(0);
+}
+
+int parse_options(int argc, char **argv) {
+ return 0;
+}
diff --git a/options.h b/options.h
new file mode 100644
index 0000000..ad33e97
--- /dev/null
+++ b/options.h
@@ -0,0 +1,60 @@
+#ifndef OPTIONS_H
+#define OPTIONS_H 1
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <pwd.h>
+#include <grp.h>
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+struct options {
+ /** user defined magic value (prevent Cisco WSA/IronPort fingerprint scan) */
+ uint32_t magic;
+ /** Proxy's internet address */
+ uint32_t given_proxy_ip;
+ /** Password (must be the same on proxy and client for authentication to succeed) */
+ char password;
+ /** Port the client listens on */
+ int tcp_listen_port;
+ /** Proxy's internet address */
+ uint32_t given_dst_ip;
+ /** Port to send data to from the proxy */
+ int tcp_port;
+ /** Default maximum number of tunnels to support at once */
+ uint32_t max_tunnels;
+ /** Default log level */
+ int log_level;
+ /** Device to capture packets from */
+ char *pcap_device;
+ /** True if user wants packet capturing */
+ bool pcap;
+ /** Usually stdout, but can be altered by the user */
+ FILE *log_file;
+
+#ifndef WIN32
+#ifdef HAVE_SELINUX
+ char *selinux_context;
+#endif
+ /** UID of the running process */
+ uid_t uid;
+ /** GID of the running process */
+ gid_t gid;
+ /** CHROOT dir */
+ char *root_dir;
+ /** PIDFILE */
+ char *pid_file;
+ /** run as daemon */
+ bool daemonize;
+#endif
+};
+
+extern struct options opts;
+
+void print_usage(const char *arg0);
+
+int parse_options(int argc, char **argv);
+
+#endif
diff --git a/ptunnel.c b/ptunnel.c
index 24928b9..8244a38 100755
--- a/ptunnel.c
+++ b/ptunnel.c
@@ -40,8 +40,9 @@
Note that the source code is best viewed with tabs set to 4 spaces.
*/
-#include "ptunnel.h"
-#include "md5.h"
+#include "ptunnel.h"
+#include "options.h"
+#include "md5.h"
#ifdef WIN32
/* pthread porting to windows */
@@ -426,6 +427,7 @@ int main(int argc, char *argv[]) {
void usage(char *exec_name) {
+print_usage(exec_name);
printf("ptunnel v %d.%.2d.\n", kMajor_version, kMinor_version);
printf("Usage: %s -p <addr> -lp <port> -da <dest_addr> -dp <dest_port> [-m max_tunnels] [-v verbosity] [-f logfile]\n", exec_name);
printf(" %s [-m max_threads] [-v verbosity] [-c <device>]\n", exec_name);
@@ -603,6 +605,9 @@ void* pt_proxy(void *args) {
proxy_desc_t *cur, *prev, *tmp;
pcap_info_t pc;
xfer_stats_t xfer;
+ ip_packet_t *pkt;
+ uint32_t ip;
+ in_addr_t *adr;
// Start the thread, initialize protocol and ring states.
pt_log(kLog_debug, "Starting ping proxy..\n");
@@ -830,7 +835,10 @@ void* pt_proxy(void *args) {
cur = pc.pkt_q.head;
memset(&addr, 0, sizeof(struct sockaddr));
addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = *(in_addr_t*)&(((ip_packet_t*)(cur->data))->src_ip);
+ pkt = (ip_packet_t*)&cur->data[0];
+ ip = pkt->src_ip;
+ adr = (in_addr_t*)&ip;
+ addr.sin_addr.s_addr = *adr;
handle_packet(cur->data, cur->bytes, 1, &addr, fwd_sock);
pc.pkt_q.head = cur->next;
free(cur);
@@ -1590,7 +1598,7 @@ void send_termination_msg(proxy_desc_t *cur, int icmp_sock) {
}
-void pt_log(int level, char *fmt, ...) {
+void pt_log(int level, const char *fmt, ...) {
va_list args;
const char *header[] = { "[err]: ",
"[inf]: ",
diff --git a/ptunnel.h b/ptunnel.h
index 57fb170..f6a2044 100755
--- a/ptunnel.h
+++ b/ptunnel.h
@@ -41,54 +41,53 @@
*/
#ifndef PING_TUNNEL_H
- #define PING_TUNNEL_H
+#define PING_TUNNEL_H 1
// Includes
#ifndef WIN32
- #include <sys/unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <netdb.h>
- #include <pthread.h>
- #include <errno.h>
- #include <net/ethernet.h>
- #include <syslog.h>
- #include <pwd.h>
- #include <grp.h>
+#include <sys/unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <pthread.h>
+#include <errno.h>
+#include <net/ethernet.h>
+#include <syslog.h>
+#include <pwd.h>
+#include <grp.h>
#endif /* !WIN32 */
- #include <stdarg.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <sys/time.h>
- #include <signal.h>
- #include <stdint.h>
- #include <pcap.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <stdint.h>
+#include <pcap.h>
#ifdef WIN32
- #include <winsock2.h>
- typedef int socklen_t;
- typedef uint32_t in_addr_t;
- #define ETH_ALEN 6 /* Octets in one ethernet addr */
- struct ether_header
- {
- u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
- u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
- u_int16_t ether_type; /* packet type ID field */
- };
+#include <winsock2.h>
+typedef int socklen_t;
+typedef uint32_t in_addr_t;
+#define ETH_ALEN 6 /* Octets in one ethernet addr */
+struct ether_header {
+ u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
+ u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
+ u_int16_t ether_type; /* packet type ID field */
+};
#endif /* WIN32 */
-// Constants
-#define false 0
-#define true 1
-#define bool char
+// Constants
+#define false 0
+#define true 1
+#define bool char
enum {
- kOpt_undefined = 0, // Constants for parsing options
+ kOpt_undefined = 0, // Constants for parsing options
kOpt_set_magic,
kOpt_set_proxy_addr,
kOpt_set_mode,
@@ -455,6 +454,6 @@ typedef struct {
void send_termination_msg(proxy_desc_t *cur, int icmp_sock);
char* f_inet_ntoa(uint32_t ip);
- void pt_log(int level, char *fmt, ...);
+ void pt_log(int level, const char *fmt, ...);
double time_as_double(void);
#endif
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..2ac39f7
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,6 @@
+#ifndef UTILS_H
+#define UTILS_H 1
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+#endif