diff --git a/CHANGES b/CHANGES index 345f4cf..523e57d 100755 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,10 @@ Changes to proxytunnel version 1.6.0 -- Mon Feb 6 17:00:00 CET 2006 only works on the FIRST proxy, not on a second proxy !! - Added SSL encryption to the data-layer to fool proxies that do deep- packet inspection, by: Alex Peuchert proxytunnel@peuchert.de +- Added -x/--proctitle option, to hide/obfuscate the proxytunnel + command-line in process-listings. This code is disabled by default + But can be enabled by uncommenting the define in the Makefile. + Please test this code on systems available to you :) Changes to proxytunnel version 1.5.2 -- Fri Dec 16 09:27:11 CET 2005 diff --git a/LICENSE.txt b/LICENSE.txt index 61c4ee7..9fea64b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -15,6 +15,44 @@ and came with the following copyright notice: * redistribution of source. */ +The setproctitle code came from sendmail, and comes with the following +license-text (it's a 4-clause BSD license) + +/* + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + Other contributors can be found in the CREDITS file diff --git a/Makefile b/Makefile index 623caaa..309b554 100755 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ CC ?= gcc CFLAGS += -Wall -DHAVE_GETOPT_LONG -DUSE_SSL +#CFLAGS += -DSETPROCTITLE LDFLAGS += -lssl BINDIR = /usr/local/bin INSTALLPATH = $(DESTDIR)/$(BINDIR) @@ -14,6 +15,7 @@ INSTALLMANPATH = $(DESTDIR)/$(MANPATH) PROGNAME = proxytunnel OBJ = proxytunnel.o \ base64.o \ + setproctitle.o \ io.o \ http.o \ basicauth.o \ diff --git a/cmdline.c b/cmdline.c index 2db6bad..27ce023 100755 --- a/cmdline.c +++ b/cmdline.c @@ -22,6 +22,7 @@ #include #include #include "config.h" +#include "proxytunnel.h" #ifndef HAVE_GETOPT_LONG extern char * optarg; @@ -60,6 +61,9 @@ cmdline_parser_print_help (void) #ifdef USE_SSL " -e --encrypt encrypt the communication using SSL\n" #endif +#ifdef SETPROCTITLE +" -x STRING --proctitle=STRING Set the process-title to STRING\n" +#endif " -p STRING --proxy=STRING Proxy host:port combination to connect to\n" " -d STRING --dest=STRING Destination host:port to built the tunnel to\n" "\nParameters for proxy-authentication (not needed for plain proxies):\n" @@ -129,6 +133,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar args_info->header_given = 0; args_info->domain_given = 0; args_info->encrypt_given = 0; + args_info->proctitle_given = 0; /* No... we can't make this a function... -- Maniac */ #define clear_args() \ @@ -147,6 +152,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar args_info->quiet_flag = 0; \ args_info->standalone_arg = 0; \ args_info->encrypt_flag = 0; \ + args_info->proctitle_arg = NULL; \ } clear_args(); @@ -178,6 +184,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar { "proxyport", 1, NULL, 'G' }, { "dest", 1, NULL, 'd' }, { "remproxy", 1, NULL, 'r' }, + { "proctitle", 1, NULL, 'x' }, { "header", 1, NULL, 'H' }, { "verbose", 0, NULL, 'v' }, { "ntlm", 0, NULL, 'N' }, @@ -188,9 +195,9 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar { NULL, 0, NULL, 0 } }; - c = getopt_long (argc, argv, "hVia:u:s:t:U:S:p:r:d:H:nvNeq", long_options, &option_index); + c = getopt_long (argc, argv, "hVia:u:s:t:U:S:p:r:d:H:x:nvNeq", long_options, &option_index); #else - c = getopt( argc, argv, "hVia:u:s:t:U:S:p:r:d:H:nvNeq" ); + c = getopt( argc, argv, "hVia:u:s:t:U:S:p:r:d:H:x:nvNeq" ); #endif if (c == -1) break; /* Exit from `while (1)' loop. */ @@ -236,6 +243,12 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar cmdline_parser_print_version (); exit (0); + case 'x': + args_info->proctitle_given = 1; + message( "Proctitle override enabled\n" ); + args_info->proctitle_arg = gengetopt_strdup (optarg); + break; + case 'u': /* Username to send to HTTPS proxy for authentication. */ if (args_info->user_given) { diff --git a/cmdline.h b/cmdline.h index f531412..79d0747 100755 --- a/cmdline.h +++ b/cmdline.h @@ -39,6 +39,7 @@ struct gengetopt_args_info { int quiet_flag; /* Turn on quiet mode (default=off). */ int standalone_arg; /* Turn on stdalone (-a) on port */ int encrypt_flag; /* Turn on SSL encryption (default=off). */ + char * proctitle_arg; /* Override process title (default=off). */ int help_given; /* Whether help was given. */ int version_given; /* Whether version was given. */ @@ -56,6 +57,7 @@ struct gengetopt_args_info { int quiet_given; /* Whether quiet mode was given. */ int header_given; /* Whenther extra headers are given */ int encrypt_given; /* Whether encrypt was given */ + int proctitle_given; /* Whether to override process title */ } ; int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *args_info ); diff --git a/proxytunnel.c b/proxytunnel.c index aeab1bd..d6d47ae 100755 --- a/proxytunnel.c +++ b/proxytunnel.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "io.h" #include "config.h" @@ -282,7 +283,7 @@ void do_daemon() /* * We begin at the beginning */ -int main( int argc, char *argv[] ) +int main( int argc, char *argv[], char *envp[] ) { program_name = argv[0]; @@ -291,6 +292,9 @@ int main( int argc, char *argv[] ) */ cmdline_parser( argc, argv, &args_info ); +#ifdef SETPROCTITLE + initsetproctitle( argc, argv, envp ); +#endif /* * This is what we do: @@ -348,6 +352,14 @@ int main( int argc, char *argv[] ) if( args_info.encrypt_flag ) do_ssl(); #endif +#ifdef SETPROCTITLE + if( args_info.proctitle_given ) + setproctitle( args_info.proctitle_arg ); +#else + if( args_info.proctitle_given ) + message( "Setting process-title is not supported in this build\n"); +#endif + cpio(); } diff --git a/proxytunnel.h b/proxytunnel.h index dbde5ec..87eff36 100644 --- a/proxytunnel.h +++ b/proxytunnel.h @@ -37,7 +37,9 @@ void proxy_protocol(); void do_ssl(); void einde(); void do_daemon(); -int main( int argc, char *argv[] ); +int initsetproctitle(int argc, char *argv[], char* envp[]); +void setproctitle(const char *fmt, ...); +int main( int argc, char *argv[], char *envp[] ); /* Globals */ int sd; /* The tunnel's socket descriptor */ diff --git a/setproctitle.c b/setproctitle.c new file mode 100644 index 0000000..4d22a99 --- /dev/null +++ b/setproctitle.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef SETPROCTITLE + +#include +#include +#include +#include +#include +#include + +#include + +#define VA_LOCAL_DECL va_list ap; +#define VA_START(f) va_start(ap, f) +#define VA_END va_end(ap) + +/* return number of bytes left in a buffer */ +#define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf)) + +/* +** SETPROCTITLE -- set process title for ps +** +** Parameters: +** fmt -- a printf style format string. +** a, b, c -- possible parameters to fmt. +** +** Returns: +** none. +** +** Side Effects: +** Clobbers argv of our main procedure so ps(1) will +** display the title. +*/ + +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_REUSEARGV 1 /* cover argv with title information */ +#define SPT_BUILTIN 2 /* use libc builtin */ +#define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ +#define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ +#define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ +#define SPT_SCO 6 /* write kernel u. area */ +#define SPT_CHANGEARGV 7 /* write our own strings into argv[] */ + +# define MAXLINE 2048 /* max line length */ + +#ifndef SPT_TYPE +# define SPT_TYPE SPT_REUSEARGV +#endif + +#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN + +# if SPT_TYPE == SPT_PSTAT +# include +# endif +# if SPT_TYPE == SPT_PSSTRINGS +# include +# include +# ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ +# undef SPT_TYPE +# define SPT_TYPE SPT_REUSEARGV +# else +# ifndef NKPDE /* FreeBSD 2.0 */ +# define NKPDE 63 +typedef unsigned int *pt_entry_t; +# endif +# endif +# endif + +# if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV +# define SETPROC_STATIC static +# else +# define SETPROC_STATIC +# endif + +# if SPT_TYPE == SPT_SYSMIPS +# include +# include +# endif + +# if SPT_TYPE == SPT_SCO +# include +# include +# include +# include +# if PSARGSZ > MAXLINE +# define SPT_BUFSIZE PSARGSZ +# endif +# endif + +# ifndef SPT_PADCHAR +# define SPT_PADCHAR ' ' +# endif + +# ifndef SPT_BUFSIZE +# define SPT_BUFSIZE MAXLINE +# endif + +#endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ + +/* +** Pointers for setproctitle. +** This allows "ps" listings to give more useful information. +*/ + +char **Argv = NULL; /* pointer to argument vector */ +char *LastArgv = NULL; /* end of argv */ + +int +initsetproctitle(argc, argv, envp) + int argc; + char **argv; + char **envp; +{ + register int i, envpsize = 0; + extern char **environ; + + /* + ** Move the environment so setproctitle can use the space at + ** the top of memory. + */ + + for (i = 0; envp[i] != NULL; i++) + envpsize += strlen(envp[i]) + 1; + environ = (char **) malloc(sizeof (char *) * (i + 1)); + if (environ == NULL) + return -1; + /* ---> removed some macro calls */ + for (i = 0; envp[i] != NULL; i++) { + size_t len = strlen(envp[i]) + 1; + char *p = malloc(len); + if (p == NULL) + return -1; + environ[i] = strncpy(p, envp[i], len); + p[len - 1] = NULL; + } + environ[i] = NULL; + + /* + ** Save start and extent of argv for setproctitle. + */ + + Argv = argv; + + /* + ** Find the last environment variable within sendmail's + ** process memory area. + */ + while (i > 0 && (envp[i - 1] < argv[0] || + envp[i - 1] > (argv[argc - 1] + + strlen(argv[argc - 1]) + 1 + envpsize))) + i--; + + if (i > 0) + LastArgv = envp[i - 1] + strlen(envp[i - 1]); + else + LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); + + return 0; +} + +#if SPT_TYPE != SPT_BUILTIN + + +/*VARARGS1*/ +void +setproctitle(const char *fmt, ...) +{ +# if SPT_TYPE != SPT_NONE + register char *p; + register int i; + SETPROC_STATIC char buf[SPT_BUFSIZE]; + VA_LOCAL_DECL +# if SPT_TYPE == SPT_PSTAT + union pstun pst; +# endif +# if SPT_TYPE == SPT_SCO + off_t seek_off; + static int kmem = -1; + static int kmempid = -1; + struct user u; +# endif + + p = buf; + + /* print the argument string */ + VA_START(fmt); + vsnprintf(p, SPACELEFT(buf, p), fmt, ap); + VA_END; + + i = strlen(buf); + +# if SPT_TYPE == SPT_PSTAT + pst.pst_command = buf; + pstat(PSTAT_SETCMD, pst, i, 0, 0); +# endif +# if SPT_TYPE == SPT_PSSTRINGS + PS_STRINGS->ps_nargvstr = 1; + PS_STRINGS->ps_argvstr = buf; +# endif +# if SPT_TYPE == SPT_SYSMIPS + sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); +# endif +# if SPT_TYPE == SPT_SCO + if (kmem < 0 || kmempid != getpid()) + { + if (kmem >= 0) + close(kmem); + kmem = open(_PATH_KMEM, O_RDWR, 0); + if (kmem < 0) + return; + (void) fcntl(kmem, F_SETFD, 1); + kmempid = getpid(); + } + buf[PSARGSZ - 1] = '\0'; + seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; + if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off) + (void) write(kmem, buf, PSARGSZ); +# endif +# if SPT_TYPE == SPT_REUSEARGV + if (i > LastArgv - Argv[0] - 2) + { + i = LastArgv - Argv[0] - 2; + buf[i] = '\0'; + } + (void) strcpy(Argv[0], buf); + p = &Argv[0][i]; + while (p < LastArgv) + *p++ = SPT_PADCHAR; + Argv[1] = NULL; +# endif +# if SPT_TYPE == SPT_CHANGEARGV + Argv[0] = buf; + Argv[1] = 0; +# endif +# endif /* SPT_TYPE != SPT_NONE */ +} + +#endif /* SPT_TYPE != SPT_BUILTIN */ + +#endif /* SETPROCTITLE */