├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile ├── Makefile.am ├── Makefile.in ├── NEWS ├── README.md ├── TODO ├── acinclude.m4 ├── aclocal.m4 ├── autogen.sh ├── config.guess ├── config.h.in ├── config.sub ├── configure ├── configure.ac ├── doc ├── HTML_VARIABLES ├── HTTP_ERROR_CODES ├── Makefile ├── Makefile.am ├── Makefile.in ├── RFC_INFO ├── debug.html ├── default.html ├── filter-howto.txt ├── releases.txt ├── report.sh.tmpl ├── stats.html ├── tinyproxy.8 └── tinyproxy.conf ├── install-sh ├── ltmain.sh ├── missing ├── mkinstalldirs ├── packaging └── redhat │ ├── tinyproxy-1.5.2-config-patch │ ├── tinyproxy-initd │ └── tinyproxy.spec ├── src ├── Makefile ├── Makefile.am ├── Makefile.in ├── acl.c ├── acl.h ├── anonymous.c ├── anonymous.h ├── buffer.c ├── buffer.h ├── child.c ├── child.h ├── common.h ├── conns.c ├── conns.h ├── daemon.c ├── daemon.h ├── filter.c ├── filter.h ├── gnuregex.c ├── gnuregex.h ├── grammar.c ├── grammar.h ├── grammar.y ├── hashmap.c ├── hashmap.h ├── heap.c ├── heap.h ├── htmlerror.c ├── htmlerror.h ├── http_message.c ├── http_message.h ├── log.c ├── log.h ├── network.c ├── network.h ├── regexp.h ├── reqs.c ├── reqs.h ├── scanner.c ├── scanner.l ├── sock.c ├── sock.h ├── stats.c ├── stats.h ├── text.c ├── text.h ├── tinyproxy.c ├── tinyproxy.h ├── utils.c ├── utils.h ├── vector.c └── vector.h ├── stamp-h.in └── tiny ├── install.sh ├── tiny.sh ├── tinyproxy └── tinyproxy.conf /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | 34 | config.h 35 | config.log 36 | config.status 37 | libtool 38 | stamp-h 39 | src/tinyproxy 40 | tiny.tar.gz 41 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | tinyproxy is a collaborative work between Steven Young 2 | and Robert James Kaes . 3 | 4 | From versions 0-1.1, Steven Young was the primary maintainer. 5 | From 1.2 to 1.3.0, Robert James Kaes was the primary maintainer. 6 | As of 1.3.1, Steven Young was once again be the primary maintainer. 7 | 8 | But, Robert James Kaes was again the maintainer starting with 1.4.0. 9 | Place your bets as to when the maintainer will change again. :) Kidding! 10 | 11 | Please see the ChangeLog for futher details as to who did what. :) 12 | 13 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Basic Installation 2 | ================== 3 | 4 | These are generic installation instructions. 5 | 6 | The `configure' shell script attempts to guess correct values for 7 | various system-dependent variables used during compilation. It uses 8 | those values to create a `Makefile' in each directory of the package. 9 | It may also create one or more `.h' files containing system-dependent 10 | definitions. Finally, it creates a shell script `config.status' that 11 | you can run in the future to recreate the current configuration, a file 12 | `config.cache' that saves the results of its tests to speed up 13 | reconfiguring, and a file `config.log' containing compiler output 14 | (useful mainly for debugging `configure'). 15 | 16 | If you need to do unusual things to compile the package, please try 17 | to figure out how `configure' could check whether to do them, and mail 18 | diffs or instructions to the address given in the `README' so they can 19 | be considered for the next release. If at some point `config.cache' 20 | contains results you don't want to keep, you may remove or edit it. 21 | 22 | The file `configure.in' is used to create `configure' by a program 23 | called `autoconf'. You only need `configure.in' if you want to change 24 | it or regenerate `configure' using a newer version of `autoconf'. 25 | 26 | The simplest way to compile this package is: 27 | 28 | 1. `cd' to the directory containing the package's source code and type 29 | `./configure' to configure the package for your system. If you're 30 | using `csh' on an old version of System V, you might need to type 31 | `sh ./configure' instead to prevent `csh' from trying to execute 32 | `configure' itself. 33 | 34 | Running `configure' takes awhile. While running, it prints some 35 | messages telling which features it is checking for. 36 | 37 | 2. Type `make' to compile the package. 38 | 39 | 3. Optionally, type `make check' to run any self-tests that come with 40 | the package. 41 | 42 | 4. Type `make install' to install the programs and any data files and 43 | documentation. 44 | 45 | 5. You can remove the program binaries and object files from the 46 | source code directory by typing `make clean'. To also remove the 47 | files that `configure' created (so you can compile the package for 48 | a different kind of computer), type `make distclean'. There is 49 | also a `make maintainer-clean' target, but that is intended mainly 50 | for the package's developers. If you use it, you may have to get 51 | all sorts of other programs in order to regenerate files that came 52 | with the distribution. 53 | 54 | Compilers and Options 55 | ===================== 56 | 57 | Some systems require unusual options for compilation or linking that 58 | the `configure' script does not know about. You can give `configure' 59 | initial values for variables by setting them in the environment. Using 60 | a Bourne-compatible shell, you can do that on the command line like 61 | this: 62 | CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure 63 | 64 | Or on systems that have the `env' program, you can do it like this: 65 | env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure 66 | 67 | Compiling For Multiple Architectures 68 | ==================================== 69 | 70 | You can compile the package for more than one kind of computer at the 71 | same time, by placing the object files for each architecture in their 72 | own directory. To do this, you must use a version of `make' that 73 | supports the `VPATH' variable, such as GNU `make'. `cd' to the 74 | directory where you want the object files and executables to go and run 75 | the `configure' script. `configure' automatically checks for the 76 | source code in the directory that `configure' is in and in `..'. 77 | 78 | If you have to use a `make' that does not supports the `VPATH' 79 | variable, you have to compile the package for one architecture at a time 80 | in the source code directory. After you have installed the package for 81 | one architecture, use `make distclean' before reconfiguring for another 82 | architecture. 83 | 84 | Installation Names 85 | ================== 86 | 87 | By default, `make install' will install the package's files in 88 | `/usr/local/bin', `/usr/local/man', etc. You can specify an 89 | installation prefix other than `/usr/local' by giving `configure' the 90 | option `--prefix=PATH'. 91 | 92 | You can specify separate installation prefixes for 93 | architecture-specific files and architecture-independent files. If you 94 | give `configure' the option `--exec-prefix=PATH', the package will use 95 | PATH as the prefix for installing programs and libraries. 96 | Documentation and other data files will still use the regular prefix. 97 | 98 | In addition, if you use an unusual directory layout you can give 99 | options like `--bindir=PATH' to specify different values for particular 100 | kinds of files. Run `configure --help' for a list of the directories 101 | you can set and what kinds of files go in them. 102 | 103 | If the package supports it, you can cause programs to be installed 104 | with an extra prefix or suffix on their names by giving `configure' the 105 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 106 | 107 | Optional Features 108 | ================= 109 | 110 | Some packages pay attention to `--enable-FEATURE' options to 111 | `configure', where FEATURE indicates an optional part of the package. 112 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 113 | is something like `gnu-as' or `x' (for the X Window System). The 114 | `README' should mention any `--enable-' and `--with-' options that the 115 | package recognizes. 116 | 117 | For packages that use the X Window System, `configure' can usually 118 | find the X include and library files automatically, but if it doesn't, 119 | you can use the `configure' options `--x-includes=DIR' and 120 | `--x-libraries=DIR' to specify their locations. 121 | 122 | Specifying the System Type 123 | ========================== 124 | 125 | There may be some features `configure' can not figure out 126 | automatically, but needs to determine by the type of host the package 127 | will run on. Usually `configure' can figure that out, but if it prints 128 | a message saying it can not guess the host type, give it the 129 | `--host=TYPE' option. TYPE can either be a short name for the system 130 | type, such as `sun4', or a canonical name with three fields: 131 | CPU-COMPANY-SYSTEM 132 | 133 | See the file `config.sub' for the possible values of each field. If 134 | `config.sub' isn't included in this package, then this package doesn't 135 | need to know the host type. 136 | 137 | If you are building compiler tools for cross-compiling, you can also 138 | use the `--target=TYPE' option to select the type of system they will 139 | produce code for and the `--build=TYPE' option to select the type of 140 | system on which you are compiling the package. 141 | 142 | Sharing Defaults 143 | ================ 144 | 145 | If you want to set default values for `configure' scripts to share, 146 | you can create a site shell script called `config.site' that gives 147 | default values for variables like `CC', `cache_file', and `prefix'. 148 | `configure' looks for `PREFIX/share/config.site' if it exists, then 149 | `PREFIX/etc/config.site' if it exists. Or, you can set the 150 | `CONFIG_SITE' environment variable to the location of the site script. 151 | A warning: not all `configure' scripts look for a site script. 152 | 153 | Operation Controls 154 | ================== 155 | 156 | `configure' recognizes the following options to control how it 157 | operates. 158 | 159 | `--cache-file=FILE' 160 | Use and save the results of the tests in FILE instead of 161 | `./config.cache'. Set FILE to `/dev/null' to disable caching, for 162 | debugging `configure'. 163 | 164 | `--help' 165 | Print a summary of the options to `configure', and exit. 166 | 167 | `--quiet' 168 | `--silent' 169 | `-q' 170 | Do not print messages saying which checks are being made. To 171 | suppress all normal output, redirect it to `/dev/null' (any error 172 | messages will still be shown). 173 | 174 | `--srcdir=DIR' 175 | Look for the package's source code in directory DIR. Usually 176 | `configure' can determine that directory automatically. 177 | 178 | `--version' 179 | Print the version of Autoconf used to generate the `configure' 180 | script, and exit. 181 | 182 | `configure' also accepts some other, not widely useful, options. 183 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Redhat spec files (from RPMs) 2 | REDHAT_DIR = packaging/redhat 3 | REDHAT = \ 4 | $(REDHAT_DIR)/tinyproxy-1.5.2-config-patch \ 5 | $(REDHAT_DIR)/tinyproxy-initd \ 6 | $(REDHAT_DIR)/tinyproxy.spec 7 | 8 | # Packaging files 9 | PACKAGING = $(REDHAT) 10 | 11 | EXTRA_DIST = TODO $(PACKAGING) 12 | SUBDIRS = src doc 13 | 14 | install-data-local: tinyproxy-configure-file tinyproxy-html-files 15 | 16 | # Install the configuration file if it doesn't already exist 17 | tinyproxy-configure-file: 18 | $(mkinstalldirs) $(DESTDIR)@TINYPROXY_CONFIG_DIR@ 19 | $(INSTALL) -m 600 $(srcdir)/doc/tinyproxy.conf \ 20 | $(DESTDIR)@TINYPROXY_CONFIG_DIR@/@TINYPROXY_CONFIG_FILE@-dist 21 | test -f $(DESTDIR)@TINYPROXY_CONFIG_DIR@/@TINYPROXY_CONFIG_FILE@ \ 22 | || $(INSTALL) -m 600 $(srcdir)/doc/tinyproxy.conf \ 23 | $(DESTDIR)@TINYPROXY_CONFIG_DIR@/@TINYPROXY_CONFIG_FILE@ 24 | @echo "" 25 | @echo "A configuration file has been copied to:" 26 | @echo "" 27 | @echo "@TINYPROXY_CONFIG_DIR@/@TINYPROXY_CONFIG_FILE@-dist" 28 | @echo "" 29 | @echo "You will need to rename this file to:" 30 | @echo "" 31 | @echo "@TINYPROXY_CONFIG_DIR@/@TINYPROXY_CONFIG_FILE@" 32 | @echo "" 33 | @echo "and modify the values to suit your local system." 34 | @echo "" 35 | @echo "All the configuration directives are commented in the file, so" 36 | @echo "you should not have any problems configuring your system." 37 | @echo "" 38 | 39 | # Install the HTML files 40 | tinyproxy-html-files: 41 | $(mkinstalldirs) $(DESTDIR)$(datadir)/tinyproxy 42 | 43 | for file in debug default stats; do \ 44 | $(INSTALL) -m 644 $(srcdir)/doc/$$file.html $(DESTDIR)$(datadir)/tinyproxy/$$file.html.dist ; \ 45 | test -f $(DESTDIR)$(datadir)/tinyproxy/$$file.html || \ 46 | $(INSTALL) -m 644 $(srcdir)/doc/$$file.html $(DESTDIR)$(datadir)/tinyproxy/$$file.html ; \ 47 | done 48 | $(INSTALL) -m 644 $(srcdir)/doc/HTML_VARIABLES $(DESTDIR)$(datadir)/tinyproxy/HTML_VARIABLES 49 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | INTRODUCTION 2 | ------------ 3 | 4 | It's been a very long time since the last tinyproxy stable release. I 5 | run my own small business, so that obviously has priority over all 6 | other non-business tasks. However, I have managed to automate more of 7 | my business, so I now have time to tackle tinyproxy again. (Email 8 | messages to the mailing list or me personally will actually be 9 | answered in a timely fashion and not just disappear into a black-hole.) 10 | 11 | This release only contains bug fixes. See the summary of changes 12 | below. 13 | 14 | If you find any problems with tinyproxy, please post them to the 15 | tinyproxy bug tracking system at Sourceforge: 16 | 17 | http://sourceforge.net/tracker/?group_id=2632 18 | 19 | Discussions about problems with tinyproxy (or general usage 20 | questions) can always be posted to the tinyproxy mailing list. See 21 | the end of this document for more information. 22 | 23 | 24 | CHANGES 25 | ------- 26 | 27 | Summary of changes since 1.6.2: 28 | 29 | * Fixed a problem with upstream proxy support from Hans-Dieter. This 30 | closes bug 996518. 31 | 32 | * All the fields in the child_config_s structure now use signed 33 | integers since the servers_waiting variable is a signed integer. 34 | This ensures all the comparisons are computed correctly. 35 | 36 | * The standard file descriptors (stdin, stdout, and stderr) are 37 | closed when a production executable is compiled. They are only 38 | left open when a debugging version of tinyproxy is created. 39 | 40 | * Fixed some spelling mistakes. 41 | 42 | Summary of changes since 1.6.1: 43 | 44 | * Fixed a bug in the filter code when handling comments in the filter 45 | configuration file. Closes bug 822226. 46 | 47 | * When installing the HTML documentation, the wrong directory was 48 | being created. This is fixed. 49 | 50 | Summary of changes since 1.6.0: 51 | 52 | * Fixed an off-by-one error with respect to the MaxRequestsPerChild 53 | test. [Fix proposed by Yannick Koehler] 54 | 55 | * Remove the assert on the pointer being NULL since a NULL pointer is 56 | allowed by the realloc() spec. 57 | 58 | 59 | FUTURE 60 | ------ 61 | 62 | Here is a list of improvements slated for the next tinyproxy release: 63 | 64 | * Improve the shared memory implementation (maybe using the MM 65 | library.) 66 | 67 | 68 | CONCLUSION 69 | ---------- 70 | 71 | tinyproxy is shaping up to be a very useful little tool. There are 72 | still long term goals relating to making tinyproxy a completely 73 | HTTP/1.1 standards compliant proxy. Anyone with ideas or patches for 74 | tinyproxy should submit them to the tinyproxy-users mailing list at: 75 | 76 | tinyproxy-users@lists.sourceforge.net 77 | 78 | or see the project's page at: 79 | 80 | http://tinyproxy.sourceforge.net/ 81 | http://sourceforge.net/projects/tinyproxy/ 82 | 83 | Thanks again to all those who have helped to make tinyproxy a more 84 | useful utility. 85 | 86 | Robert James Kaes 87 | August 10, 2004 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tinyproxy 2 | 3 | add socks4/5 support 4 | 5 | # build 6 | 7 | CC=arm-brcm-linux-uclibcgnueabi-gcc ./configure --host=arm-linux 8 | 9 | 10 | DESCRIPTION 11 | ----------- 12 | 13 | tinyproxy is a small, efficient HTTP/SSL proxy daemon released under 14 | the GNU General Public License (GPL). tinyproxy is very useful in a 15 | small network setting, where a larger proxy like Squid would either 16 | be too resource intensive, or a security risk. One of the key 17 | features of tinyproxy is the buffering connection concept. In 18 | effect, tinyproxy will buffer a high speed response from a server, 19 | and then relay it to a client at the highest speed the client will 20 | accept. This feature greatly reduces the problems with sluggishness 21 | on the Internet. If you are sharing an Internet connection with a 22 | small network, and you only want to allow HTTP requests to be 23 | allowed, then tinyproxy is a great tool for the network 24 | administrator. 25 | 26 | 27 | INSTALLATION 28 | ------------ 29 | 30 | To install this package under a Unix derivative, read the INSTALL 31 | file. tinyproxy uses a standard GNU configure script (basically you 32 | should be able to do: 33 | 34 | ./configure ; make ; make install 35 | 36 | in the top level directory to compile and install tinyproxy). There 37 | are additional command line arguments you can supply to configure. 38 | They include: 39 | 40 | --enable-debug If you would like to turn on full 41 | debugging support 42 | --enable-socks This turns on SOCKS support for using 43 | tinyproxy across a fire wall. 44 | --enable-xtinyproxy Compile in support for the XTinyproxy 45 | header, which is sent to any web 46 | server in your domain. 47 | --enable-filter Allows tinyproxy to filter out certain 48 | domains and URLs. 49 | --enable-upstream Enable support for proxying connections 50 | through another proxy server. 51 | --enable-transparent-proxy 52 | Allow tinyproxy to be used as a 53 | transparent proxy daemon 54 | --enable-static Compile a static version of tinyproxy 55 | 56 | 57 | Options for file locations etc. 58 | --with-stathost=HOST Set the default name of the stats host 59 | --with-config=FILE Set the default location of the 60 | configuration file 61 | 62 | Once you have completed your installation, if you would like to 63 | report your success please execute the report.sh script in the doc 64 | directory. This will send an email to the authors reporting your 65 | version, and a few bits of information concerning the memory usage of 66 | tinyproxy. Alternatively, you could just send an email stating the 67 | version, whichever you prefer. 68 | 69 | 70 | SUPPORT 71 | ------- 72 | 73 | If you are having problems with tinyproxy, please submit a bug to the 74 | tinyproxy Bug Tracking system hosted by SourceForge and located at: 75 | 76 | http://sourceforge.net/tracker/?group_id=2632 77 | 78 | You may also wish to subscribe to the tinyproxy-user mailing list. To 79 | do so please visit: 80 | 81 | http://lists.sourceforge.net/lists/listinfo/tinyproxy-users 82 | 83 | for more information on how to subscribe and post messages to the 84 | list. 85 | 86 | Please recompile tinyproxy with full debug support (--enable-debug) 87 | and include a copy of the log file, and any assert errors reported by 88 | tinyproxy. Note that tinyproxy will output memory statistics to 89 | standard error if compiled with debugging support so you might want 90 | to redirect the output to a file for later examination. Also, if you 91 | feel up to it, try running tinyproxy under your debugger and report 92 | the error your received and a context listing of the location. Under 93 | gdb you would run tinyproxy like so: 94 | 95 | gdb tinyproxy 96 | 97 | (gdb) run -c location_of_tinyproxy_conf -d 2>/dev/null 98 | 99 | Now access the port tinyproxy is on until you receive a break in the 100 | gdb. You can now type: 101 | 102 | (gbd) l 103 | 104 | to produce a context listing of the location of the error. Send a 105 | copy to the authors. 106 | 107 | 108 | HOW TO CONTRIBUTE TO tinyproxy 109 | ------------------------------ 110 | 111 | If you would like to contribute a feature, or a bug fix to the 112 | tinyproxy source, please send a diff (preferable a unified 113 | diff. i.e. "diff -u") against the latest release of tinyproxy. Also, 114 | if you could include a brief description of what your patch does. 115 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO List 2 | --------- 3 | 4 | The following are features that I would like to add to tinyproxy in the 5 | future. Where possible, I've listed the person who suggested it. This 6 | list is in no particular order. And hey, if you want to implement one of 7 | these, or another idea you have, go right ahead. Just mail me the diff 8 | against the current tree and I'll integrate it if possible. 9 | 10 | [ Actually, the ordering has become kind of important as of 11 | late. Basically, I'm adding new ideas to the bottom of the list 12 | as I go. ] 13 | 14 | * Include hooks so other types of proxies can be modularly added to 15 | the source tree. Then people can simply choose which types of 16 | proxies (ftp, www, etc) they'd like enabled in tinyproxy.h 17 | Suggested: Tarun Tuli. 18 | 19 | * Include a function to rewrite the incoming requests. Should not be 20 | much of a problem. Just need to modify the process_method() code 21 | to look up the URL and rewrite it. If we want to go really fancy 22 | with RegEx mapping this could get ugly. :) 23 | 24 | * Have the ability to send the data from the connections through an 25 | external filtering program. I kind of like this idea, but I don't 26 | really have a good way of doing it yet. 27 | Suggested: Ed Avis 28 | 29 | * Include the ability to rewrite both incoming and outgoing headers. 30 | 31 | * Enable an option for chroot() jailing tinyproxy. 32 | 33 | * Come up with a more consistent (and elegant) way of logging errors 34 | for the administrators. Right now it's more a hodge-podge 35 | collections of error messages without a _real_ standard. I would 36 | prefer a more uniform look. 37 | 38 | * Include user authentication for accessing tinyproxy itself. 39 | Administrators should be allowed to selectively allow certain users 40 | access to tinyproxy via a user name/password pair. Check the 41 | HTTP/1.1 RFC for more information. [Suggested: Tyrone Tranmer] -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | dnl Taken from Unix Network Programming, W. Richard Stevens 2 | 3 | dnl ################################################################## 4 | dnl We cannot use the AC_CHECK_TYPE macros becasue AC_CHECK_TYPE 5 | dnl #includes only , , and . 6 | dnl Unfortunately, many implementations today hide typedefs in wierd 7 | dnl locations: Solaris 2.5.1 has uint8_t and uint32_t in . 8 | dnl SunOS 4.1.x has int8_t in . 9 | dnl So we define our own macro AC_UNP_CHECK_TYPE that does the same 10 | dnl #includes as "unp.h", and then looks for the typedef. 11 | dnl 12 | dnl This macro should be invoked after all the header checks have been 13 | dnl performed, since we #include "confdefs.h" below, and then use the 14 | dnl HAVE_foo_H values that is can #define. 15 | dnl 16 | AC_DEFUN([AC_UNP_CHECK_TYPE], 17 | [AC_MSG_CHECKING(if $1 defined) 18 | AC_CACHE_VAL(ac_cv_type_$1, 19 | [AC_TRY_COMPILE( 20 | [ 21 | #include "confdefs.h" /* the header built by configure so far */ 22 | #ifdef HAVE_SYS_TYPES_H 23 | # include 24 | #endif 25 | #ifdef HAVE_SYS_SOCKET_H 26 | # include 27 | #endif 28 | #ifdef HAVE_SYS_TIME_H 29 | # include 30 | #endif 31 | #ifdef HAVE_NETINET_IN_H 32 | # include 33 | #endif 34 | #ifdef HAVE_ARPA_INET_H 35 | # include 36 | #endif 37 | #ifdef HAVE_ERRNO_H 38 | # include 39 | #endif 40 | #ifdef HAVE_FCNTL_H 41 | # include 42 | #endif 43 | #ifdef HAVE_NETDB_H 44 | # include 45 | #endif 46 | #ifdef HAVE_SIGNAL_H 47 | # include 48 | #endif 49 | #ifdef HAVE_STDIO_H 50 | # include 51 | #endif 52 | #ifdef HAVE_STDLIB_H 53 | # include 54 | #endif 55 | #ifdef HAVE_STRING_H 56 | # include 57 | #endif 58 | #ifdef HAVE_SYS_STAT_H 59 | # include 60 | #endif 61 | #ifdef HAVE_SYS_UIO_H 62 | # include 63 | #endif 64 | #ifdef HAVE_UNISTD_H 65 | # include 66 | #endif 67 | #ifdef HAVE_SYS_WAIT_H 68 | # include 69 | #endif 70 | #ifdef HAVE_SYS_UN_H 71 | # include 72 | #endif 73 | #ifdef HAVE_SYS_SELECT_H 74 | # include 75 | #endif 76 | #ifdef HAVE_STRINGS_H 77 | # include 78 | #endif 79 | #ifdef HAVE_SYS_IOCTL_H 80 | # include 81 | #endif 82 | #ifdef HAVE_SYS_FILIO_H 83 | # include 84 | #endif 85 | #ifdef HAVE_SYS_SOCKIO_H 86 | # include 87 | #endif 88 | #ifdef HAVE_PTHREAD_H 89 | # include 90 | #endif 91 | #ifdef HAVE_STDINT_H 92 | # include 93 | #endif 94 | ], 95 | [ $1 foo ], 96 | [ac_cv_type_$1=yes], 97 | [ac_cv_type_$1=no])]) 98 | AC_MSG_RESULT([$ac_cv_type_$1]) 99 | if test $ac_cv_type_$1 = no ; then 100 | AH_TEMPLATE([$1], [Defined with the proper type.]) 101 | AC_DEFINE($1, $2) 102 | fi 103 | ]) -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | srcdir=`dirname $0` 4 | test -z "$srcdir" && srcdir=. 5 | ORIGDIR=`pwd` 6 | 7 | set -x 8 | 9 | cd $srcdir 10 | 11 | aclocal -I m4macros \ 12 | && autoheader \ 13 | && automake --gnu --add-missing \ 14 | && autoconf 15 | 16 | cd $ORIGDIR 17 | 18 | set - 19 | 20 | echo $srcdir/configure "$@" 21 | $srcdir/configure "$@" 22 | RC=$? 23 | if test $RC -ne 0; then 24 | echo 25 | echo "Configure failed or did not finish!" 26 | exit $RC 27 | fi 28 | 29 | echo 30 | echo "Now type 'make' to compile Tinyproxy." 31 | -------------------------------------------------------------------------------- /doc/HTML_VARIABLES: -------------------------------------------------------------------------------- 1 | There are several standard HTML variables that are available in every .html 2 | file: 3 | 4 | request - The full HTTP request line. 5 | cause - The abbreviated cause of the error condition. 6 | clientip - The IP address of the client making the request. 7 | clienthost - The hostname of the client making the request. 8 | version - The version of tinyproxy. 9 | package - Presently, resolves to 'tinyproxy'. 10 | date - The current date/time in HTTP format. 11 | 12 | In addition, almost all pages support: 13 | 14 | detail - A detailed, plain English explanation of the error and possible 15 | causes. You might consider this the Microsoftian error message. 16 | -------------------------------------------------------------------------------- /doc/HTTP_ERROR_CODES: -------------------------------------------------------------------------------- 1 | The following is a list of the response codes for the various states of 2 | the server. Currently I would recommend we stick to the HTTP/1.0 return 3 | codes for our errors. Once we start to support the distinction between 4 | HTTP/1.0 and HTTP/1.1 requests from the client, then we can use the 5 | HTTP/1.1 responses. 6 | -- rjkaes 7 | 8 | [ Taken from Apache: The Definitive Guide by Ben Laurie & Peter Laurie. 9 | Published by O'Reilly & Associates, Inc. pg. 146-147 ] 10 | 11 | HTTP/1.0 12 | 200 OK 13 | 302 Found 14 | 304 Not Modified 15 | 400 Bad Request 16 | 401 Unauthorized 17 | 403 Forbidden 18 | 404 Not Found 19 | 500 Server error 20 | 501 Not Implemented 21 | 502 Bad Gateway 22 | 503 Out of resources 23 | 24 | HTTP/1.1 25 | 100 Continue 26 | 101 Switching Protocols 27 | 200 Ok 28 | 201 Created 29 | 202 Accepted 30 | 203 Non-Authoritative Information 31 | 204 No Content 32 | 205 Reset Content 33 | 206 Partial Content 34 | 300 Multiple Choices 35 | 301 Moved Permanently 36 | 302 Moved Temporarily 37 | 303 See Other 38 | 304 Not Modified 39 | 305 Use Proxy 40 | 400 Bad Request 41 | 401 Unauthorized 42 | 402 Payment Required 43 | 403 Forbidden 44 | 404 Not Found 45 | 405 Method Not Allowed 46 | 406 Not Acceptable 47 | 407 Proxy Authentication Required 48 | 408 Request Time-out 49 | 409 Conflict 50 | 410 Gone 51 | 411 Length Required 52 | 412 Precondition Failed 53 | 413 Request Entity Too Large 54 | 414 Request-URI Too Large 55 | 415 Unsupported Media Type 56 | 500 Internal Server Error 57 | 501 Not Implemented 58 | 502 Bad Gateway 59 | 503 Service Unavailable 60 | 504 Gateway Time-out 61 | 505 HTTP Version not supported 62 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am 2 | 3 | # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. 4 | # This Makefile.in is free software; the Free Software Foundation 5 | # gives unlimited permission to copy and/or distribute it, 6 | # with or without modifications, as long as this notice is preserved. 7 | 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 10 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | # PARTICULAR PURPOSE. 12 | 13 | # HTML Variable Substitution Files 14 | 15 | 16 | SHELL = /bin/sh 17 | 18 | srcdir = . 19 | top_srcdir = .. 20 | 21 | prefix = /usr/local 22 | exec_prefix = ${prefix} 23 | 24 | bindir = ${exec_prefix}/bin 25 | sbindir = ${exec_prefix}/sbin 26 | libexecdir = ${exec_prefix}/libexec 27 | datadir = ${prefix}/share 28 | sysconfdir = ${prefix}/etc 29 | sharedstatedir = ${prefix}/com 30 | localstatedir = ${prefix}/var 31 | libdir = ${exec_prefix}/lib 32 | infodir = ${prefix}/info 33 | mandir = ${prefix}/man 34 | includedir = ${prefix}/include 35 | oldincludedir = /usr/include 36 | 37 | DESTDIR = 38 | 39 | pkgdatadir = $(datadir)/tinyproxy 40 | pkglibdir = $(libdir)/tinyproxy 41 | pkgincludedir = $(includedir)/tinyproxy 42 | 43 | top_builddir = .. 44 | 45 | ACLOCAL = /projects/arm/source/tinyproxy/missing aclocal-1.4 46 | AUTOCONF = autoconf 47 | AUTOMAKE = /projects/arm/source/tinyproxy/missing automake-1.4 48 | AUTOHEADER = autoheader 49 | 50 | INSTALL = /usr/bin/install -c 51 | INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS) 52 | INSTALL_DATA = ${INSTALL} -m 644 53 | INSTALL_SCRIPT = ${INSTALL} 54 | transform = s,x,x, 55 | 56 | NORMAL_INSTALL = : 57 | PRE_INSTALL = : 58 | POST_INSTALL = : 59 | NORMAL_UNINSTALL = : 60 | PRE_UNINSTALL = : 61 | POST_UNINSTALL = : 62 | host_alias = arm-linux 63 | host_triplet = arm-unknown-linux-gnu 64 | ADDITIONAL_OBJECTS = filter.o gnuregex.o 65 | AR = arm-linux-ar 66 | AS = @AS@ 67 | CC = arm-brcm-linux-uclibcgnueabi-gcc 68 | CFLAGS = -O2 -DNDEBUG 69 | CPP = arm-brcm-linux-uclibcgnueabi-gcc -E 70 | CPPFLAGS = 71 | CXX = arm-linux-g++ 72 | CXXCPP = arm-linux-g++ -E 73 | DLLTOOL = @DLLTOOL@ 74 | ECHO = echo 75 | EGREP = grep -E 76 | EXEEXT = 77 | F77 = f95 78 | GCJ = @GCJ@ 79 | GCJFLAGS = @GCJFLAGS@ 80 | HAVE_LIB = @HAVE_LIB@ 81 | LDFLAGS = -static 82 | LEX = flex 83 | LEX_FLAGS = 84 | LIB = @LIB@ 85 | LIBS = -lresolv -lnsl 86 | LIBTOOL = $(SHELL) $(top_builddir)/libtool 87 | LN_S = ln -s 88 | LTLIB = @LTLIB@ 89 | MAKEINFO = makeinfo 90 | OBJDUMP = @OBJDUMP@ 91 | OBJEXT = o 92 | PACKAGE = tinyproxy 93 | RANLIB = arm-linux-ranlib 94 | RC = @RC@ 95 | STRIP = strip 96 | TINYPROXY_CONFIG_DIR = /usr/local/etc/tinyproxy 97 | TINYPROXY_CONFIG_FILE = tinyproxy.conf 98 | U = 99 | VERSION = 1.6.3 100 | YACC = bison -y 101 | YFLAGS = -d 102 | 103 | HTML_VAR_SUBST = HTML_VARIABLES debug.html default.html stats.html 104 | man_MANS = tinyproxy.8 105 | 106 | EXTRA_DIST = $(man_MANS) tinyproxy.conf HTTP_ERROR_CODES RFC_INFO releases.txt filter-howto.txt report.sh.tmpl $(HTML_VAR_SUBST) 107 | 108 | mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs 109 | CONFIG_HEADER = ../config.h 110 | CONFIG_CLEAN_FILES = 111 | man8dir = $(mandir)/man8 112 | MANS = $(man_MANS) 113 | 114 | NROFF = nroff 115 | DIST_COMMON = Makefile.am Makefile.in 116 | 117 | 118 | DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) 119 | 120 | TAR = tar 121 | GZIP_ENV = --best 122 | all: all-redirect 123 | .SUFFIXES: 124 | $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) 125 | cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile 126 | 127 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 128 | cd $(top_builddir) \ 129 | && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status 130 | 131 | 132 | install-man8: 133 | $(mkinstalldirs) $(DESTDIR)$(man8dir) 134 | @list='$(man8_MANS)'; \ 135 | l2='$(man_MANS)'; for i in $$l2; do \ 136 | case "$$i" in \ 137 | *.8*) list="$$list $$i" ;; \ 138 | esac; \ 139 | done; \ 140 | for i in $$list; do \ 141 | if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ 142 | else file=$$i; fi; \ 143 | ext=`echo $$i | sed -e 's/^.*\\.//'`; \ 144 | inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ 145 | inst=`echo $$inst | sed '$(transform)'`.$$ext; \ 146 | echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ 147 | $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ 148 | done 149 | 150 | uninstall-man8: 151 | @list='$(man8_MANS)'; \ 152 | l2='$(man_MANS)'; for i in $$l2; do \ 153 | case "$$i" in \ 154 | *.8*) list="$$list $$i" ;; \ 155 | esac; \ 156 | done; \ 157 | for i in $$list; do \ 158 | ext=`echo $$i | sed -e 's/^.*\\.//'`; \ 159 | inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ 160 | inst=`echo $$inst | sed '$(transform)'`.$$ext; \ 161 | echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ 162 | rm -f $(DESTDIR)$(man8dir)/$$inst; \ 163 | done 164 | install-man: $(MANS) 165 | @$(NORMAL_INSTALL) 166 | $(MAKE) $(AM_MAKEFLAGS) install-man8 167 | uninstall-man: 168 | @$(NORMAL_UNINSTALL) 169 | $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 170 | tags: TAGS 171 | TAGS: 172 | 173 | 174 | distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) 175 | 176 | subdir = doc 177 | 178 | distdir: $(DISTFILES) 179 | @for file in $(DISTFILES); do \ 180 | d=$(srcdir); \ 181 | if test -d $$d/$$file; then \ 182 | cp -pr $$d/$$file $(distdir)/$$file; \ 183 | else \ 184 | test -f $(distdir)/$$file \ 185 | || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ 186 | || cp -p $$d/$$file $(distdir)/$$file || :; \ 187 | fi; \ 188 | done 189 | info-am: 190 | info: info-am 191 | dvi-am: 192 | dvi: dvi-am 193 | check-am: all-am 194 | check: check-am 195 | installcheck-am: 196 | installcheck: installcheck-am 197 | install-exec-am: install-exec-local 198 | install-exec: install-exec-am 199 | 200 | install-data-am: install-man 201 | install-data: install-data-am 202 | 203 | install-am: all-am 204 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 205 | install: install-am 206 | uninstall-am: uninstall-man 207 | uninstall: uninstall-am 208 | all-am: Makefile $(MANS) 209 | all-redirect: all-am 210 | install-strip: 211 | $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install 212 | installdirs: 213 | $(mkinstalldirs) $(DESTDIR)$(mandir)/man8 214 | 215 | 216 | mostlyclean-generic: 217 | 218 | clean-generic: 219 | 220 | distclean-generic: 221 | -rm -f Makefile $(CONFIG_CLEAN_FILES) 222 | -rm -f config.cache config.log stamp-h stamp-h[0-9]* 223 | 224 | maintainer-clean-generic: 225 | mostlyclean-am: mostlyclean-generic 226 | 227 | mostlyclean: mostlyclean-am 228 | 229 | clean-am: clean-generic mostlyclean-am 230 | 231 | clean: clean-am 232 | 233 | distclean-am: distclean-generic clean-am 234 | -rm -f libtool 235 | 236 | distclean: distclean-am 237 | 238 | maintainer-clean-am: maintainer-clean-generic distclean-am 239 | @echo "This command is intended for maintainers to use;" 240 | @echo "it deletes files that may require special tools to rebuild." 241 | 242 | maintainer-clean: maintainer-clean-am 243 | 244 | .PHONY: install-man8 uninstall-man8 install-man uninstall-man tags \ 245 | distdir info-am info dvi-am dvi check check-am installcheck-am \ 246 | installcheck install-exec-local install-exec-am install-exec \ 247 | install-data-am install-data install-am install uninstall-am uninstall \ 248 | all-redirect all-am all installdirs mostlyclean-generic \ 249 | distclean-generic clean-generic maintainer-clean-generic clean \ 250 | mostlyclean distclean maintainer-clean 251 | 252 | 253 | install-exec-local: report.sh 254 | 255 | # Build the report.sh script 256 | report.sh: $(srcdir)/report.sh.tmpl 257 | sed -e "s,@TINYPROXY_LOCATION@,$(DESTDIR)$(sbindir)," < $(srcdir)/report.sh.tmpl > $(top_builddir)/doc/report.sh 258 | chmod 755 $(top_builddir)/doc/report.sh 259 | @echo "" 260 | @echo "Report tinyproxy" 261 | @echo "----------------" 262 | @echo "Run the $(top_builddir)/doc/report.sh script to report a" 263 | @echo "successful installation to the authors." 264 | @echo "" 265 | 266 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 267 | # Otherwise a system limit (for SysV at least) may be exceeded. 268 | .NOEXPORT: 269 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | # HTML Variable Substitution Files 2 | HTML_VAR_SUBST = HTML_VARIABLES debug.html default.html stats.html 3 | man_MANS = tinyproxy.8 4 | 5 | EXTRA_DIST = $(man_MANS) tinyproxy.conf \ 6 | HTTP_ERROR_CODES RFC_INFO \ 7 | releases.txt \ 8 | filter-howto.txt \ 9 | report.sh.tmpl \ 10 | $(HTML_VAR_SUBST) 11 | 12 | install-exec-local: report.sh 13 | 14 | # Build the report.sh script 15 | report.sh: $(srcdir)/report.sh.tmpl 16 | sed -e "s,@TINYPROXY_LOCATION@,$(DESTDIR)$(sbindir)," < $(srcdir)/report.sh.tmpl > $(top_builddir)/doc/report.sh 17 | chmod 755 $(top_builddir)/doc/report.sh 18 | @echo "" 19 | @echo "Report tinyproxy" 20 | @echo "----------------" 21 | @echo "Run the $(top_builddir)/doc/report.sh script to report a" 22 | @echo "successful installation to the authors." 23 | @echo "" -------------------------------------------------------------------------------- /doc/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated automatically by automake 1.4-p6 from Makefile.am 2 | 3 | # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. 4 | # This Makefile.in is free software; the Free Software Foundation 5 | # gives unlimited permission to copy and/or distribute it, 6 | # with or without modifications, as long as this notice is preserved. 7 | 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 10 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 11 | # PARTICULAR PURPOSE. 12 | 13 | # HTML Variable Substitution Files 14 | 15 | 16 | SHELL = @SHELL@ 17 | 18 | srcdir = @srcdir@ 19 | top_srcdir = @top_srcdir@ 20 | VPATH = @srcdir@ 21 | prefix = @prefix@ 22 | exec_prefix = @exec_prefix@ 23 | 24 | bindir = @bindir@ 25 | sbindir = @sbindir@ 26 | libexecdir = @libexecdir@ 27 | datadir = @datadir@ 28 | sysconfdir = @sysconfdir@ 29 | sharedstatedir = @sharedstatedir@ 30 | localstatedir = @localstatedir@ 31 | libdir = @libdir@ 32 | infodir = @infodir@ 33 | mandir = @mandir@ 34 | includedir = @includedir@ 35 | oldincludedir = /usr/include 36 | 37 | DESTDIR = 38 | 39 | pkgdatadir = $(datadir)/@PACKAGE@ 40 | pkglibdir = $(libdir)/@PACKAGE@ 41 | pkgincludedir = $(includedir)/@PACKAGE@ 42 | 43 | top_builddir = .. 44 | 45 | ACLOCAL = @ACLOCAL@ 46 | AUTOCONF = @AUTOCONF@ 47 | AUTOMAKE = @AUTOMAKE@ 48 | AUTOHEADER = @AUTOHEADER@ 49 | 50 | INSTALL = @INSTALL@ 51 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) 52 | INSTALL_DATA = @INSTALL_DATA@ 53 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 54 | transform = @program_transform_name@ 55 | 56 | NORMAL_INSTALL = : 57 | PRE_INSTALL = : 58 | POST_INSTALL = : 59 | NORMAL_UNINSTALL = : 60 | PRE_UNINSTALL = : 61 | POST_UNINSTALL = : 62 | host_alias = @host_alias@ 63 | host_triplet = @host@ 64 | ADDITIONAL_OBJECTS = @ADDITIONAL_OBJECTS@ 65 | AR = @AR@ 66 | AS = @AS@ 67 | CC = @CC@ 68 | CFLAGS = @CFLAGS@ 69 | CPP = @CPP@ 70 | CPPFLAGS = @CPPFLAGS@ 71 | CXX = @CXX@ 72 | CXXCPP = @CXXCPP@ 73 | DLLTOOL = @DLLTOOL@ 74 | ECHO = @ECHO@ 75 | EGREP = @EGREP@ 76 | EXEEXT = @EXEEXT@ 77 | F77 = @F77@ 78 | GCJ = @GCJ@ 79 | GCJFLAGS = @GCJFLAGS@ 80 | HAVE_LIB = @HAVE_LIB@ 81 | LDFLAGS = @LDFLAGS@ 82 | LEX = @LEX@ 83 | LEX_FLAGS = @LEX_FLAGS@ 84 | LIB = @LIB@ 85 | LIBS = @LIBS@ 86 | LIBTOOL = @LIBTOOL@ 87 | LN_S = @LN_S@ 88 | LTLIB = @LTLIB@ 89 | MAKEINFO = @MAKEINFO@ 90 | OBJDUMP = @OBJDUMP@ 91 | OBJEXT = @OBJEXT@ 92 | PACKAGE = @PACKAGE@ 93 | RANLIB = @RANLIB@ 94 | RC = @RC@ 95 | STRIP = @STRIP@ 96 | TINYPROXY_CONFIG_DIR = @TINYPROXY_CONFIG_DIR@ 97 | TINYPROXY_CONFIG_FILE = @TINYPROXY_CONFIG_FILE@ 98 | U = @U@ 99 | VERSION = @VERSION@ 100 | YACC = @YACC@ 101 | YFLAGS = @YFLAGS@ 102 | 103 | HTML_VAR_SUBST = HTML_VARIABLES debug.html default.html stats.html 104 | man_MANS = tinyproxy.8 105 | 106 | EXTRA_DIST = $(man_MANS) tinyproxy.conf HTTP_ERROR_CODES RFC_INFO releases.txt filter-howto.txt report.sh.tmpl $(HTML_VAR_SUBST) 107 | 108 | mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs 109 | CONFIG_HEADER = ../config.h 110 | CONFIG_CLEAN_FILES = 111 | man8dir = $(mandir)/man8 112 | MANS = $(man_MANS) 113 | 114 | NROFF = nroff 115 | DIST_COMMON = Makefile.am Makefile.in 116 | 117 | 118 | DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) 119 | 120 | TAR = tar 121 | GZIP_ENV = --best 122 | all: all-redirect 123 | .SUFFIXES: 124 | $(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.ac $(ACLOCAL_M4) 125 | cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile 126 | 127 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 128 | cd $(top_builddir) \ 129 | && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status 130 | 131 | 132 | install-man8: 133 | $(mkinstalldirs) $(DESTDIR)$(man8dir) 134 | @list='$(man8_MANS)'; \ 135 | l2='$(man_MANS)'; for i in $$l2; do \ 136 | case "$$i" in \ 137 | *.8*) list="$$list $$i" ;; \ 138 | esac; \ 139 | done; \ 140 | for i in $$list; do \ 141 | if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ 142 | else file=$$i; fi; \ 143 | ext=`echo $$i | sed -e 's/^.*\\.//'`; \ 144 | inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ 145 | inst=`echo $$inst | sed '$(transform)'`.$$ext; \ 146 | echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \ 147 | $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \ 148 | done 149 | 150 | uninstall-man8: 151 | @list='$(man8_MANS)'; \ 152 | l2='$(man_MANS)'; for i in $$l2; do \ 153 | case "$$i" in \ 154 | *.8*) list="$$list $$i" ;; \ 155 | esac; \ 156 | done; \ 157 | for i in $$list; do \ 158 | ext=`echo $$i | sed -e 's/^.*\\.//'`; \ 159 | inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ 160 | inst=`echo $$inst | sed '$(transform)'`.$$ext; \ 161 | echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \ 162 | rm -f $(DESTDIR)$(man8dir)/$$inst; \ 163 | done 164 | install-man: $(MANS) 165 | @$(NORMAL_INSTALL) 166 | $(MAKE) $(AM_MAKEFLAGS) install-man8 167 | uninstall-man: 168 | @$(NORMAL_UNINSTALL) 169 | $(MAKE) $(AM_MAKEFLAGS) uninstall-man8 170 | tags: TAGS 171 | TAGS: 172 | 173 | 174 | distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) 175 | 176 | subdir = doc 177 | 178 | distdir: $(DISTFILES) 179 | @for file in $(DISTFILES); do \ 180 | d=$(srcdir); \ 181 | if test -d $$d/$$file; then \ 182 | cp -pr $$d/$$file $(distdir)/$$file; \ 183 | else \ 184 | test -f $(distdir)/$$file \ 185 | || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ 186 | || cp -p $$d/$$file $(distdir)/$$file || :; \ 187 | fi; \ 188 | done 189 | info-am: 190 | info: info-am 191 | dvi-am: 192 | dvi: dvi-am 193 | check-am: all-am 194 | check: check-am 195 | installcheck-am: 196 | installcheck: installcheck-am 197 | install-exec-am: install-exec-local 198 | install-exec: install-exec-am 199 | 200 | install-data-am: install-man 201 | install-data: install-data-am 202 | 203 | install-am: all-am 204 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 205 | install: install-am 206 | uninstall-am: uninstall-man 207 | uninstall: uninstall-am 208 | all-am: Makefile $(MANS) 209 | all-redirect: all-am 210 | install-strip: 211 | $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install 212 | installdirs: 213 | $(mkinstalldirs) $(DESTDIR)$(mandir)/man8 214 | 215 | 216 | mostlyclean-generic: 217 | 218 | clean-generic: 219 | 220 | distclean-generic: 221 | -rm -f Makefile $(CONFIG_CLEAN_FILES) 222 | -rm -f config.cache config.log stamp-h stamp-h[0-9]* 223 | 224 | maintainer-clean-generic: 225 | mostlyclean-am: mostlyclean-generic 226 | 227 | mostlyclean: mostlyclean-am 228 | 229 | clean-am: clean-generic mostlyclean-am 230 | 231 | clean: clean-am 232 | 233 | distclean-am: distclean-generic clean-am 234 | -rm -f libtool 235 | 236 | distclean: distclean-am 237 | 238 | maintainer-clean-am: maintainer-clean-generic distclean-am 239 | @echo "This command is intended for maintainers to use;" 240 | @echo "it deletes files that may require special tools to rebuild." 241 | 242 | maintainer-clean: maintainer-clean-am 243 | 244 | .PHONY: install-man8 uninstall-man8 install-man uninstall-man tags \ 245 | distdir info-am info dvi-am dvi check check-am installcheck-am \ 246 | installcheck install-exec-local install-exec-am install-exec \ 247 | install-data-am install-data install-am install uninstall-am uninstall \ 248 | all-redirect all-am all installdirs mostlyclean-generic \ 249 | distclean-generic clean-generic maintainer-clean-generic clean \ 250 | mostlyclean distclean maintainer-clean 251 | 252 | 253 | install-exec-local: report.sh 254 | 255 | # Build the report.sh script 256 | report.sh: $(srcdir)/report.sh.tmpl 257 | sed -e "s,@TINYPROXY_LOCATION@,$(DESTDIR)$(sbindir)," < $(srcdir)/report.sh.tmpl > $(top_builddir)/doc/report.sh 258 | chmod 755 $(top_builddir)/doc/report.sh 259 | @echo "" 260 | @echo "Report tinyproxy" 261 | @echo "----------------" 262 | @echo "Run the $(top_builddir)/doc/report.sh script to report a" 263 | @echo "successful installation to the authors." 264 | @echo "" 265 | 266 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 267 | # Otherwise a system limit (for SysV at least) may be exceeded. 268 | .NOEXPORT: 269 | -------------------------------------------------------------------------------- /doc/RFC_INFO: -------------------------------------------------------------------------------- 1 | INFO 2 | ---- 3 | The following files were/are useful for the proper coding of 4 | tinyproxy. Please note: someday tinyproxy will actually be RFC 5 | compliant, but today is not that day. Right now tinyproxy is pretty 6 | close to being HTTP/1.0 compliant, but there are probably a few 7 | incompatibilities kicking around. 8 | 9 | RFCs 10 | ---- 11 | 1945 Hypertext Transfer Protocol -- HTTP/1.0 12 | 2396 Uniform Resource Identifiers (URI): Generic Syntax 13 | 2616 Hypertext Transfer Protocol -- HTTP/1.1 14 | 2617 HTTP Authentication: Basic and Digest Access Authentication 15 | 16 | POSSIBLE LOCATION 17 | ----------------- 18 | There are many places to obtain a copy of the RFCs, but I use 19 | 20 | http://www.rfc-editor.org/ 21 | 22 | since it provides a great search feature for finding all the RFCs for 23 | a particular topic. 24 | -------------------------------------------------------------------------------- /doc/debug.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Request failed - {cause} 5 | 6 | 7 | 8 |
{cause}
9 |
10 | The request you made failed. Here are the error variables: 11 |
12 | request 13 |
14 | {request} 15 |
16 | cause 17 |
18 | {cause} 19 |
20 | clientip 21 |
22 | {clientip} 23 |
24 | clienthost 25 |
26 | {clienthost} 27 |
28 | version 29 |
30 | {version} 31 |
32 | package 33 |
34 | {package} 35 |
36 | date 37 |
38 | {date} 39 |
40 | detail 41 |
42 | {detail} 43 |
44 | url 45 |
46 | {url} 47 | 48 | 49 | -------------------------------------------------------------------------------- /doc/default.html: -------------------------------------------------------------------------------- 1 | {cause} 2 | 3 | Cache Error!
4 | The following error has occured: {detail} 5 |
6 | Generated by {package} ({version}) 7 | 8 | -------------------------------------------------------------------------------- /doc/filter-howto.txt: -------------------------------------------------------------------------------- 1 | Using tinyproxy with Your Home/Small Business Network 2 | 3 | Written: Patrick L. McGillan 4 | Edited: Robert James Kaes (2002-06-04) 5 | ----------------------------------------------------- 6 | 7 | Being as this will be the most common usage and there were no clear 8 | basic instructions for this scenario, I thought I would write up what 9 | I did for my home system. 10 | 11 | First the layout of the network. A cable modem is connected through a 12 | Linksys Router to a small hub. The computers hanging off the hub and 13 | have a clear shot to the Internet. 14 | 15 | So, the connection from the Internet to the hub looks like this: 16 | 17 | Internet->Cable TV Line->Cable Modem->Linksys Router->Hub/Switch 18 | 19 | Restricting Internet web access on some of those computers (connected 20 | to the hub) is what using tinyproxy is all about. Using the web 21 | interface to the Linksys router, turn off all Internet access to those 22 | computers that shouldn't have direct access to the Internet. This is 23 | done by clicking on the advanced tab and entering the IP number in the 24 | filter range. Now those computers have to go through a proxy, for 25 | their access, as they have no direct access. 26 | 27 | On one of the Linux computers which still has Internet access (I use 28 | an old 486) load up tinyproxy. Now have the users configure their 29 | Internet Explorer/Netscape Navigator programs to use the proxy on the 30 | tinyproxy computer box, along with the port number declared in the 31 | tinyproxy configuration file. By default, there is no blocking of web 32 | sites with this program, so I created a file, called "filter", to 33 | start blocking some sites. 34 | 35 | Example "filter" file entries: 36 | 37 | bannerads.zwire.com 38 | ad.doubleclick.net 39 | ads.fortunecity.com 40 | 41 | This filter file usually goes into the same folder, as your 42 | configuration file. Be sure and uncomment the 'Filter' line in your 43 | configuration file and make sure it points at your newly created 44 | filter file. 45 | 46 | ------------------------------------------------------------------------ 47 | 48 | Copyright (c) 2002 Patrick L. McGillan 49 | 50 | This document is released under the same copyright license as 51 | tinyproxy. You should have found a COPYING file in the top level 52 | directory of this distribution which contains the current license. -------------------------------------------------------------------------------- /doc/releases.txt: -------------------------------------------------------------------------------- 1 | tinyproxy Release Order 2 | ----------------------- 3 | 4 | Below is a list of all the tinyproxy releases since 1.3.2. Each version 5 | has its release date in brackets. To find the information in the 6 | ChangeLog do a: 7 | 8 | grep 'Released tinyproxy x.y.z' 9 | 10 | and you will be brought to the entry for the release. 11 | 12 | NOTE: Right now the list is not complete (or necessarily accuracte) 13 | between version 1.4.1 and 1.4.3. I will be updating this 14 | list as more information becomes available. 15 | 16 | Also, there is currently no information for releases before 17 | version 1.3.2 18 | 19 | 20 | Releases 21 | -------- 22 | 23 | tinyproxy 1.6.1 (2003-08-06) 24 | tinyproxy 1.6.0 (2003-07-14) 25 | tinyproxy 1.5.3 (2003-03-10) 26 | tinyproxy 1.5.2 (2003-01-22) 27 | tinyproxy 1.5.1 (2002-08-09) 28 | tinyproxy 1.5.0 (2002-05-09) 29 | tinyproxy 1.4.3 (2001-11-21) 30 | tinyproxy 1.4.2.2 (2001-09-04) 31 | tinyproxy 1.4.2 (2001-08-29) 32 | tinyproxy 1.4.1.5 (2001-08-28) 33 | tinyproxy 1.4.1.4 (2001-08-27) 34 | tinyproxy 1.4.1.3 (2001-08-26) 35 | tinyproxy 1.4.1 (2001-08-26) 36 | tinyproxy 1.4.0 (2001-06-24) 37 | tinyproxy 1.3.3b (2001-03-26) 38 | tinyproxy 1.3.3a (2001-01-17) 39 | tinyproxy 1.3.3 (2000-04-03) 40 | tinyproxy 1.3.2 (2000-02-16) 41 | tinyproxy 1.3.1 42 | tinyproxy 1.3.0 (1999-12-03 unconfirmed) 43 | -------------------------------------------------------------------------------- /doc/report.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TINYPROXY_BIN=@TINYPROXY_LOCATION@/tinyproxy 4 | 5 | (echo "date: " 6 | date 7 | echo "uname: " 8 | uname -a 9 | echo "ps: " 10 | ps -ef | grep '[t]inyproxy' 11 | echo "ver: " 12 | if [ -x $TINYPROXY_BIN ]; then 13 | $TINYPROXY_BIN -v 14 | else 15 | echo no ver available. 16 | fi;) 2>&1 | mail -s 'tinyproxy install report' rjkaes@users.sourceforge.net 17 | -------------------------------------------------------------------------------- /doc/stats.html: -------------------------------------------------------------------------------- 1 | {package} ({version}) stats 2 | 3 |

{package} ({version}) run-time statistics


4 |
5 | Number of open connections: {opens}
6 | Number of requests: {reqs}
7 | Number of bad connections: {badconns}
8 | Number of denied connections: {deniedconns}
9 | Number of refused connections due to high load: {refusedconns}
10 |
11 | -------------------------------------------------------------------------------- /doc/tinyproxy.8: -------------------------------------------------------------------------------- 1 | .\" -*- nroff -*- 2 | .\" 3 | .\" tinyproxy.8 4 | .\" 5 | .\" Copyright (c) 1998-2000 Steven Young and Robert James Kaes. 6 | .\" Copyright (c) 2001 Robert James Kaes 7 | .\" 8 | .\" This program is distributed under the terms of the GNU General Public 9 | .\" License. See COPYING for additional information. 10 | .\" 11 | .TH tinyproxy 8 .\" "tinyproxy Manual" "January 27, 2003" 12 | .SH NAME 13 | tinyproxy - A small HTTP proxy server 14 | .SH SYNTAX 15 | \fBtinyproxy\fR [ \fBoptions\fR ] 16 | .SH VERSION 17 | This man page documents tinyproxy 18 | .SH DESCRIPTION 19 | \fBtinyproxy\fR is an HTTP proxy server designed to consume a minimum of 20 | system resources. It listens on a given TCP port and handles HTTP proxy 21 | requests. 22 | .SH OPTIONS 23 | .IP "-c config_file" 24 | Use an alternate configuration file. 25 | .IP -d 26 | Don't daemonize; stay in the foreground. Useful for debugging purposes. 27 | .IP -h 28 | Display a short help screen of command line arguments and exit. 29 | .IP -l 30 | Displays the licensing agreement. 31 | .IP -v 32 | Display version information and exit. 33 | .SH SIGNALS 34 | In addition to these command line options, there are also several signals 35 | that can be sent to tinyproxy while it is running to generate debugging 36 | information and to force certain events. 37 | .TP 5 38 | .B SIGHUP 39 | Force \fBtinyproxy\fR to do a garbage collection on the current connections 40 | linked list. This is usually done automatically after a certain number of 41 | connections have been handled. 42 | .SH FILES 43 | .nf 44 | /etc/tinyproxy/tinyproxy.conf 45 | /var/run/tinyproxy.pid 46 | /var/log/tinyproxy.log 47 | .fi 48 | .SH AUTHORS 49 | .nf 50 | Robert James Kaes (rjkaes@flarenet.com) 51 | Steven Young (sdyoung@users.sourceforge.net) 52 | .fi 53 | .SH COPYRIGHT 54 | \fBtinyproxy\fR is distributed under the GNU Public License (GPL). For more 55 | information on the GPL, please see the file COPYING which should have been 56 | included in the archive with \fBtinyproxy\fR. Failing that, 57 | http://www.fsf.org/ will doubtless have a copy up for you to peruse. Please 58 | don't use this software if you don't agree to the terms specified therein. 59 | .SH AVAILABILITY 60 | The latest version of \fBtinyproxy\fR can be acquired from: http://tinyproxy.sourceforge.net/ 61 | -------------------------------------------------------------------------------- /doc/tinyproxy.conf: -------------------------------------------------------------------------------- 1 | ## 2 | ## tinyproxy.conf -- tinyproxy daemon configuration file 3 | ## 4 | 5 | # 6 | # Name of the user the tinyproxy daemon should switch to after the port 7 | # has been bound. 8 | # 9 | #User root 10 | #Group root 11 | 12 | # 13 | # Port to listen on. 14 | # 15 | Port 8888 16 | 17 | # 18 | # If you have multiple interfaces this allows you to bind to only one. If 19 | # this is commented out, tinyproxy will bind to all interfaces present. 20 | # 21 | #Listen 192.168.0.1 22 | 23 | # 24 | # The Bind directive allows you to bind the outgoing connections to a 25 | # particular IP address. 26 | # 27 | #Bind 192.168.0.1 28 | 29 | # 30 | # Timeout: The number of seconds of inactivity a connection is allowed to 31 | # have before it closed by tinyproxy. 32 | # 33 | Timeout 600 34 | 35 | # 36 | # ErrorFile: Defines the HTML file to send when a given HTTP error 37 | # occurs. You will probably need to customize the location to your 38 | # particular install. The usual locations to check are: 39 | # /usr/local/share/tinyproxy 40 | # /usr/share/tinyproxy 41 | # /etc/tinyproxy 42 | # 43 | # ErrorFile 404 "/usr/share/tinyproxy/404.html" 44 | # ErrorFile 400 "/usr/share/tinyproxy/400.html" 45 | # ErrorFile 503 "/usr/share/tinyproxy/503.html" 46 | # ErrorFile 403 "/usr/share/tinyproxy/403.html" 47 | # ErrorFile 408 "/usr/share/tinyproxy/408.html" 48 | 49 | # 50 | # DefaultErrorFile: The HTML file that gets sent if there is no 51 | # HTML file defined with an ErrorFile keyword for the HTTP error 52 | # that has occured. 53 | # 54 | DefaultErrorFile "/usr/share/tinyproxy/default.html" 55 | 56 | # 57 | # StatFile: The HTML file that gets sent when a request is made 58 | # for the stathost. If this file doesn't exist a basic page is 59 | # hardcoded in tinyproxy. 60 | # 61 | StatFile "/usr/share/tinyproxy/stats.html" 62 | 63 | # 64 | # Where to log the information. Either LogFile or Syslog should be set, 65 | # but not both. 66 | # 67 | #Logfile "/var/log/tinyproxy.log" 68 | Syslog On 69 | 70 | # 71 | # Set the logging level. Allowed settings are: 72 | # Critical (least verbose) 73 | # Error 74 | # Warning 75 | # Notice 76 | # Connect (to log connections without Info's noise) 77 | # Info (most verbose) 78 | # The LogLevel logs from the set level and above. For example, if the LogLevel 79 | # was set to Warning, than all log messages from Warning to Critical would be 80 | # output, but Notice and below would be suppressed. 81 | # 82 | LogLevel Error 83 | 84 | # 85 | # PidFile: Write the PID of the main tinyproxy thread to this file so it 86 | # can be used for signalling purposes. 87 | # 88 | PidFile "/var/run/tinyproxy.pid" 89 | 90 | # 91 | # Include the X-Tinyproxy header, which has the client's IP address when 92 | # connecting to the sites listed. 93 | # 94 | #XTinyproxy mydomain.com 95 | 96 | # 97 | # Turns on upstream proxy support. 98 | # 99 | # The upstream rules allow you to selectively route upstream connections 100 | # based on the host/domain of the site being accessed. 101 | # 102 | # For example: 103 | # # connection to test domain goes through testproxy 104 | # upstream testproxy:8008 ".test.domain.invalid" 105 | # upstream testproxy:8008 ".our_testbed.example.com" 106 | # upstream testproxy:8008 "192.168.128.0/255.255.254.0" 107 | # 108 | # # no upstream proxy for internal websites and unqualified hosts 109 | # no upstream ".internal.example.com" 110 | # no upstream "www.example.com" 111 | # no upstream "10.0.0.0/8" 112 | # no upstream "192.168.0.0/255.255.254.0" 113 | # no upstream "." 114 | # 115 | # # connection to these boxes go through their DMZ firewalls 116 | # upstream cust1_firewall:8008 "testbed_for_cust1" 117 | # upstream cust2_firewall:8008 "testbed_for_cust2" 118 | # 119 | # # default upstream is internet firewall 120 | # upstream firewall.internal.example.com:80 121 | # 122 | # The LAST matching rule wins the route decision. As you can see, you 123 | # can use a host, or a domain: 124 | # name matches host exactly 125 | # .name matches any host in domain "name" 126 | # . matches any host with no domain (in 'empty' domain) 127 | # IP/bits matches network/mask 128 | # IP/mask matches network/mask 129 | # 130 | Upstream socks5 127.0.0.1:23456 131 | 132 | # 133 | # This is the absolute highest number of threads which will be created. In 134 | # other words, only MaxClients number of clients can be connected at the 135 | # same time. 136 | # 137 | MaxClients 100 138 | 139 | # 140 | # These settings set the upper and lower limit for the number of 141 | # spare servers which should be available. If the number of spare servers 142 | # falls below MinSpareServers then new ones will be created. If the number 143 | # of servers exceeds MaxSpareServers then the extras will be killed off. 144 | # 145 | MinSpareServers 5 146 | MaxSpareServers 20 147 | 148 | # 149 | # Number of servers to start initially. 150 | # 151 | StartServers 10 152 | 153 | # 154 | # MaxRequestsPerChild is the number of connections a thread will handle 155 | # before it is killed. In practise this should be set to 0, which disables 156 | # thread reaping. If you do notice problems with memory leakage, then set 157 | # this to something like 10000 158 | # 159 | MaxRequestsPerChild 0 160 | 161 | # 162 | # The following is the authorization controls. If there are any access 163 | # control keywords then the default action is to DENY. Otherwise, the 164 | # default action is ALLOW. 165 | # 166 | # Also the order of the controls are important. The incoming connections 167 | # are tested against the controls based on order. 168 | # 169 | #Allow 127.0.0.1 170 | #Allow 192.168.1.0/25 171 | 172 | # 173 | # The "Via" header is required by the HTTP RFC, but using the real host name 174 | # is a security concern. If the following directive is enabled, the string 175 | # supplied will be used as the host name in the Via header; otherwise, the 176 | # server's host name will be used. 177 | # 178 | ViaProxyName "tinyproxy" 179 | 180 | # 181 | # The location of the filter file. 182 | # 183 | #Filter "/etc/tinyproxy/filter" 184 | 185 | # 186 | # Filter based on URLs rather than domains. 187 | # 188 | #FilterURLs On 189 | 190 | # 191 | # Use POSIX Extended regular expressions rather than basic. 192 | # 193 | #FilterExtended On 194 | 195 | # 196 | # Use case sensitive regular expressions. 197 | # 198 | #FilterCaseSensitive On 199 | 200 | # 201 | # Change the default policy of the filtering system. If this directive is 202 | # commented out, or is set to "No" then the default policy is to allow 203 | # everything which is not specifically denied by the filter file. 204 | # 205 | # However, by setting this directive to "Yes" the default policy becomes to 206 | # deny everything which is _not_ specifically allowed by the filter file. 207 | # 208 | #FilterDefaultDeny Yes 209 | 210 | # 211 | # If an Anonymous keyword is present, then anonymous proxying is enabled. 212 | # The headers listed are allowed through, while all others are denied. If 213 | # no Anonymous keyword is present, then all header are allowed through. 214 | # You must include quotes around the headers. 215 | # 216 | #Anonymous "Host" 217 | #Anonymous "Authorization" 218 | 219 | # 220 | # This is a list of ports allowed by tinyproxy when the CONNECT method 221 | # is used. To disable the CONNECT method altogether, set the value to 0. 222 | # If no ConnectPort line is found, all ports are allowed (which is not 223 | # very secure.) 224 | # 225 | # The following two ports are used by SSL. 226 | # 227 | ConnectPort 443 228 | ConnectPort 563 229 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # install - install a program, script, or datafile 4 | # This comes from X11R5 (mit/util/scripts/install.sh). 5 | # 6 | # Copyright 1991 by the Massachusetts Institute of Technology 7 | # 8 | # Permission to use, copy, modify, distribute, and sell this software and its 9 | # documentation for any purpose is hereby granted without fee, provided that 10 | # the above copyright notice appear in all copies and that both that 11 | # copyright notice and this permission notice appear in supporting 12 | # documentation, and that the name of M.I.T. not be used in advertising or 13 | # publicity pertaining to distribution of the software without specific, 14 | # written prior permission. M.I.T. makes no representations about the 15 | # suitability of this software for any purpose. It is provided "as is" 16 | # without express or implied warranty. 17 | # 18 | # Calling this script install-sh is preferred over install.sh, to prevent 19 | # `make' implicit rules from creating a file called install from it 20 | # when there is no Makefile. 21 | # 22 | # This script is compatible with the BSD install script, but was written 23 | # from scratch. It can only install one file at a time, a restriction 24 | # shared with many OS's install programs. 25 | 26 | 27 | # set DOITPROG to echo to test this script 28 | 29 | # Don't use :- since 4.3BSD and earlier shells don't like it. 30 | doit="${DOITPROG-}" 31 | 32 | 33 | # put in absolute paths if you don't have them in your path; or use env. vars. 34 | 35 | mvprog="${MVPROG-mv}" 36 | cpprog="${CPPROG-cp}" 37 | chmodprog="${CHMODPROG-chmod}" 38 | chownprog="${CHOWNPROG-chown}" 39 | chgrpprog="${CHGRPPROG-chgrp}" 40 | stripprog="${STRIPPROG-strip}" 41 | rmprog="${RMPROG-rm}" 42 | mkdirprog="${MKDIRPROG-mkdir}" 43 | 44 | transformbasename="" 45 | transform_arg="" 46 | instcmd="$mvprog" 47 | chmodcmd="$chmodprog 0755" 48 | chowncmd="" 49 | chgrpcmd="" 50 | stripcmd="" 51 | rmcmd="$rmprog -f" 52 | mvcmd="$mvprog" 53 | src="" 54 | dst="" 55 | dir_arg="" 56 | 57 | while [ x"$1" != x ]; do 58 | case $1 in 59 | -c) instcmd="$cpprog" 60 | shift 61 | continue;; 62 | 63 | -d) dir_arg=true 64 | shift 65 | continue;; 66 | 67 | -m) chmodcmd="$chmodprog $2" 68 | shift 69 | shift 70 | continue;; 71 | 72 | -o) chowncmd="$chownprog $2" 73 | shift 74 | shift 75 | continue;; 76 | 77 | -g) chgrpcmd="$chgrpprog $2" 78 | shift 79 | shift 80 | continue;; 81 | 82 | -s) stripcmd="$stripprog" 83 | shift 84 | continue;; 85 | 86 | -t=*) transformarg=`echo $1 | sed 's/-t=//'` 87 | shift 88 | continue;; 89 | 90 | -b=*) transformbasename=`echo $1 | sed 's/-b=//'` 91 | shift 92 | continue;; 93 | 94 | *) if [ x"$src" = x ] 95 | then 96 | src=$1 97 | else 98 | # this colon is to work around a 386BSD /bin/sh bug 99 | : 100 | dst=$1 101 | fi 102 | shift 103 | continue;; 104 | esac 105 | done 106 | 107 | if [ x"$src" = x ] 108 | then 109 | echo "install: no input file specified" 110 | exit 1 111 | else 112 | true 113 | fi 114 | 115 | if [ x"$dir_arg" != x ]; then 116 | dst=$src 117 | src="" 118 | 119 | if [ -d $dst ]; then 120 | instcmd=: 121 | chmodcmd="" 122 | else 123 | instcmd=mkdir 124 | fi 125 | else 126 | 127 | # Waiting for this to be detected by the "$instcmd $src $dsttmp" command 128 | # might cause directories to be created, which would be especially bad 129 | # if $src (and thus $dsttmp) contains '*'. 130 | 131 | if [ -f $src -o -d $src ] 132 | then 133 | true 134 | else 135 | echo "install: $src does not exist" 136 | exit 1 137 | fi 138 | 139 | if [ x"$dst" = x ] 140 | then 141 | echo "install: no destination specified" 142 | exit 1 143 | else 144 | true 145 | fi 146 | 147 | # If destination is a directory, append the input filename; if your system 148 | # does not like double slashes in filenames, you may need to add some logic 149 | 150 | if [ -d $dst ] 151 | then 152 | dst="$dst"/`basename $src` 153 | else 154 | true 155 | fi 156 | fi 157 | 158 | ## this sed command emulates the dirname command 159 | dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` 160 | 161 | # Make sure that the destination directory exists. 162 | # this part is taken from Noah Friedman's mkinstalldirs script 163 | 164 | # Skip lots of stat calls in the usual case. 165 | if [ ! -d "$dstdir" ]; then 166 | defaultIFS=' 167 | ' 168 | IFS="${IFS-${defaultIFS}}" 169 | 170 | oIFS="${IFS}" 171 | # Some sh's can't handle IFS=/ for some reason. 172 | IFS='%' 173 | set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` 174 | IFS="${oIFS}" 175 | 176 | pathcomp='' 177 | 178 | while [ $# -ne 0 ] ; do 179 | pathcomp="${pathcomp}${1}" 180 | shift 181 | 182 | if [ ! -d "${pathcomp}" ] ; 183 | then 184 | $mkdirprog "${pathcomp}" 185 | else 186 | true 187 | fi 188 | 189 | pathcomp="${pathcomp}/" 190 | done 191 | fi 192 | 193 | if [ x"$dir_arg" != x ] 194 | then 195 | $doit $instcmd $dst && 196 | 197 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && 198 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && 199 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && 200 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi 201 | else 202 | 203 | # If we're going to rename the final executable, determine the name now. 204 | 205 | if [ x"$transformarg" = x ] 206 | then 207 | dstfile=`basename $dst` 208 | else 209 | dstfile=`basename $dst $transformbasename | 210 | sed $transformarg`$transformbasename 211 | fi 212 | 213 | # don't allow the sed command to completely eliminate the filename 214 | 215 | if [ x"$dstfile" = x ] 216 | then 217 | dstfile=`basename $dst` 218 | else 219 | true 220 | fi 221 | 222 | # Make a temp file name in the proper directory. 223 | 224 | dsttmp=$dstdir/#inst.$$# 225 | 226 | # Move or copy the file name to the temp name 227 | 228 | $doit $instcmd $src $dsttmp && 229 | 230 | trap "rm -f ${dsttmp}" 0 && 231 | 232 | # and set any options; do chmod last to preserve setuid bits 233 | 234 | # If any of these fail, we abort the whole thing. If we want to 235 | # ignore errors from any of these, just make sure not to ignore 236 | # errors from the above "$doit $instcmd $src $dsttmp" command. 237 | 238 | if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && 239 | if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && 240 | if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && 241 | if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && 242 | 243 | # Now rename the file to the real destination. 244 | 245 | $doit $rmcmd -f $dstdir/$dstfile && 246 | $doit $mvcmd $dsttmp $dstdir/$dstfile 247 | 248 | fi && 249 | 250 | 251 | exit 0 252 | -------------------------------------------------------------------------------- /missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common stub for a few missing GNU programs while installing. 3 | # Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc. 4 | # Franc,ois Pinard , 1996. 5 | 6 | # This program is free software; you can redistribute it and/or modify 7 | # it under the terms of the GNU General Public License as published by 8 | # the Free Software Foundation; either version 2, or (at your option) 9 | # any later version. 10 | 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 | # 02111-1307, USA. 20 | 21 | if test $# -eq 0; then 22 | echo 1>&2 "Try \`$0 --help' for more information" 23 | exit 1 24 | fi 25 | 26 | # In the cases where this matters, `missing' is being run in the 27 | # srcdir already. 28 | if test -f configure.in; then 29 | configure_ac=configure.ac 30 | else 31 | configure_ac=configure.in 32 | fi 33 | 34 | case "$1" in 35 | 36 | -h|--h|--he|--hel|--help) 37 | echo "\ 38 | $0 [OPTION]... PROGRAM [ARGUMENT]... 39 | 40 | Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an 41 | error status if there is no known handling for PROGRAM. 42 | 43 | Options: 44 | -h, --help display this help and exit 45 | -v, --version output version information and exit 46 | 47 | Supported PROGRAM values: 48 | aclocal touch file \`aclocal.m4' 49 | autoconf touch file \`configure' 50 | autoheader touch file \`config.h.in' 51 | automake touch all \`Makefile.in' files 52 | bison create \`y.tab.[ch]', if possible, from existing .[ch] 53 | flex create \`lex.yy.c', if possible, from existing .c 54 | lex create \`lex.yy.c', if possible, from existing .c 55 | makeinfo touch the output file 56 | yacc create \`y.tab.[ch]', if possible, from existing .[ch]" 57 | ;; 58 | 59 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 60 | echo "missing - GNU libit 0.0" 61 | ;; 62 | 63 | -*) 64 | echo 1>&2 "$0: Unknown \`$1' option" 65 | echo 1>&2 "Try \`$0 --help' for more information" 66 | exit 1 67 | ;; 68 | 69 | aclocal*) 70 | echo 1>&2 "\ 71 | WARNING: \`$1' is missing on your system. You should only need it if 72 | you modified \`acinclude.m4' or \`$configure_ac'. You might want 73 | to install the \`Automake' and \`Perl' packages. Grab them from 74 | any GNU archive site." 75 | touch aclocal.m4 76 | ;; 77 | 78 | autoconf) 79 | echo 1>&2 "\ 80 | WARNING: \`$1' is missing on your system. You should only need it if 81 | you modified \`$configure_ac'. You might want to install the 82 | \`Autoconf' and \`GNU m4' packages. Grab them from any GNU 83 | archive site." 84 | touch configure 85 | ;; 86 | 87 | autoheader) 88 | echo 1>&2 "\ 89 | WARNING: \`$1' is missing on your system. You should only need it if 90 | you modified \`acconfig.h' or \`$configure_ac'. You might want 91 | to install the \`Autoconf' and \`GNU m4' packages. Grab them 92 | from any GNU archive site." 93 | files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` 94 | test -z "$files" && files="config.h" 95 | touch_files= 96 | for f in $files; do 97 | case "$f" in 98 | *:*) touch_files="$touch_files "`echo "$f" | 99 | sed -e 's/^[^:]*://' -e 's/:.*//'`;; 100 | *) touch_files="$touch_files $f.in";; 101 | esac 102 | done 103 | touch $touch_files 104 | ;; 105 | 106 | automake*) 107 | echo 1>&2 "\ 108 | WARNING: \`$1' is missing on your system. You should only need it if 109 | you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. 110 | You might want to install the \`Automake' and \`Perl' packages. 111 | Grab them from any GNU archive site." 112 | find . -type f -name Makefile.am -print | 113 | sed 's/\.am$/.in/' | 114 | while read f; do touch "$f"; done 115 | ;; 116 | 117 | bison|yacc) 118 | echo 1>&2 "\ 119 | WARNING: \`$1' is missing on your system. You should only need it if 120 | you modified a \`.y' file. You may need the \`Bison' package 121 | in order for those modifications to take effect. You can get 122 | \`Bison' from any GNU archive site." 123 | rm -f y.tab.c y.tab.h 124 | if [ $# -ne 1 ]; then 125 | eval LASTARG="\${$#}" 126 | case "$LASTARG" in 127 | *.y) 128 | SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` 129 | if [ -f "$SRCFILE" ]; then 130 | cp "$SRCFILE" y.tab.c 131 | fi 132 | SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` 133 | if [ -f "$SRCFILE" ]; then 134 | cp "$SRCFILE" y.tab.h 135 | fi 136 | ;; 137 | esac 138 | fi 139 | if [ ! -f y.tab.h ]; then 140 | echo >y.tab.h 141 | fi 142 | if [ ! -f y.tab.c ]; then 143 | echo 'main() { return 0; }' >y.tab.c 144 | fi 145 | ;; 146 | 147 | lex|flex) 148 | echo 1>&2 "\ 149 | WARNING: \`$1' is missing on your system. You should only need it if 150 | you modified a \`.l' file. You may need the \`Flex' package 151 | in order for those modifications to take effect. You can get 152 | \`Flex' from any GNU archive site." 153 | rm -f lex.yy.c 154 | if [ $# -ne 1 ]; then 155 | eval LASTARG="\${$#}" 156 | case "$LASTARG" in 157 | *.l) 158 | SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` 159 | if [ -f "$SRCFILE" ]; then 160 | cp "$SRCFILE" lex.yy.c 161 | fi 162 | ;; 163 | esac 164 | fi 165 | if [ ! -f lex.yy.c ]; then 166 | echo 'main() { return 0; }' >lex.yy.c 167 | fi 168 | ;; 169 | 170 | makeinfo) 171 | echo 1>&2 "\ 172 | WARNING: \`$1' is missing on your system. You should only need it if 173 | you modified a \`.texi' or \`.texinfo' file, or any other file 174 | indirectly affecting the aspect of the manual. The spurious 175 | call might also be the consequence of using a buggy \`make' (AIX, 176 | DU, IRIX). You might want to install the \`Texinfo' package or 177 | the \`GNU make' package. Grab either from any GNU archive site." 178 | file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` 179 | if test -z "$file"; then 180 | file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` 181 | file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` 182 | fi 183 | touch $file 184 | ;; 185 | 186 | *) 187 | echo 1>&2 "\ 188 | WARNING: \`$1' is needed, and you do not seem to have it handy on your 189 | system. You might have modified some files without having the 190 | proper tools for further handling them. Check the \`README' file, 191 | it often tells you about the needed prerequirements for installing 192 | this package. You may also peek at any GNU archive site, in case 193 | some other package would contain this missing \`$1' program." 194 | exit 1 195 | ;; 196 | esac 197 | 198 | exit 0 199 | -------------------------------------------------------------------------------- /mkinstalldirs: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # mkinstalldirs --- make directory hierarchy 3 | # Author: Noah Friedman 4 | # Created: 1993-05-16 5 | # Public domain 6 | 7 | # $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ 8 | 9 | errstatus=0 10 | 11 | for file 12 | do 13 | set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` 14 | shift 15 | 16 | pathcomp= 17 | for d 18 | do 19 | pathcomp="$pathcomp$d" 20 | case "$pathcomp" in 21 | -* ) pathcomp=./$pathcomp ;; 22 | esac 23 | 24 | if test ! -d "$pathcomp"; then 25 | echo "mkdir $pathcomp" 26 | 27 | mkdir "$pathcomp" || lasterr=$? 28 | 29 | if test ! -d "$pathcomp"; then 30 | errstatus=$lasterr 31 | fi 32 | fi 33 | 34 | pathcomp="$pathcomp/" 35 | done 36 | done 37 | 38 | exit $errstatus 39 | 40 | # mkinstalldirs ends here 41 | -------------------------------------------------------------------------------- /packaging/redhat/tinyproxy-1.5.2-config-patch: -------------------------------------------------------------------------------- 1 | --- doc/tinyproxy.conf 2003-02-01 22:03:25.000000000 -0500 2 | +++ doc/tinyproxy.conf 2003-02-01 22:05:01.000000000 -0500 3 | @@ -7,7 +7,7 @@ 4 | # has been bound. 5 | # 6 | User nobody 7 | -Group nogroup 8 | +Group nobody 9 | 10 | # 11 | # Port to listen on. 12 | ## -108,7 +108,7 @@ 13 | # are tested against the controls based on order. 14 | # 15 | Allow 127.0.0.1 16 | - Allow 192.168.1.0/25 17 | +# Allow 192.168.1.0/25 18 | 19 | -------------------------------------------------------------------------------- /packaging/redhat/tinyproxy-initd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # initfile for tinyproxy 4 | # 5 | # description: A small, efficient HTTP/SSL proxy daemon. 6 | # 7 | # processname: tinyproxy 8 | # 9 | # chkconfig 2345 10 | # 11 | 12 | . /etc/rc.d/init.d/functions 13 | 14 | case "$1" in 15 | start) 16 | echo -n "Starting tinyproxy: " 17 | daemon /usr/sbin/tinyproxy 18 | touch /var/lock/subsys/tinyproxy 19 | echo 20 | ;; 21 | stop) 22 | echo -n "Shutting down tinyproxy: " 23 | killproc tinyproxy 24 | rm -f /var/lock/subsys/tinyproxy 25 | echo 26 | ;; 27 | restart) 28 | $0 stop 29 | $0 start 30 | ;; 31 | status) 32 | status tinyproxy 33 | ;; 34 | *) 35 | echo "Usage: tinyproxy {start|stop|restart|status}" 36 | exit 1 37 | esac 38 | 39 | exit 0 40 | 41 | 42 | -------------------------------------------------------------------------------- /packaging/redhat/tinyproxy.spec: -------------------------------------------------------------------------------- 1 | Summary: A small, efficient HTTP/SSL proxy daemon. 2 | Name: tinyproxy 3 | Version: 1.5.2 4 | Release: 1 5 | License: GPL 6 | Group: System Environment/Daemons 7 | URL: http://tinyproxy.sourceforge.net 8 | Prefix: %{_prefix} 9 | Packager: S. A. Hutchins 10 | Source: tinyproxy-1.5.2.tar.gz 11 | Source1: tinyproxy-initd 12 | Patch0: tinyproxy-1.5.2-config-patch 13 | BuildRoot: %{_tmppath}/%{name}-%{version}-root 14 | 15 | %description 16 | tinyproxy is a small, efficient HTTP/SSL proxy daemon released under the GNU 17 | General Public License (GPL). tinyproxy is very useful in a small network 18 | setting, where a larger proxy like Squid would either be too resource 19 | intensive, or a security risk. 20 | 21 | %prep 22 | %setup 23 | %patch 24 | 25 | %build 26 | ./configure --enable-transparent-proxy --prefix=%{_prefix} \ 27 | --mandir=%{_mandir} 28 | make 29 | 30 | %install 31 | if [ "$RPM_BUILD_ROOT" != "/" ]; then 32 | rm -rf $RPM_BUILD_ROOT 33 | fi 34 | 35 | pwd 36 | 37 | cd $RPM_BUILD_DIR/%{name}-%{version} 38 | make install prefix=%{_prefix} DESTDIR="$RPM_BUILD_ROOT" 39 | 40 | mkdir -p $RPM_BUILD_ROOT/etc/init.d 41 | cp -f $RPM_SOURCE_DIR/tinyproxy-initd $RPM_BUILD_ROOT/etc/init.d/tinyproxy 42 | 43 | %files 44 | %defattr(-, root, root) 45 | %{_sbindir}/tinyproxy 46 | %{_mandir}/* 47 | 48 | %defattr(0755, root, root) 49 | /etc/init.d/tinyproxy 50 | 51 | %defattr(0600, root, root) 52 | /etc/tinyproxy/tinyproxy.conf 53 | /etc/tinyproxy/tinyproxy.conf-dist 54 | 55 | %doc AUTHORS COPYING INSTALL NEWS README TODO 56 | %doc ChangeLog 57 | %doc doc/filter-howto.txt 58 | %doc doc/HTTP_ERROR_CODES 59 | %doc doc/releases.txt 60 | %doc doc/RFC_INFO 61 | %doc doc/report.sh 62 | 63 | %clean 64 | if [ "$RPM_BUILD_DIR" != "/" ]; then 65 | rm -rf $RPM_BUILD_DIR/%{name}-%{version} 66 | fi 67 | if [ "$RPM_BUILD_ROOT" != "/" ]; then 68 | rm -rf $RPM_BUILD_ROOT 69 | fi 70 | 71 | %changelog 72 | * Sat Feb 01 2003 S. A. Hutchins 73 | - From the depths of the void this beast I spawn. I added an initrd script for 74 | this so it can be started/stopped from /sbin/service. My version of RedHat 75 | doesn't have a 'nogroup' so used nobody instead. 76 | 77 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # $Id: Makefile.am,v 1.17 2003/06/26 18:23:01 rjkaes Exp $ 2 | # 3 | # Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 4 | # 5 | # This program is free software; you can redistribute it and/or modify it 6 | # under the terms of the GNU General Public License as published by the 7 | # Free Software Foundation; either version 2, or (at your option) any 8 | # later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | 16 | YFLAGS = @YFLAGS@ 17 | LDFLAGS = @LDFLAGS@ 18 | 19 | sbin_PROGRAMS = tinyproxy 20 | 21 | tinyproxy_SOURCES = \ 22 | acl.c acl.h \ 23 | anonymous.c anonymous.h \ 24 | buffer.c buffer.h \ 25 | child.c child.h \ 26 | common.h \ 27 | conns.c conns.h \ 28 | daemon.c daemon.h \ 29 | hashmap.c hashmap.h \ 30 | heap.c heap.h \ 31 | htmlerror.c htmlerror.h \ 32 | http_message.c http_message.h \ 33 | log.c log.h \ 34 | network.c network.h \ 35 | reqs.c reqs.h \ 36 | sock.c sock.h \ 37 | stats.c stats.h \ 38 | text.c text.h \ 39 | tinyproxy.c tinyproxy.h \ 40 | utils.c utils.h \ 41 | vector.c vector.h \ 42 | grammar.y scanner.l \ 43 | regexp.h 44 | 45 | EXTRA_DIST = gnuregex.c gnuregex.h 46 | EXTRA_tinyproxy_SOURCES = filter.c filter.h grammar.h 47 | tinyproxy_DEPENDENCIES = @ADDITIONAL_OBJECTS@ 48 | tinyproxy_LDADD = @ADDITIONAL_OBJECTS@ 49 | 50 | scanner.c: scanner.l grammar.h 51 | $(LEX) $(LEX_FLAGS) $(LFLAGS) -i $< && mv $(LEX_OUTPUT_ROOT).c $@ 52 | 53 | clean: 54 | rm -f *.da 55 | rm -f gmon.out 56 | -------------------------------------------------------------------------------- /src/acl.c: -------------------------------------------------------------------------------- 1 | /* $Id: acl.c,v 1.16 2002/06/05 16:59:21 rjkaes Exp $ 2 | * 3 | * This system handles Access Control for use of this daemon. A list of 4 | * domains, or IP addresses (including IP blocks) are stored in a list 5 | * which is then used to compare incoming connections. 6 | * 7 | * Copyright (C) 2000,2002 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published by the 11 | * Free Software Foundation; either version 2, or (at your option) any 12 | * later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | */ 19 | 20 | #include "tinyproxy.h" 21 | 22 | #include "acl.h" 23 | #include "heap.h" 24 | #include "log.h" 25 | #include "sock.h" 26 | 27 | struct acl_s { 28 | acl_access_t acl_access; 29 | enum { ACL_STRING, ACL_NUMERIC } type; 30 | char *location; 31 | int netmask; 32 | struct acl_s *next; 33 | }; 34 | 35 | static struct acl_s *access_list = NULL; 36 | 37 | /* 38 | * Take a netmask number (between 0 and 32) and returns a network ordered 39 | * value for comparison. 40 | */ 41 | static in_addr_t 42 | make_netmask(int netmask_num) 43 | { 44 | assert(netmask_num >= 0 && netmask_num <= 32); 45 | 46 | return htonl(~((1 << (32 - netmask_num)) - 1)); 47 | } 48 | 49 | /* 50 | * Inserts a new access control into the list. The function will figure out 51 | * whether the location is an IP address (with optional netmask) or a 52 | * domain name. 53 | * 54 | * Returns: 55 | * -1 on failure 56 | * 0 otherwise. 57 | */ 58 | int 59 | insert_acl(char *location, acl_access_t access_type) 60 | { 61 | size_t i; 62 | struct acl_s **rev_acl_ptr, *acl_ptr, *new_acl_ptr; 63 | char *nptr; 64 | 65 | assert(location != NULL); 66 | 67 | /* 68 | * First check to see if the location is a string or numeric. 69 | */ 70 | for (i = 0; location[i] != '\0'; i++) { 71 | /* 72 | * Numeric strings can not contain letters, so test on it. 73 | */ 74 | if (isalpha((unsigned char) location[i])) { 75 | break; 76 | } 77 | } 78 | 79 | /* 80 | * Add a new ACL to the list. 81 | */ 82 | rev_acl_ptr = &access_list; 83 | acl_ptr = access_list; 84 | while (acl_ptr) { 85 | rev_acl_ptr = &acl_ptr->next; 86 | acl_ptr = acl_ptr->next; 87 | } 88 | new_acl_ptr = safemalloc(sizeof(struct acl_s)); 89 | if (!new_acl_ptr) { 90 | return -1; 91 | } 92 | 93 | new_acl_ptr->acl_access = access_type; 94 | 95 | if (location[i] == '\0') { 96 | DEBUG2("ACL \"%s\" is a number.", location); 97 | 98 | /* 99 | * We did not break early, so this a numeric location. 100 | * Check for a netmask. 101 | */ 102 | new_acl_ptr->type = ACL_NUMERIC; 103 | nptr = strchr(location, '/'); 104 | if (nptr) { 105 | *nptr++ = '\0'; 106 | 107 | new_acl_ptr->netmask = strtol(nptr, NULL, 10); 108 | if (new_acl_ptr->netmask < 0 109 | || new_acl_ptr->netmask > 32) { 110 | safefree(new_acl_ptr); 111 | return -1; 112 | } 113 | } else { 114 | new_acl_ptr->netmask = 32; 115 | } 116 | } else { 117 | DEBUG2("ACL \"%s\" is a string.", location); 118 | 119 | new_acl_ptr->type = ACL_STRING; 120 | new_acl_ptr->netmask = 32; 121 | } 122 | 123 | new_acl_ptr->location = safestrdup(location); 124 | if (!new_acl_ptr->location) { 125 | safefree(new_acl_ptr); 126 | return -1; 127 | } 128 | 129 | *rev_acl_ptr = new_acl_ptr; 130 | new_acl_ptr->next = acl_ptr; 131 | 132 | return 0; 133 | } 134 | 135 | /* 136 | * This function is called whenever a "string" access control is found in 137 | * the ACL. From here we do both a text based string comparison, along with 138 | * a reverse name lookup comparison of the IP addresses. 139 | * 140 | * Return: 0 if host is denied 141 | * 1 if host is allowed 142 | * -1 if no tests match, so skip 143 | */ 144 | static inline int 145 | acl_string_processing(struct acl_s* aclptr, 146 | const char* ip_address, 147 | const char* string_address) 148 | { 149 | int i; 150 | struct hostent* result; 151 | size_t test_length, match_length; 152 | 153 | /* 154 | * If the first character of the ACL string is a period, we need to 155 | * do a string based test only; otherwise, we can do a reverse 156 | * lookup test as well. 157 | */ 158 | if (aclptr->location[0] != '.') { 159 | /* It is not a partial domain, so do a reverse lookup. */ 160 | result = gethostbyname(aclptr->location); 161 | if (!result) 162 | goto STRING_TEST; 163 | 164 | for (i = 0; result->h_addr_list[i]; ++i) { 165 | if (strcmp(ip_address, 166 | inet_ntoa(*((struct in_addr*)result->h_addr_list[i]))) == 0) { 167 | /* We have a match */ 168 | if (aclptr->acl_access == ACL_DENY) { 169 | return 0; 170 | } else { 171 | DEBUG2("Matched using reverse domain lookup: %s", ip_address); 172 | return 1; 173 | } 174 | } 175 | } 176 | 177 | /* 178 | * If we got this far, the reverse didn't match, so drop down 179 | * to a standard string test. 180 | */ 181 | } 182 | 183 | STRING_TEST: 184 | test_length = strlen(string_address); 185 | match_length = strlen(aclptr->location); 186 | 187 | /* 188 | * If the string length is shorter than AC string, return a -1 so 189 | * that the "driver" will skip onto the next control in the list. 190 | */ 191 | if (test_length < match_length) 192 | return -1; 193 | 194 | if (strcasecmp(string_address + (test_length - match_length), aclptr->location) == 0) { 195 | if (aclptr->acl_access == ACL_DENY) 196 | return 0; 197 | else 198 | return 1; 199 | } 200 | 201 | /* Indicate that no tests succeeded, so skip to next control. */ 202 | return -1; 203 | } 204 | 205 | /* 206 | * Checks whether file descriptor is allowed. 207 | * 208 | * Returns: 209 | * 1 if allowed 210 | * 0 if denied 211 | */ 212 | int 213 | check_acl(int fd, const char* ip_address, const char* string_address) 214 | { 215 | struct acl_s* aclptr; 216 | int ret; 217 | 218 | assert(fd >= 0); 219 | assert(ip_address != NULL); 220 | assert(string_address != NULL); 221 | 222 | /* 223 | * If there is no access list allow everything. 224 | */ 225 | aclptr = access_list; 226 | if (!aclptr) 227 | return 1; 228 | 229 | while (aclptr) { 230 | if (aclptr->type == ACL_STRING) { 231 | ret = acl_string_processing(aclptr, 232 | ip_address, 233 | string_address); 234 | if (ret == 0) 235 | goto UNAUTHORIZED; 236 | else if (ret == 1) 237 | return 1; 238 | 239 | aclptr = aclptr->next; 240 | continue; 241 | } else { 242 | struct in_addr test_addr, match_addr; 243 | in_addr_t netmask_addr; 244 | 245 | if (ip_address[0] == 0) { 246 | aclptr = aclptr->next; 247 | continue; 248 | } 249 | 250 | inet_aton(ip_address, &test_addr); 251 | inet_aton(aclptr->location, &match_addr); 252 | 253 | netmask_addr = make_netmask(aclptr->netmask); 254 | 255 | if ((test_addr.s_addr & netmask_addr) == 256 | (match_addr.s_addr & netmask_addr)) { 257 | if (aclptr->acl_access == ACL_DENY) 258 | goto UNAUTHORIZED; 259 | else 260 | return 1; 261 | } 262 | } 263 | 264 | /* 265 | * Dropped through... go on to the next one. 266 | */ 267 | aclptr = aclptr->next; 268 | } 269 | 270 | /* 271 | * Deny all connections by default. 272 | */ 273 | UNAUTHORIZED: 274 | log_message(LOG_NOTICE, "Unauthorized connection from \"%s\" [%s].", 275 | string_address, ip_address); 276 | return 0; 277 | } 278 | -------------------------------------------------------------------------------- /src/acl.h: -------------------------------------------------------------------------------- 1 | /* $Id: acl.h,v 1.3 2002/04/17 20:52:45 rjkaes Exp $ 2 | * 3 | * See 'acl.c' for detailed information. 4 | * 5 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_ACL_H 19 | #define TINYPROXY_ACL_H 20 | 21 | typedef enum { ACL_ALLOW, ACL_DENY } acl_access_t; 22 | 23 | extern int insert_acl(char *location, acl_access_t access_type); 24 | extern int check_acl(int fd, const char* ip_address, const char* string_address); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/anonymous.c: -------------------------------------------------------------------------------- 1 | /* $Id: anonymous.c,v 1.14 2002/05/23 18:20:27 rjkaes Exp $ 2 | * 3 | * Handles insertion and searches for headers which should be let through when 4 | * the anonymous feature is turned on. 5 | * 6 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #include "tinyproxy.h" 20 | 21 | #include "anonymous.h" 22 | #include "hashmap.h" 23 | #include "heap.h" 24 | #include "log.h" 25 | 26 | static hashmap_t anonymous_map = NULL; 27 | 28 | short int 29 | is_anonymous_enabled(void) 30 | { 31 | return (anonymous_map != NULL) ? 1 : 0; 32 | } 33 | 34 | /* 35 | * Search for the header. This function returns a positive value greater than 36 | * zero if the string was found, zero if it wasn't and negative upon error. 37 | */ 38 | int 39 | anonymous_search(char *s) 40 | { 41 | assert(s != NULL); 42 | assert(anonymous_map != NULL); 43 | 44 | return hashmap_search(anonymous_map, s); 45 | } 46 | 47 | /* 48 | * Insert a new header. 49 | * 50 | * Return -1 if there is an error, otherwise a 0 is returned if the insert was 51 | * successful. 52 | */ 53 | int 54 | anonymous_insert(char *s) 55 | { 56 | char data = 1; 57 | 58 | assert(s != NULL); 59 | 60 | if (!anonymous_map) { 61 | anonymous_map = hashmap_create(32); 62 | if (!anonymous_map) 63 | return -1; 64 | } 65 | 66 | if (hashmap_search(anonymous_map, s) > 0) { 67 | /* The key was already found, so return a positive number. */ 68 | return 0; 69 | } 70 | 71 | /* Insert the new key */ 72 | return hashmap_insert(anonymous_map, s, &data, sizeof(data)); 73 | } 74 | -------------------------------------------------------------------------------- /src/anonymous.h: -------------------------------------------------------------------------------- 1 | /* $Id: anonymous.h,v 1.6 2001/12/15 20:08:24 rjkaes Exp $ 2 | * 3 | * See 'anonymous.c' for a detailed description. 4 | * 5 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef _TINYPROXY_ANONYMOUS_H_ 19 | #define _TINYPROXY_ANONYMOUS_H_ 20 | 21 | extern short int is_anonymous_enabled(void); 22 | extern int anonymous_search(char *s); 23 | extern int anonymous_insert(char *s); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/buffer.c: -------------------------------------------------------------------------------- 1 | /* $Id: buffer.c,v 1.22 2002/05/24 04:45:32 rjkaes Exp $ 2 | * 3 | * The buffer used in each connection is a linked list of lines. As the lines 4 | * are read in and written out the buffer expands and contracts. Basically, 5 | * by using this method we can increase the buffer size dynamically. However, 6 | * we have a hard limit of 64 KB for the size of the buffer. The buffer can be 7 | * thought of as a queue were we act on both the head and tail. The various 8 | * functions act on each end (the names are taken from what Perl uses to act on 9 | * the ends of an array. :) 10 | * 11 | * Copyright (C) 1999,2001 Robert James Kaes (rjkaes@users.sourceforge.net) 12 | * 13 | * This program is free software; you can redistribute it and/or modify it 14 | * under the terms of the GNU General Public License as published by the 15 | * Free Software Foundation; either version 2, or (at your option) any 16 | * later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, but 19 | * WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | * General Public License for more details. 22 | */ 23 | 24 | #include "tinyproxy.h" 25 | 26 | #include "buffer.h" 27 | #include "heap.h" 28 | #include "log.h" 29 | 30 | #define BUFFER_HEAD(x) (x)->head 31 | #define BUFFER_TAIL(x) (x)->tail 32 | 33 | struct bufline_s { 34 | unsigned char *string; /* the actual string of data */ 35 | struct bufline_s *next; /* pointer to next in linked list */ 36 | size_t length; /* length of the string of data */ 37 | size_t pos; /* start sending from this offset */ 38 | }; 39 | 40 | /* 41 | * The buffer structure points to the beginning and end of the buffer list 42 | * (and includes the total size) 43 | */ 44 | struct buffer_s { 45 | struct bufline_s *head; /* top of the buffer */ 46 | struct bufline_s *tail; /* bottom of the buffer */ 47 | size_t size; /* total size of the buffer */ 48 | }; 49 | 50 | /* 51 | * Take a string of data and a length and make a new line which can be added 52 | * to the buffer. The data IS copied, so make sure if you allocated your 53 | * data buffer on the heap, delete it because you now have TWO copies. 54 | */ 55 | static struct bufline_s * 56 | makenewline(unsigned char *data, size_t length) 57 | { 58 | struct bufline_s *newline; 59 | 60 | assert(data != NULL); 61 | assert(length > 0); 62 | 63 | if (!(newline = safemalloc(sizeof(struct bufline_s)))) 64 | return NULL; 65 | 66 | if (!(newline->string = safemalloc(length))) { 67 | safefree(newline); 68 | return NULL; 69 | } 70 | 71 | memcpy(newline->string, data, length); 72 | 73 | newline->next = NULL; 74 | newline->length = length; 75 | 76 | /* Position our "read" pointer at the beginning of the data */ 77 | newline->pos = 0; 78 | 79 | return newline; 80 | } 81 | 82 | /* 83 | * Free the allocated buffer line 84 | */ 85 | static void 86 | free_line(struct bufline_s *line) 87 | { 88 | assert(line != NULL); 89 | 90 | if (!line) 91 | return; 92 | 93 | if (line->string) 94 | safefree(line->string); 95 | 96 | safefree(line); 97 | } 98 | 99 | /* 100 | * Create a new buffer 101 | */ 102 | struct buffer_s * 103 | new_buffer(void) 104 | { 105 | struct buffer_s *buffptr; 106 | 107 | if (!(buffptr = safemalloc(sizeof(struct buffer_s)))) 108 | return NULL; 109 | 110 | /* 111 | * Since the buffer is initially empty, set the HEAD and TAIL 112 | * pointers to NULL since they can't possibly point anywhere at the 113 | * moment. 114 | */ 115 | BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = NULL; 116 | buffptr->size = 0; 117 | 118 | return buffptr; 119 | } 120 | 121 | /* 122 | * Delete all the lines in the buffer and the buffer itself 123 | */ 124 | void 125 | delete_buffer(struct buffer_s *buffptr) 126 | { 127 | struct bufline_s *next; 128 | 129 | assert(buffptr != NULL); 130 | 131 | while (BUFFER_HEAD(buffptr)) { 132 | next = BUFFER_HEAD(buffptr)->next; 133 | free_line(BUFFER_HEAD(buffptr)); 134 | BUFFER_HEAD(buffptr) = next; 135 | } 136 | 137 | safefree(buffptr); 138 | } 139 | 140 | /* 141 | * Return the current size of the buffer. 142 | */ 143 | size_t buffer_size(struct buffer_s *buffptr) 144 | { 145 | return buffptr->size; 146 | } 147 | 148 | /* 149 | * Push a new line on to the end of the buffer. 150 | */ 151 | int 152 | add_to_buffer(struct buffer_s *buffptr, unsigned char *data, size_t length) 153 | { 154 | struct bufline_s *newline; 155 | 156 | assert(buffptr != NULL); 157 | assert(data != NULL); 158 | assert(length > 0); 159 | 160 | /* 161 | * Sanity check here. A buffer with a non-NULL head pointer must 162 | * have a size greater than zero, and vice-versa. 163 | */ 164 | if (BUFFER_HEAD(buffptr) == NULL) 165 | assert(buffptr->size == 0); 166 | else 167 | assert(buffptr->size > 0); 168 | 169 | /* 170 | * Make a new line so we can add it to the buffer. 171 | */ 172 | if (!(newline = makenewline(data, length))) 173 | return -1; 174 | 175 | if (buffptr->size == 0) 176 | BUFFER_HEAD(buffptr) = BUFFER_TAIL(buffptr) = newline; 177 | else { 178 | BUFFER_TAIL(buffptr)->next = newline; 179 | BUFFER_TAIL(buffptr) = newline; 180 | } 181 | 182 | buffptr->size += length; 183 | 184 | return 0; 185 | } 186 | 187 | /* 188 | * Remove the first line from the top of the buffer 189 | */ 190 | static struct bufline_s * 191 | remove_from_buffer(struct buffer_s *buffptr) 192 | { 193 | struct bufline_s *line; 194 | 195 | assert(buffptr != NULL); 196 | assert(BUFFER_HEAD(buffptr) != NULL); 197 | 198 | line = BUFFER_HEAD(buffptr); 199 | BUFFER_HEAD(buffptr) = line->next; 200 | 201 | buffptr->size -= line->length; 202 | 203 | return line; 204 | } 205 | 206 | /* 207 | * Reads the bytes from the socket, and adds them to the buffer. 208 | * Takes a connection and returns the number of bytes read. 209 | */ 210 | #define READ_BUFFER_SIZE (1024 * 2) 211 | ssize_t 212 | read_buffer(int fd, struct buffer_s * buffptr) 213 | { 214 | ssize_t bytesin; 215 | unsigned char buffer[READ_BUFFER_SIZE]; 216 | 217 | assert(fd >= 0); 218 | assert(buffptr != NULL); 219 | 220 | /* 221 | * Don't allow the buffer to grow larger than MAXBUFFSIZE 222 | */ 223 | if (buffptr->size >= MAXBUFFSIZE) 224 | return 0; 225 | 226 | bytesin = read(fd, buffer, READ_BUFFER_SIZE); 227 | 228 | if (bytesin > 0) { 229 | if (add_to_buffer(buffptr, buffer, bytesin) < 0) { 230 | log_message(LOG_ERR, 231 | "readbuff: add_to_buffer() error."); 232 | return -1; 233 | } 234 | 235 | return bytesin; 236 | } else { 237 | if (bytesin == 0) { 238 | /* connection was closed by client */ 239 | return -1; 240 | } else { 241 | switch (errno) { 242 | #ifdef EWOULDBLOCK 243 | case EWOULDBLOCK: 244 | #else 245 | # ifdef EAGAIN 246 | case EAGAIN: 247 | # endif 248 | #endif 249 | case EINTR: 250 | return 0; 251 | default: 252 | log_message(LOG_ERR, 253 | "readbuff: recv() error \"%s\" on file descriptor %d", 254 | strerror(errno), fd); 255 | return -1; 256 | } 257 | } 258 | } 259 | } 260 | 261 | /* 262 | * Write the bytes in the buffer to the socket. 263 | * Takes a connection and returns the number of bytes written. 264 | */ 265 | ssize_t 266 | write_buffer(int fd, struct buffer_s * buffptr) 267 | { 268 | ssize_t bytessent; 269 | struct bufline_s *line; 270 | 271 | assert(fd >= 0); 272 | assert(buffptr != NULL); 273 | 274 | if (buffptr->size == 0) 275 | return 0; 276 | 277 | /* Sanity check. It would be bad to be using a NULL pointer! */ 278 | assert(BUFFER_HEAD(buffptr) != NULL); 279 | line = BUFFER_HEAD(buffptr); 280 | 281 | bytessent = 282 | send(fd, line->string + line->pos, line->length - line->pos, MSG_NOSIGNAL); 283 | 284 | if (bytessent >= 0) { 285 | /* bytes sent, adjust buffer */ 286 | line->pos += bytessent; 287 | if (line->pos == line->length) 288 | free_line(remove_from_buffer(buffptr)); 289 | return bytessent; 290 | } else { 291 | switch (errno) { 292 | #ifdef EWOULDBLOCK 293 | case EWOULDBLOCK: 294 | #else 295 | # ifdef EAGAIN 296 | case EAGAIN: 297 | # endif 298 | #endif 299 | case EINTR: 300 | return 0; 301 | case ENOBUFS: 302 | case ENOMEM: 303 | log_message(LOG_ERR, 304 | "writebuff: write() error [NOBUFS/NOMEM] \"%s\" on file descriptor %d", 305 | strerror(errno), fd); 306 | return 0; 307 | default: 308 | log_message(LOG_ERR, 309 | "writebuff: write() error \"%s\" on file descriptor %d", 310 | strerror(errno), fd); 311 | return -1; 312 | } 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /src/buffer.h: -------------------------------------------------------------------------------- 1 | /* $Id: buffer.h,v 1.8 2002/05/14 00:43:38 rjkaes Exp $ 2 | * 3 | * See 'buffer.c' for a detailed description. 4 | * 5 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef _TINYPROXY_BUFFER_H_ 19 | #define _TINYPROXY_BUFFER_H_ 20 | 21 | /* Forward declaration */ 22 | struct buffer_s; 23 | 24 | extern struct buffer_s *new_buffer(void); 25 | extern void delete_buffer(struct buffer_s *buffptr); 26 | extern size_t buffer_size(struct buffer_s *buffptr); 27 | 28 | /* 29 | * Add a new line to the given buffer. The data IS copied into the structure. 30 | */ 31 | extern int add_to_buffer(struct buffer_s *buffptr, unsigned char *data, 32 | size_t length); 33 | 34 | extern ssize_t read_buffer(int fd, struct buffer_s *buffptr); 35 | extern ssize_t write_buffer(int fd, struct buffer_s *buffptr); 36 | 37 | #endif /* __BUFFER_H_ */ 38 | -------------------------------------------------------------------------------- /src/child.h: -------------------------------------------------------------------------------- 1 | /* $Id: child.h,v 1.1.2.1 2004/06/14 20:49:57 rjkaes Exp $ 2 | * 3 | * See 'child.c' for more information. 4 | * 5 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_CHILD_H 19 | #define TINYPROXY_CHILD_H 20 | 21 | typedef enum { 22 | CHILD_MAXCLIENTS, 23 | CHILD_MAXSPARESERVERS, 24 | CHILD_MINSPARESERVERS, 25 | CHILD_STARTSERVERS, 26 | CHILD_MAXREQUESTSPERCHILD 27 | } child_config_t; 28 | 29 | extern short int child_pool_create(void); 30 | extern int child_listening_sock(uint16_t port); 31 | extern void child_close_sock(void); 32 | extern void child_main_loop(void); 33 | extern void child_kill_children(void); 34 | 35 | extern short int child_configure(child_config_t type, int val); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* $Id: common.h,v 1.6 2003/06/25 18:20:22 rjkaes Exp $ 2 | * 3 | * This file groups all the headers required throughout the tinyproxy 4 | * system. All this information use to be in the "tinyproxy.h" header, 5 | * but various other "libraries" in the program need the same information, 6 | * without the tinyproxy specific defines. 7 | * 8 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 9 | * 10 | * This program is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2, or (at your option) any 13 | * later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | */ 20 | 21 | #ifndef COMMON_HEADER_H 22 | #define COMMON_HEADER_H 23 | 24 | #ifdef HAVE_CONFIG_H 25 | # include 26 | #endif 27 | 28 | /* 29 | * Include standard headers which are used through-out tinyproxy 30 | */ 31 | #ifdef HAVE_SYS_TYPES_H 32 | # include 33 | #endif 34 | #ifdef HAVE_INTTYPES_H 35 | # include 36 | #endif 37 | #ifdef HAVE_STDDEF_H 38 | # include 39 | #endif 40 | #ifdef HAVE_STDINT_H 41 | # include 42 | #endif 43 | 44 | #ifdef HAVE_SYS_IOCTL_H 45 | # include 46 | #endif 47 | #ifdef HAVE_SYS_SELECT_H 48 | # include 49 | #endif 50 | #ifdef HAVE_SYS_SOCKET_H 51 | # include 52 | #endif 53 | #ifdef HAVE_SYS_STAT_H 54 | # include 55 | #endif 56 | 57 | #ifdef TIME_WITH_SYS_TIME 58 | # include 59 | # include 60 | #else 61 | # ifdef HAVE_SYS_TIME_H 62 | # include 63 | # else 64 | # include 65 | # endif 66 | #endif 67 | 68 | #ifdef HAVE_SYS_RESOURCE_H 69 | # include 70 | #endif 71 | #ifdef HAVE_SYS_UIO_H 72 | # include 73 | #endif 74 | #ifdef HAVE_SYS_UN_H 75 | # include 76 | #endif 77 | #ifdef HAVE_SYS_WAIT_H 78 | # include 79 | #endif 80 | 81 | #ifdef HAVE_NETINET_IN_H 82 | # include 83 | #endif 84 | #ifdef HAVE_ARPA_INET_H 85 | # include 86 | #endif 87 | #ifdef HAVE_ALLOCA_H 88 | # include 89 | #endif 90 | #ifdef HAVE_ASSERT_H 91 | # include 92 | #endif 93 | #ifdef HAVE_CTYPE_H 94 | # include 95 | #endif 96 | #ifdef HAVE_ERRNO_H 97 | # include 98 | #endif 99 | #ifdef HAVE_FCNTL_H 100 | # include 101 | #endif 102 | #ifdef HAVE_GRP_H 103 | # include 104 | #endif 105 | #ifdef HAVE_MEMORY_H 106 | # include 107 | #endif 108 | #ifdef HAVE_NETDB_H 109 | # include 110 | #endif 111 | #ifdef HAVE_PWD_H 112 | # include 113 | #endif 114 | #ifdef HAVE_SIGNAL_H 115 | # include 116 | #endif 117 | #ifdef HAVE_STDARG_H 118 | # include 119 | #endif 120 | #ifdef HAVE_STDIO_H 121 | # include 122 | #endif 123 | #ifdef HAVE_STDLIB_H 124 | # include 125 | #else 126 | # ifdef HAVE_MALLOC_H 127 | # include 128 | # endif 129 | #endif 130 | #ifdef HAVE_STRING_H 131 | # include 132 | #endif 133 | #ifdef HAVE_STRINGS_H 134 | # include 135 | #endif 136 | #ifdef HAVE_SYSEXITS_H 137 | # include 138 | #endif 139 | #ifdef HAVE_SYSLOG_H 140 | # include 141 | #endif 142 | #ifdef HAVE_UNISTD_H 143 | # include 144 | #endif 145 | #ifdef HAVE_VFORK_H 146 | # include 147 | #endif 148 | #ifdef HAVE_WCHAR_H 149 | # include 150 | #endif 151 | #ifdef HAVE_WCTYPE_H 152 | # include 153 | #endif 154 | #ifdef HAVE_SYS_MMAN_H 155 | # include 156 | #endif 157 | 158 | /* 159 | * If MSG_NOSIGNAL is not defined, define it to be zero so that it doesn't 160 | * cause any problems. 161 | */ 162 | #ifndef MSG_NOSIGNAL 163 | # define MSG_NOSIGNAL (0) 164 | #endif 165 | 166 | #ifndef SHUT_RD /* these three Posix.1g names are quite new */ 167 | # define SHUT_RD 0 /* shutdown for reading */ 168 | # define SHUT_WR 1 /* shutdown for writing */ 169 | # define SHUT_RDWR 2 /* shutdown for reading and writing */ 170 | #endif 171 | 172 | #define MAXLISTEN 1024 /* Max number of connections */ 173 | 174 | /* 175 | * SunOS doesn't have INADDR_NONE defined. 176 | */ 177 | #ifndef INADDR_NONE 178 | # define INADDR_NONE -1 179 | #endif 180 | 181 | /* Define boolean values */ 182 | #ifndef FALSE 183 | # define FALSE 0 184 | # define TRUE (!FALSE) 185 | #endif 186 | 187 | /* Useful function macros */ 188 | #if !defined(min) || !defined(max) 189 | # define min(a,b) ((a) < (b) ? (a) : (b)) 190 | # define max(a,b) ((a) > (b) ? (a) : (b)) 191 | #endif 192 | 193 | #endif 194 | -------------------------------------------------------------------------------- /src/conns.c: -------------------------------------------------------------------------------- 1 | /* $Id: conns.c,v 1.17.2.1 2004/08/06 16:56:55 rjkaes Exp $ 2 | * 3 | * Create and free the connection structure. One day there could be 4 | * other connection related tasks put here, but for now the header 5 | * file and this file are only used for create/free functions and the 6 | * connection structure definition. 7 | * 8 | * Copyright (C) 2001 Robert James Kaes (rjkaes@flarenet.com) 9 | * 10 | * This program is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2, or (at your option) any 13 | * later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | */ 20 | 21 | #include "tinyproxy.h" 22 | 23 | #include "buffer.h" 24 | #include "conns.h" 25 | #include "heap.h" 26 | #include "log.h" 27 | #include "stats.h" 28 | 29 | struct conn_s * 30 | initialize_conn(int client_fd, const char* ipaddr, const char* string_addr) 31 | { 32 | struct conn_s *connptr; 33 | struct buffer_s *cbuffer, *sbuffer; 34 | 35 | assert(client_fd >= 0); 36 | 37 | /* 38 | * Allocate the memory for all the internal components 39 | */ 40 | cbuffer = new_buffer(); 41 | sbuffer = new_buffer(); 42 | 43 | if (!cbuffer || !sbuffer) 44 | goto error_exit; 45 | 46 | /* 47 | * Allocate the space for the conn_s structure itself. 48 | */ 49 | connptr = safemalloc(sizeof(struct conn_s)); 50 | if (!connptr) 51 | goto error_exit; 52 | 53 | connptr->client_fd = client_fd; 54 | connptr->server_fd = -1; 55 | 56 | connptr->cbuffer = cbuffer; 57 | connptr->sbuffer = sbuffer; 58 | 59 | connptr->request_line = NULL; 60 | 61 | /* These store any error strings */ 62 | connptr->error_variables = NULL; 63 | connptr->error_variable_count = 0; 64 | connptr->error_string = NULL; 65 | connptr->error_number = -1; 66 | 67 | connptr->connect_method = FALSE; 68 | connptr->show_stats = FALSE; 69 | 70 | connptr->protocol.major = connptr->protocol.minor = 0; 71 | 72 | /* There is _no_ content length initially */ 73 | connptr->content_length.server = connptr->content_length.client = -1; 74 | 75 | connptr->client_ip_addr = safestrdup(ipaddr); 76 | connptr->client_string_addr = safestrdup(string_addr); 77 | 78 | connptr->upstream_proxy = NULL; 79 | 80 | update_stats(STAT_OPEN); 81 | 82 | return connptr; 83 | 84 | error_exit: 85 | /* 86 | * If we got here, there was a problem allocating memory 87 | */ 88 | if (cbuffer) 89 | delete_buffer(cbuffer); 90 | if (sbuffer) 91 | delete_buffer(sbuffer); 92 | 93 | return NULL; 94 | } 95 | 96 | void 97 | destroy_conn(struct conn_s *connptr) 98 | { 99 | assert(connptr != NULL); 100 | 101 | if (connptr->client_fd != -1) 102 | if (close(connptr->client_fd) < 0) 103 | log_message(LOG_INFO, "Client (%d) close message: %s", 104 | connptr->client_fd, strerror(errno)); 105 | if (connptr->server_fd != -1) 106 | if (close(connptr->server_fd) < 0) 107 | log_message(LOG_INFO, "Server (%d) close message: %s", 108 | connptr->server_fd, strerror(errno)); 109 | 110 | if (connptr->cbuffer) 111 | delete_buffer(connptr->cbuffer); 112 | if (connptr->sbuffer) 113 | delete_buffer(connptr->sbuffer); 114 | 115 | if (connptr->request_line) 116 | safefree(connptr->request_line); 117 | 118 | if (connptr->error_variables) { 119 | int i; 120 | 121 | for (i = 0; i != connptr->error_variable_count; ++i) { 122 | safefree(connptr->error_variables[i]->error_key); 123 | safefree(connptr->error_variables[i]->error_val); 124 | safefree(connptr->error_variables[i]); 125 | } 126 | 127 | safefree(connptr->error_variables); 128 | } 129 | 130 | if (connptr->error_string) 131 | safefree(connptr->error_string); 132 | 133 | if (connptr->client_ip_addr) 134 | safefree(connptr->client_ip_addr); 135 | if (connptr->client_string_addr) 136 | safefree(connptr->client_string_addr); 137 | 138 | safefree(connptr); 139 | 140 | update_stats(STAT_CLOSE); 141 | } 142 | -------------------------------------------------------------------------------- /src/conns.h: -------------------------------------------------------------------------------- 1 | /* $Id: conns.h,v 1.14.2.1 2004/08/06 16:56:55 rjkaes Exp $ 2 | * 3 | * See 'conns.c' for a detailed description. 4 | * 5 | * Copyright (C) 2001 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_CONNS_H 19 | #define TINYPROXY_CONNS_H 20 | 21 | #include "tinyproxy.h" 22 | 23 | /* 24 | * Connection Definition 25 | */ 26 | struct conn_s { 27 | int client_fd; 28 | int server_fd; 29 | 30 | struct buffer_s *cbuffer; 31 | struct buffer_s *sbuffer; 32 | 33 | /* The request line (first line) from the client */ 34 | char *request_line; 35 | 36 | /* Booleans */ 37 | unsigned int connect_method; 38 | unsigned int show_stats; 39 | 40 | /* 41 | * Store the error response if there is one. 42 | * This structure stores key -> value mappings for substitution 43 | * in the error HTML files. 44 | */ 45 | struct error_variable_s { 46 | char *error_key; 47 | char *error_val; 48 | } **error_variables; 49 | int error_variable_count; 50 | 51 | int error_number; 52 | char *error_string; 53 | 54 | /* A Content-Length value from the remote server */ 55 | struct { 56 | long int server; 57 | long int client; 58 | } content_length; 59 | 60 | /* 61 | * Store the client's IP and hostname information 62 | */ 63 | char* client_ip_addr; 64 | char* client_string_addr; 65 | 66 | /* 67 | * Store the incoming request's HTTP protocol. 68 | */ 69 | struct { 70 | unsigned int major; 71 | unsigned int minor; 72 | } protocol; 73 | /* 74 | * Pointer to upstream proxy. 75 | */ 76 | struct upstream *upstream_proxy; 77 | }; 78 | 79 | /* 80 | * Functions for the creation and destruction of a connection structure. 81 | */ 82 | extern struct conn_s* initialize_conn(int client_fd, const char* ipaddr, 83 | const char* string_addr); 84 | extern void destroy_conn(struct conn_s *connptr); 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /src/daemon.c: -------------------------------------------------------------------------------- 1 | /* $Id: daemon.c,v 1.2.2.1 2004/08/10 03:38:13 rjkaes Exp $ 2 | * 3 | * This file contains functions which are useful when writing a 4 | * daemon process. The functions include a "makedaemon" function and 5 | * a function to portably set a signal handler. 6 | * 7 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published by the 11 | * Free Software Foundation; either version 2, or (at your option) any 12 | * later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | */ 19 | 20 | #include "tinyproxy.h" 21 | 22 | #include "daemon.h" 23 | 24 | /* 25 | * Fork a child process and then kill the parent so make the calling 26 | * program a daemon process. 27 | */ 28 | void 29 | makedaemon(void) 30 | { 31 | if (fork() != 0) 32 | exit(0); 33 | 34 | setsid(); 35 | set_signal_handler(SIGHUP, SIG_IGN); 36 | 37 | if (fork() != 0) 38 | exit(0); 39 | 40 | chdir("/"); 41 | umask(077); 42 | 43 | #if NDEBUG 44 | /* 45 | * When not in debugging mode, close the standard file 46 | * descriptors. 47 | */ 48 | close(0); 49 | close(1); 50 | close(2); 51 | #endif 52 | } 53 | 54 | /* 55 | * Pass a signal number and a signal handling function into this function 56 | * to handle signals sent to the process. 57 | */ 58 | signal_func * 59 | set_signal_handler(int signo, signal_func *func) 60 | { 61 | struct sigaction act, oact; 62 | 63 | act.sa_handler = func; 64 | sigemptyset(&act.sa_mask); 65 | act.sa_flags = 0; 66 | if (signo == SIGALRM) { 67 | #ifdef SA_INTERRUPT 68 | act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ 69 | #endif 70 | } else { 71 | #ifdef SA_RESTART 72 | act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */ 73 | #endif 74 | } 75 | 76 | if (sigaction(signo, &act, &oact) < 0) 77 | return SIG_ERR; 78 | 79 | return oact.sa_handler; 80 | } 81 | -------------------------------------------------------------------------------- /src/daemon.h: -------------------------------------------------------------------------------- 1 | /* $Id: daemon.h,v 1.1 2002/05/23 04:39:32 rjkaes Exp $ 2 | * 3 | * See 'daemon.c' for a detailed description. 4 | * 5 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_DAEMON_H 19 | #define TINYPROXY_DAEMON_H 20 | 21 | typedef void signal_func(int); 22 | 23 | /* 24 | * Pass a singal integer and a function to handle the signal. 25 | */ 26 | extern signal_func *set_signal_handler(int signo, signal_func *func); 27 | 28 | /* 29 | * Make a program a daemon process 30 | */ 31 | extern void makedaemon(void); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/filter.c: -------------------------------------------------------------------------------- 1 | /* $Id: filter.c,v 1.16.2.1 2003/10/16 21:19:09 rjkaes Exp $ 2 | * 3 | * Copyright (c) 1999 George Talusan (gstalusan@uwaterloo.ca) 4 | * Copyright (c) 2002 James E. Flemer (jflemer@acm.jhu.edu) 5 | * Copyright (c) 2002 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * A substring of the domain to be filtered goes into the file 8 | * pointed at by DEFAULT_FILTER. 9 | * 10 | * This program is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2, or (at your option) any 13 | * later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | */ 20 | 21 | #include "tinyproxy.h" 22 | 23 | #include "filter.h" 24 | #include "heap.h" 25 | #include "log.h" 26 | #include "regexp.h" 27 | #include "reqs.h" 28 | 29 | #define FILTER_BUFFER_LEN (512) 30 | 31 | static int err; 32 | 33 | struct filter_list { 34 | struct filter_list *next; 35 | char *pat; 36 | regex_t *cpat; 37 | }; 38 | 39 | static struct filter_list *fl = NULL; 40 | static int already_init = 0; 41 | static filter_policy_t default_policy = FILTER_DEFAULT_ALLOW; 42 | 43 | /* 44 | * Initializes a linked list of strings containing hosts/urls to be filtered 45 | */ 46 | void 47 | filter_init(void) 48 | { 49 | FILE *fd; 50 | struct filter_list *p; 51 | char buf[FILTER_BUFFER_LEN]; 52 | char *s; 53 | int cflags; 54 | 55 | if (!fl && !already_init) { 56 | fd = fopen(config.filter, "r"); 57 | if (fd) { 58 | p = NULL; 59 | 60 | cflags = REG_NEWLINE | REG_NOSUB; 61 | if (config.filter_extended) 62 | cflags |= REG_EXTENDED; 63 | if (!config.filter_casesensitive) 64 | cflags |= REG_ICASE; 65 | 66 | while (fgets(buf, FILTER_BUFFER_LEN, fd)) { 67 | /* 68 | * Remove any trailing white space and 69 | * comments. 70 | */ 71 | s = buf; 72 | while (*s) { 73 | if (isspace((unsigned char)*s)) break; 74 | if (*s == '#') { 75 | /* 76 | * If the '#' char is preceeded by 77 | * an escape, it's not a comment 78 | * string. 79 | */ 80 | if (s == buf || *(s - 1) != '\\') 81 | break; 82 | } 83 | ++s; 84 | } 85 | *s = '\0'; 86 | 87 | /* skip leading whitespace */ 88 | s = buf; 89 | while (*s && isspace((unsigned char)*s)) 90 | s++; 91 | 92 | /* skip blank lines and comments */ 93 | if (*s == '\0') 94 | continue; 95 | 96 | if (!p) /* head of list */ 97 | fl = p = 98 | safecalloc(1, 99 | sizeof(struct 100 | filter_list)); 101 | else { /* next entry */ 102 | p->next = 103 | safecalloc(1, 104 | sizeof(struct 105 | filter_list)); 106 | p = p->next; 107 | } 108 | 109 | p->pat = safestrdup(s); 110 | p->cpat = safemalloc(sizeof(regex_t)); 111 | if ((err = regcomp(p->cpat, p->pat, cflags)) != 0) { 112 | fprintf(stderr, "Bad regex in %s: %s\n", 113 | config.filter, p->pat); 114 | exit(EX_DATAERR); 115 | } 116 | } 117 | if (ferror(fd)) { 118 | perror("fgets"); 119 | exit(EX_DATAERR); 120 | } 121 | fclose(fd); 122 | 123 | already_init = 1; 124 | } 125 | } 126 | } 127 | 128 | /* unlink the list */ 129 | void 130 | filter_destroy(void) 131 | { 132 | struct filter_list *p, *q; 133 | 134 | if (already_init) { 135 | for (p = q = fl; p; p = q) { 136 | regfree(p->cpat); 137 | safefree(p->cpat); 138 | safefree(p->pat); 139 | q = p->next; 140 | safefree(p); 141 | } 142 | fl = NULL; 143 | already_init = 0; 144 | } 145 | } 146 | 147 | /* Return 0 to allow, non-zero to block */ 148 | int 149 | filter_domain(const char *host) 150 | { 151 | struct filter_list *p; 152 | int result; 153 | 154 | if (!fl || !already_init) 155 | goto COMMON_EXIT; 156 | 157 | for (p = fl; p; p = p->next) { 158 | result = regexec(p->cpat, host, (size_t) 0, (regmatch_t *) 0, 0); 159 | 160 | if (result == 0) { 161 | if (default_policy == FILTER_DEFAULT_ALLOW) 162 | return 1; 163 | else 164 | return 0; 165 | } 166 | } 167 | 168 | COMMON_EXIT: 169 | if (default_policy == FILTER_DEFAULT_ALLOW) 170 | return 0; 171 | else 172 | return 1; 173 | } 174 | 175 | /* returns 0 to allow, non-zero to block */ 176 | int 177 | filter_url(const char *url) 178 | { 179 | struct filter_list *p; 180 | int result; 181 | 182 | if (!fl || !already_init) 183 | goto COMMON_EXIT; 184 | 185 | for (p = fl; p; p = p->next) { 186 | result = regexec(p->cpat, url, (size_t) 0, (regmatch_t *) 0, 0); 187 | 188 | if (result == 0) { 189 | if (default_policy == FILTER_DEFAULT_ALLOW) 190 | return 1; 191 | else 192 | return 0; 193 | } 194 | } 195 | 196 | COMMON_EXIT: 197 | if (default_policy == FILTER_DEFAULT_ALLOW) 198 | return 0; 199 | else 200 | return 1; 201 | } 202 | 203 | /* 204 | * Set the default filtering policy 205 | */ 206 | void 207 | filter_set_default_policy(filter_policy_t policy) 208 | { 209 | default_policy = policy; 210 | } 211 | -------------------------------------------------------------------------------- /src/filter.h: -------------------------------------------------------------------------------- 1 | /* $Id: filter.h,v 1.5 2002/06/07 18:36:21 rjkaes Exp $ 2 | * 3 | * See 'filter.c' for a detailed description. 4 | * 5 | * Copyright (c) 1999 George Talusan (gstalusan@uwaterloo.ca) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef _TINYPROXY_FILTER_H_ 19 | #define _TINYPROXY_FILTER_H_ 20 | 21 | typedef enum { 22 | FILTER_DEFAULT_ALLOW, 23 | FILTER_DEFAULT_DENY, 24 | } filter_policy_t; 25 | 26 | extern void filter_init(void); 27 | extern void filter_destroy(void); 28 | extern int filter_domain(const char *host); 29 | extern int filter_url(const char *url); 30 | 31 | extern void filter_set_default_policy(filter_policy_t policy); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/grammar.h: -------------------------------------------------------------------------------- 1 | 2 | /* A Bison parser, made by GNU Bison 2.4.1. */ 3 | 4 | /* Skeleton interface for Bison's Yacc-like parsers in C 5 | 6 | Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 7 | Free Software Foundation, Inc. 8 | 9 | This program is free software: you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation, either version 3 of the License, or 12 | (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program. If not, see . */ 21 | 22 | /* As a special exception, you may create a larger work that contains 23 | part or all of the Bison parser skeleton and distribute that work 24 | under terms of your choice, so long as that work isn't itself a 25 | parser generator using the skeleton or a modified version thereof 26 | as a parser skeleton. Alternatively, if you modify or redistribute 27 | the parser skeleton itself, you may (at your option) remove this 28 | special exception, which will cause the skeleton and the resulting 29 | Bison output files to be licensed under the GNU General Public 30 | License without this special exception. 31 | 32 | This special exception was added by the Free Software Foundation in 33 | version 2.2 of Bison. */ 34 | 35 | 36 | /* Tokens. */ 37 | #ifndef YYTOKENTYPE 38 | # define YYTOKENTYPE 39 | /* Put the tokens into the symbol table, so that GDB and other debuggers 40 | know about them. */ 41 | enum yytokentype { 42 | KW_PORT = 258, 43 | KW_LISTEN = 259, 44 | KW_LOGFILE = 260, 45 | KW_PIDFILE = 261, 46 | KW_SYSLOG = 262, 47 | KW_MAXCLIENTS = 263, 48 | KW_MAXSPARESERVERS = 264, 49 | KW_MINSPARESERVERS = 265, 50 | KW_STARTSERVERS = 266, 51 | KW_MAXREQUESTSPERCHILD = 267, 52 | KW_TIMEOUT = 268, 53 | KW_USER = 269, 54 | KW_GROUP = 270, 55 | KW_ANONYMOUS = 271, 56 | KW_XTINYPROXY = 272, 57 | KW_FILTER = 273, 58 | KW_FILTERURLS = 274, 59 | KW_FILTEREXTENDED = 275, 60 | KW_FILTER_DEFAULT_DENY = 276, 61 | KW_FILTER_CASESENSITIVE = 277, 62 | KW_UPSTREAM = 278, 63 | KW_CONNECTPORT = 279, 64 | KW_BIND = 280, 65 | KW_STATHOST = 281, 66 | KW_ALLOW = 282, 67 | KW_DENY = 283, 68 | KW_ERRORPAGE = 284, 69 | KW_DEFAULT_ERRORPAGE = 285, 70 | KW_STATPAGE = 286, 71 | KW_VIA_PROXY_NAME = 287, 72 | KW_PROXY_HTTP = 288, 73 | KW_PROXY_SOCKS4 = 289, 74 | KW_PROXY_SOCKS5 = 290, 75 | KW_YES = 291, 76 | KW_NO = 292, 77 | KW_LOGLEVEL = 293, 78 | KW_LOG_CRITICAL = 294, 79 | KW_LOG_ERROR = 295, 80 | KW_LOG_WARNING = 296, 81 | KW_LOG_NOTICE = 297, 82 | KW_LOG_CONNECT = 298, 83 | KW_LOG_INFO = 299, 84 | IDENTIFIER = 300, 85 | NUMBER = 301, 86 | STRING = 302, 87 | NUMERIC_ADDRESS = 303, 88 | NETMASK_ADDRESS = 304 89 | }; 90 | #endif 91 | /* Tokens. */ 92 | #define KW_PORT 258 93 | #define KW_LISTEN 259 94 | #define KW_LOGFILE 260 95 | #define KW_PIDFILE 261 96 | #define KW_SYSLOG 262 97 | #define KW_MAXCLIENTS 263 98 | #define KW_MAXSPARESERVERS 264 99 | #define KW_MINSPARESERVERS 265 100 | #define KW_STARTSERVERS 266 101 | #define KW_MAXREQUESTSPERCHILD 267 102 | #define KW_TIMEOUT 268 103 | #define KW_USER 269 104 | #define KW_GROUP 270 105 | #define KW_ANONYMOUS 271 106 | #define KW_XTINYPROXY 272 107 | #define KW_FILTER 273 108 | #define KW_FILTERURLS 274 109 | #define KW_FILTEREXTENDED 275 110 | #define KW_FILTER_DEFAULT_DENY 276 111 | #define KW_FILTER_CASESENSITIVE 277 112 | #define KW_UPSTREAM 278 113 | #define KW_CONNECTPORT 279 114 | #define KW_BIND 280 115 | #define KW_STATHOST 281 116 | #define KW_ALLOW 282 117 | #define KW_DENY 283 118 | #define KW_ERRORPAGE 284 119 | #define KW_DEFAULT_ERRORPAGE 285 120 | #define KW_STATPAGE 286 121 | #define KW_VIA_PROXY_NAME 287 122 | #define KW_PROXY_HTTP 288 123 | #define KW_PROXY_SOCKS4 289 124 | #define KW_PROXY_SOCKS5 290 125 | #define KW_YES 291 126 | #define KW_NO 292 127 | #define KW_LOGLEVEL 293 128 | #define KW_LOG_CRITICAL 294 129 | #define KW_LOG_ERROR 295 130 | #define KW_LOG_WARNING 296 131 | #define KW_LOG_NOTICE 297 132 | #define KW_LOG_CONNECT 298 133 | #define KW_LOG_INFO 299 134 | #define IDENTIFIER 300 135 | #define NUMBER 301 136 | #define STRING 302 137 | #define NUMERIC_ADDRESS 303 138 | #define NETMASK_ADDRESS 304 139 | 140 | 141 | 142 | 143 | #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 144 | typedef union YYSTYPE 145 | { 146 | 147 | /* Line 1676 of yacc.c */ 148 | #line 37 "grammar.y" 149 | 150 | unsigned int num; 151 | char *cptr; 152 | 153 | 154 | 155 | /* Line 1676 of yacc.c */ 156 | #line 157 "y.tab.h" 157 | } YYSTYPE; 158 | # define YYSTYPE_IS_TRIVIAL 1 159 | # define yystype YYSTYPE /* obsolescent; will be withdrawn */ 160 | # define YYSTYPE_IS_DECLARED 1 161 | #endif 162 | 163 | extern YYSTYPE yylval; 164 | 165 | 166 | -------------------------------------------------------------------------------- /src/hashmap.h: -------------------------------------------------------------------------------- 1 | /* $Id: hashmap.h,v 1.2 2002/04/25 18:55:56 rjkaes Exp $ 2 | * 3 | * A hashmap implementation. The keys are case-insensitive NULL terminated 4 | * strings, and the data is arbitrary lumps of data. Copies of both the 5 | * key and the data in the hashmap itself, so you must free the original 6 | * key and data to avoid a memory leak. The hashmap returns a pointer 7 | * to the data when a key is searched for, so take care in modifying the 8 | * data as it's modifying the data stored in the hashmap. (In other words, 9 | * don't try to free the data, or realloc the memory. :) 10 | * 11 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 12 | * 13 | * This program is free software; you can redistribute it and/or modify 14 | * it under the terms of the GNU General Public License as published by 15 | * the Free Software Foundation; either version 2 of the License, or 16 | * (at your option) any later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | * GNU General Public License for more details. 22 | * 23 | * You should have received a copy of the GNU General Public License 24 | * along with this program; if not, write to the Free Software 25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 26 | */ 27 | 28 | #ifndef _HASHMAP_H 29 | #define _HASHMAP_H 30 | 31 | /* Allow the use in C++ code. */ 32 | #if defined(__cplusplus) 33 | extern "C" { 34 | #endif 35 | 36 | /* 37 | * We're using a typedef here to "hide" the implementation details of the 38 | * hash map. Sure, it's a pointer, but the struct is hidden in the C file. 39 | * So, just use the hashmap_t like it's a cookie. :) 40 | */ 41 | typedef struct hashmap_s* hashmap_t; 42 | typedef int hashmap_iter; 43 | 44 | /* 45 | * hashmap_create() takes one argument, which is the number of buckets to 46 | * use internally. hashmap_delete() is self explanatory. 47 | */ 48 | extern hashmap_t hashmap_create(unsigned int nbuckets); 49 | extern int hashmap_delete(hashmap_t map); 50 | 51 | /* 52 | * When the you insert a key/data pair into the hashmap it will the key 53 | * and data are duplicated, so you must free your copy if it was created 54 | * on the heap. The key must be a NULL terminated string. "data" must be 55 | * non-NULL and length must be greater than zero. 56 | * 57 | * Returns: negative on error 58 | * 0 upon successful insert 59 | */ 60 | extern int hashmap_insert(hashmap_t map, const char *key, 61 | const void *data, size_t len); 62 | 63 | /* 64 | * Get an iterator to the first entry. 65 | * 66 | * Returns: an negative value upon error. 67 | */ 68 | extern hashmap_iter hashmap_first(hashmap_t map); 69 | 70 | /* 71 | * Checks to see if the iterator is pointing at the "end" of the entries. 72 | * 73 | * Returns: 1 if it is the end 74 | * 0 otherwise 75 | */ 76 | extern int hashmap_is_end(hashmap_t map, hashmap_iter iter); 77 | 78 | /* 79 | * Return a "pointer" to the first instance of the particular key. It can 80 | * be tested against hashmap_is_end() to see if the key was not found. 81 | * 82 | * Returns: negative upon an error 83 | * an "iterator" pointing at the first key 84 | * an "end-iterator" if the key wasn't found 85 | */ 86 | extern hashmap_iter hashmap_find(hashmap_t map, const char* key); 87 | 88 | /* 89 | * Retrieve the key/data associated with a particular iterator. 90 | * NOTE: These are pointers to the actual data, so don't mess around with them 91 | * too much. 92 | * 93 | * Returns: the length of the data block upon success 94 | * negative upon error 95 | */ 96 | extern ssize_t hashmap_return_entry(hashmap_t map, hashmap_iter iter, 97 | char** key, void** data); 98 | 99 | /* 100 | * Get the first entry (assuming there is more than one) for a particular 101 | * key. The data MUST be non-NULL. 102 | * 103 | * Returns: negative upon error 104 | * zero if no entry is found 105 | * length of data for the entry 106 | */ 107 | extern ssize_t hashmap_entry_by_key(hashmap_t map, const char* key, void** data); 108 | 109 | /* 110 | * Searches for _any_ occurrances of "key" within the hashmap and returns the 111 | * number of matching entries. 112 | * 113 | * Returns: negative upon an error 114 | * zero if no key is found 115 | * count found (positive value) 116 | */ 117 | extern ssize_t hashmap_search(hashmap_t map, const char *key); 118 | 119 | /* 120 | * Go through the hashmap and remove the particular key. 121 | * NOTE: This will invalidate any iterators which have been created. 122 | * 123 | * Remove: negative upon error 124 | * 0 if the key was not found 125 | * positive count of entries deleted 126 | */ 127 | extern ssize_t hashmap_remove(hashmap_t map, const char *key); 128 | 129 | #if defined(__cplusplus) 130 | } 131 | #endif /* C++ */ 132 | 133 | #endif /* _HASHMAP_H */ 134 | -------------------------------------------------------------------------------- /src/heap.c: -------------------------------------------------------------------------------- 1 | /* $Id: heap.c,v 1.6.2.1 2003/08/06 20:44:09 rjkaes Exp $ 2 | * 3 | * Debugging versions of various heap related functions are combined 4 | * here. The debugging versions include assertions and also print 5 | * (to standard error) the function called along with the amount 6 | * of memory allocated, and where the memory is pointing. The 7 | * format of the log message is standardized. 8 | * 9 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 10 | * 11 | * This program is free software; you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License as published by the 13 | * Free Software Foundation; either version 2, or (at your option) any 14 | * later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, but 17 | * WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * General Public License for more details. 20 | */ 21 | 22 | #include "tinyproxy.h" 23 | #include "heap.h" 24 | #include "text.h" 25 | 26 | void * 27 | debugging_calloc(size_t nmemb, size_t size, const char *file, 28 | unsigned long line) 29 | { 30 | void *ptr; 31 | 32 | assert(nmemb > 0); 33 | assert(size > 0); 34 | 35 | ptr = calloc(nmemb, size); 36 | fprintf(stderr, "{calloc: %p:%u x %u} %s:%lu\n", ptr, nmemb, size, file, 37 | line); 38 | return ptr; 39 | } 40 | 41 | void * 42 | debugging_malloc(size_t size, const char *file, unsigned long line) 43 | { 44 | void *ptr; 45 | 46 | assert(size > 0); 47 | 48 | ptr = malloc(size); 49 | fprintf(stderr, "{malloc: %p:%u} %s:%lu\n", ptr, size, file, line); 50 | return ptr; 51 | } 52 | 53 | void * 54 | debugging_realloc(void *ptr, size_t size, const char *file, unsigned long line) 55 | { 56 | void *newptr; 57 | 58 | assert(size > 0); 59 | 60 | newptr = realloc(ptr, size); 61 | fprintf(stderr, "{realloc: %p -> %p:%u} %s:%lu\n", ptr, newptr, size, 62 | file, line); 63 | return newptr; 64 | } 65 | 66 | void 67 | debugging_free(void *ptr, const char *file, unsigned long line) 68 | { 69 | fprintf(stderr, "{free: %p} %s:%lu\n", ptr, file, line); 70 | 71 | if (ptr != NULL) 72 | free(ptr); 73 | return; 74 | } 75 | 76 | char* 77 | debugging_strdup(const char* s, const char* file, unsigned long line) 78 | { 79 | char* ptr; 80 | size_t len; 81 | 82 | assert(s != NULL); 83 | 84 | len = strlen(s) + 1; 85 | ptr = malloc(len); 86 | if (!ptr) 87 | return NULL; 88 | memcpy(ptr, s, len); 89 | 90 | fprintf(stderr, "{strdup: %p:%u} %s:%lu\n", ptr, len, file, line); 91 | return ptr; 92 | } 93 | 94 | /* 95 | * Allocate a block of memory in the "shared" memory region. 96 | * 97 | * FIXME: This uses the most basic (and slowest) means of creating a 98 | * shared memory location. It requires the use of a temporary file. We might 99 | * want to look into something like MM (Shared Memory Library) for a better 100 | * solution. 101 | */ 102 | void* 103 | malloc_shared_memory(size_t size) 104 | { 105 | int fd; 106 | void* ptr; 107 | char buffer[32]; 108 | 109 | static char* shared_file = "/tmp/tinyproxy.shared.XXXXXX"; 110 | 111 | assert(size > 0); 112 | 113 | strlcpy(buffer, shared_file, sizeof(buffer)); 114 | 115 | if ((fd = mkstemp(buffer)) == -1) 116 | return (void *)MAP_FAILED; 117 | unlink(buffer); 118 | 119 | if (ftruncate(fd, size) == -1) 120 | return (void *)MAP_FAILED; 121 | ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 122 | 123 | return ptr; 124 | } 125 | 126 | /* 127 | * Allocate a block of memory from the "shared" region an initialize it to 128 | * zero. 129 | */ 130 | void* 131 | calloc_shared_memory(size_t nmemb, size_t size) 132 | { 133 | void* ptr; 134 | long length; 135 | 136 | assert(nmemb > 0); 137 | assert(size > 0); 138 | 139 | length = nmemb * size; 140 | 141 | ptr = malloc_shared_memory(length); 142 | if (ptr == MAP_FAILED) 143 | return ptr; 144 | 145 | memset(ptr, 0, length); 146 | 147 | return ptr; 148 | } 149 | 150 | -------------------------------------------------------------------------------- /src/heap.h: -------------------------------------------------------------------------------- 1 | /* $Id: heap.h,v 1.3 2003/05/31 23:04:15 rjkaes Exp $ 2 | * 3 | * See 'heap.c' for a detailed description. 4 | * 5 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_HEAP_H 19 | #define TINYPROXY_HEAP_H 20 | 21 | /* 22 | * The following is to allow for better memory checking. 23 | */ 24 | #ifndef NDEBUG 25 | 26 | extern void *debugging_calloc(size_t nmemb, size_t size, const char *file, 27 | unsigned long line); 28 | extern void *debugging_malloc(size_t size, const char *file, 29 | unsigned long line); 30 | extern void debugging_free(void *ptr, const char *file, unsigned long line); 31 | extern void *debugging_realloc(void *ptr, size_t size, const char *file, 32 | unsigned long line); 33 | extern char *debugging_strdup(const char* s, const char* file, 34 | unsigned long line); 35 | 36 | # define safecalloc(x, y) debugging_calloc(x, y, __FILE__, __LINE__) 37 | # define safemalloc(x) debugging_malloc(x, __FILE__, __LINE__) 38 | # define saferealloc(x, y) debugging_realloc(x, y, __FILE__, __LINE__) 39 | # define safestrdup(x) debugging_strdup(x, __FILE__, __LINE__) 40 | # define safefree(x) do { \ 41 | void **__safefree_tmp = (void *)&(x); \ 42 | debugging_free(*__safefree_tmp, __FILE__, __LINE__); \ 43 | *__safefree_tmp = NULL; \ 44 | } while (0) 45 | #else 46 | # define safecalloc(x, y) calloc(x, y) 47 | # define safemalloc(x) malloc(x) 48 | # define saferealloc(x, y) realloc(x, y) 49 | # define safefree(x) do { \ 50 | void **__safefree_tmp = (void *)&(x); \ 51 | free(*__safefree_tmp); \ 52 | *__safefree_tmp = NULL; \ 53 | } while (0) 54 | # define safestrdup(x) strdup(x) 55 | #endif 56 | 57 | /* 58 | * Allocate memory from the "shared" region of memory. 59 | */ 60 | extern void* malloc_shared_memory(size_t size); 61 | extern void* calloc_shared_memory(size_t nmemb, size_t size); 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/htmlerror.h: -------------------------------------------------------------------------------- 1 | /* $Id: htmlerror.h,v 1.2 2003/03/14 22:45:59 rjkaes Exp $ 2 | * 3 | * Contains header declarations for the HTML error functions in 4 | * htmlerror.c 5 | * 6 | * Copyright (C) 2003 Steven Young 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #ifndef TINYPROXY_HTMLERROR_H 20 | #define TINYPROXY_HTMLERROR_H 21 | 22 | /* Forward declaration */ 23 | struct conn_s; 24 | 25 | extern int add_new_errorpage(char *filepath, unsigned int errornum); 26 | extern int send_http_error_message(struct conn_s *connptr); 27 | extern int indicate_http_error(struct conn_s *connptr, int number, char *message, ...); 28 | extern int add_error_variable(struct conn_s *connptr, char *key, char *val); 29 | extern int send_html_file(FILE *infile, struct conn_s *connptr); 30 | extern int send_http_headers(struct conn_s *connptr, int code, char *message); 31 | extern int add_standard_vars(struct conn_s *connptr); 32 | 33 | #endif /* !TINYPROXY_HTMLERROR_H */ 34 | -------------------------------------------------------------------------------- /src/http_message.c: -------------------------------------------------------------------------------- 1 | /* $Id: http_message.c,v 1.2 2003/05/31 23:02:21 rjkaes Exp $ 2 | * 3 | * See 'http_message.h' for a detailed description. 4 | * 5 | * Copyright (C) 2003 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #include "common.h" 19 | #include "heap.h" 20 | #include "http_message.h" 21 | #include "network.h" 22 | 23 | /* 24 | * Package up an HTTP message into a nice little structure. As you can 25 | * see this structure doesn't actually store any allocated strings; 26 | * therefore, the caller must free any memory referenced by this struct. 27 | * Also, the caller MUST NOT free the memory while the structure is 28 | * still in use---bad things would happen. 29 | */ 30 | struct http_message_s { 31 | /* Response string and code supplied on the HTTP status line */ 32 | struct { 33 | const char* string; 34 | int code; 35 | } response; 36 | 37 | /* 38 | * A group of headers to be sent with this message. Right now 39 | * the strings are referenced through pointers in an array. 40 | * I might change this to a vector in the future. 41 | */ 42 | struct { 43 | char** strings; 44 | unsigned int total; 45 | unsigned int used; 46 | } headers; 47 | 48 | /* Body of the message (most likely an HTML message) */ 49 | struct { 50 | const char* text; 51 | size_t length; 52 | } body; 53 | }; 54 | 55 | /* 56 | * Check if the HTTP message is validly formed. This is the one odd-ball 57 | * function. It returns 0 if the message is invalid; otherwise, a positive 58 | * number is returned. Useful for if() tests and assert() tests. 59 | */ 60 | static int 61 | is_http_message_valid(http_message_t msg) 62 | { 63 | if (msg == NULL) return 0; 64 | if (msg->headers.strings == NULL) return 0; 65 | if (msg->response.string == NULL) return 0; 66 | if (msg->response.code < 1 || msg->response.code > 999) return 0; 67 | 68 | return 1; 69 | } 70 | 71 | /* Initially allocate space for 128 headers */ 72 | #define NUMBER_OF_HEADERS 128 73 | 74 | /* 75 | * Allocate a new http_message structure on the heap. 76 | * If memory could not be allocated, return a NULL. 77 | */ 78 | http_message_t 79 | http_message_create(int response_code, const char* response_string) 80 | { 81 | http_message_t msg; 82 | int ret; 83 | 84 | msg = safecalloc(1, sizeof(struct http_message_s)); 85 | if (msg == NULL) 86 | return NULL; 87 | 88 | msg->headers.strings = safecalloc(NUMBER_OF_HEADERS, sizeof(char*)); 89 | if (msg->headers.strings == NULL) { 90 | safefree(msg); 91 | return NULL; 92 | } 93 | 94 | msg->headers.total = NUMBER_OF_HEADERS; 95 | 96 | /* Store the HTTP response information in the structure */ 97 | ret = http_message_set_response(msg, response_code, response_string); 98 | if (IS_HTTP_MSG_ERROR(ret)) { 99 | safefree(msg->headers.strings); 100 | safefree(msg); 101 | return NULL; 102 | } 103 | 104 | return msg; 105 | } 106 | 107 | /* 108 | * Free up the space associated with this HTTP message structure. 109 | * This DOES NOT free the pointers stored in this structure. That memory 110 | * is the responsibility of the caller. 111 | */ 112 | int 113 | http_message_destroy(http_message_t msg) 114 | { 115 | assert(msg != NULL); 116 | assert(msg->headers.strings != NULL); 117 | 118 | /* Check for valid arguments */ 119 | if (msg == NULL) return -EFAULT; 120 | 121 | if (msg->headers.strings != NULL) 122 | safefree(msg->headers.strings); 123 | safefree(msg); 124 | return 0; 125 | } 126 | 127 | /* 128 | * Set the HTTP response information for this structure. The response_string 129 | * must be a NUL ('\0') terminated C string. 130 | */ 131 | int 132 | http_message_set_response(http_message_t msg, 133 | int response_code, 134 | const char* response_string) 135 | { 136 | /* Check for valid arguments */ 137 | if (msg == NULL) return -EFAULT; 138 | if (response_code < 1 || response_code > 999) return -EINVAL; 139 | if (response_string == NULL) return -EINVAL; 140 | if (strlen(response_string) == 0) return -EINVAL; 141 | 142 | msg->response.code = response_code; 143 | msg->response.string = response_string; 144 | 145 | return 0; 146 | } 147 | 148 | /* 149 | * Set the HTTP message body. 150 | */ 151 | int 152 | http_message_set_body(http_message_t msg, const char* body, size_t len) 153 | { 154 | /* Check for valid arguments */ 155 | if (msg == NULL) return -EFAULT; 156 | if (body == NULL) return -EINVAL; 157 | if (len == 0) return -EINVAL; 158 | 159 | msg->body.text = body; 160 | msg->body.length = len; 161 | 162 | return 0; 163 | } 164 | 165 | /* 166 | * Add headers to the structure. 167 | */ 168 | int 169 | http_message_add_headers(http_message_t msg, char** headers, 170 | int num_headers) 171 | { 172 | char** new_headers; 173 | int i; 174 | 175 | /* Check for valid arguments */ 176 | if (msg == NULL) return -EFAULT; 177 | if (headers == NULL) return -EINVAL; 178 | if (num_headers < 1) return -EINVAL; 179 | 180 | /* 181 | * If the number of headers to add is greater than the space 182 | * available, reallocate the memory. 183 | */ 184 | if (msg->headers.used + num_headers > msg->headers.total) { 185 | new_headers = safecalloc(msg->headers.total * 2, 186 | sizeof(char*)); 187 | if (new_headers == NULL) 188 | return -ENOMEM; 189 | 190 | /* Copy the array */ 191 | for (i = 0; i != msg->headers.used; ++i) 192 | new_headers[i] = msg->headers.strings[i]; 193 | 194 | /* Remove the old array and replace it with the new array */ 195 | safefree(msg->headers.strings); 196 | msg->headers.strings = new_headers; 197 | msg->headers.total *= 2; 198 | } 199 | 200 | /* 201 | * Add the new headers to the structure 202 | */ 203 | for (i = 0; i != num_headers; ++i) 204 | msg->headers.strings[i + msg->headers.used] = headers[i]; 205 | msg->headers.used += num_headers; 206 | 207 | return 0; 208 | } 209 | 210 | /* 211 | * Send the completed HTTP message via the supplied file descriptor. 212 | */ 213 | int 214 | http_message_send(http_message_t msg, int fd) 215 | { 216 | char timebuf[30]; 217 | time_t global_time; 218 | int i; 219 | 220 | assert(is_http_message_valid(msg)); 221 | 222 | /* Check for valid arguments */ 223 | if (msg == NULL) return -EFAULT; 224 | if (fd < 1) return -EBADF; 225 | if (!is_http_message_valid(msg)) return -EINVAL; 226 | 227 | /* Write the response line */ 228 | write_message(fd, "HTTP/1.0 %d %s\r\n", 229 | msg->response.code, msg->response.string); 230 | 231 | /* Go through all the headers */ 232 | for (i = 0; i != msg->headers.used; ++i) 233 | write_message(fd, "%s\r\n", msg->headers.strings[i]); 234 | 235 | /* Output the date */ 236 | global_time = time(NULL); 237 | strftime(timebuf, sizeof(timebuf), "%a, %d %b %Y %H:%M:%S GMT", 238 | gmtime(&global_time)); 239 | write_message(fd, "Date: %s\r\n", timebuf); 240 | 241 | /* Output the content-length */ 242 | write_message(fd, "Content-length: %u\r\n", msg->body.length); 243 | 244 | /* Write the separator between the headers and body */ 245 | safe_write(fd, "\r\n", 2); 246 | 247 | /* If there's a body, send it! */ 248 | if (msg->body.length > 0) 249 | safe_write(fd, msg->body.text, msg->body.length); 250 | 251 | return 0; 252 | } 253 | -------------------------------------------------------------------------------- /src/http_message.h: -------------------------------------------------------------------------------- 1 | /* $Id: http_message.h,v 1.1 2003/03/13 05:25:30 rjkaes Exp $ 2 | * 3 | * HTTP Message API 4 | * ---------------- 5 | * The idea behind this application programming interface (API) is to 6 | * represent an HTTP response message as a concrete entity. The API 7 | * functions allow the message to be built up systematically before 8 | * transmission to a connected socket. 9 | * 10 | * The order of the functions in your program would look something like 11 | * this: 12 | * http_message_create() 13 | * http_message_set_response() 14 | * http_message_set_body() [optional if no body is required] 15 | * http_message_add_headers() [optional if no additional headers are used] 16 | * http_message_send() 17 | * http_message_destroy() 18 | * 19 | * NOTE: No user data is stored in the http_message_t type; therefore, 20 | * do not delete strings referenced by the http_message_t object 21 | * before you call http_message_destroy(). By not copying data, the 22 | * API functions are faster, but you must take greater care. 23 | * 24 | * (Side note: be _very_ careful when using stack allocated memory with 25 | * this API. Bad things will happen if you try to pass the 26 | * http_message_t out of the calling function since the stack 27 | * allocated memory referenced by the http_message_t will no long 28 | * exist.) 29 | * 30 | * Copyright (C) 2003 Robert James Kaes (rjkaes@flarenet.com) 31 | * 32 | * This program is free software; you can redistribute it and/or modify it 33 | * under the terms of the GNU General Public License as published by the 34 | * Free Software Foundation; either version 2, or (at your option) any 35 | * later version. 36 | * 37 | * This program is distributed in the hope that it will be useful, but 38 | * WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 40 | * General Public License for more details. 41 | */ 42 | 43 | #ifndef _TINYPROXY_HTTP_MESSAGE_H_ 44 | #define _TINYPROXY_HTTP_MESSAGE_H_ 45 | 46 | /* Use the "http_message_t" as a cookie or handle to the structure. */ 47 | typedef struct http_message_s *http_message_t; 48 | 49 | /* 50 | * Macro to test if an error occurred with the API. All the HTTP message 51 | * functions will return 0 if no error occurred, or a negative number if 52 | * there was a problem. 53 | */ 54 | #define IS_HTTP_MSG_ERROR(x) (x < 0) 55 | 56 | /* Initialize the internal structure of the HTTP message */ 57 | extern http_message_t http_message_create(int response_code, 58 | const char* response_string); 59 | 60 | /* Free up an _internal_ resources */ 61 | extern int http_message_destroy(http_message_t msg); 62 | 63 | /* 64 | * Send an HTTP message via the supplied file descriptor. This function 65 | * will add the "Date" header before it's sent. 66 | */ 67 | extern int http_message_send(http_message_t msg, int fd); 68 | 69 | /* 70 | * Change the internal state of the HTTP message. Either set the 71 | * body of the message, update the response information, or 72 | * add a new set of headers. 73 | */ 74 | extern int http_message_set_body(http_message_t msg, 75 | const char* body, size_t len); 76 | extern int http_message_set_response(http_message_t msg, 77 | int response_code, 78 | const char* response_string); 79 | 80 | /* 81 | * Set the headers for this HTTP message. Each string must be NUL ('\0') 82 | * terminated, but DO NOT include any carriage returns (CR) or 83 | * line-feeds (LF) since they will be included when the http_message is 84 | * sent. 85 | */ 86 | extern int http_message_add_headers(http_message_t msg, 87 | char** headers, 88 | int num_headers); 89 | 90 | #endif /* _TINYPROXY_HTTP_MESSAGE_H_ */ 91 | -------------------------------------------------------------------------------- /src/log.c: -------------------------------------------------------------------------------- 1 | /* $Id: log.c,v 1.26 2003/05/31 23:02:21 rjkaes Exp $ 2 | * 3 | * Logs the various messages which tinyproxy produces to either a log file or 4 | * the syslog daemon. Not much to it... 5 | * 6 | * Copyright (C) 1998 Steven Young 7 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published by the 11 | * Free Software Foundation; either version 2, or (at your option) any 12 | * later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | */ 19 | 20 | #include "tinyproxy.h" 21 | 22 | #include "heap.h" 23 | #include "log.h" 24 | #include "utils.h" 25 | #include "vector.h" 26 | 27 | static char *syslog_level[] = { 28 | NULL, 29 | NULL, 30 | "CRITICAL", 31 | "ERROR", 32 | "WARNING", 33 | "NOTICE", 34 | "INFO", 35 | "DEBUG", 36 | "CONNECT" 37 | }; 38 | 39 | #define TIME_LENGTH 16 40 | #define STRING_LENGTH 800 41 | 42 | /* 43 | * Global file descriptor for the log file 44 | */ 45 | int log_file_fd = -1; 46 | 47 | /* 48 | * Store the log level setting. 49 | */ 50 | static int log_level = LOG_INFO; 51 | 52 | /* 53 | * Hold a listing of log messages which need to be sent once the log 54 | * file has been established. 55 | * The key is the actual messages (already filled in full), and the value 56 | * is the log level. 57 | */ 58 | static vector_t log_message_storage; 59 | 60 | /* 61 | * Open the log file and store the file descriptor in a global location. 62 | */ 63 | int 64 | open_log_file(const char* log_file_name) 65 | { 66 | log_file_fd = create_file_safely(log_file_name, FALSE); 67 | return log_file_fd; 68 | } 69 | 70 | /* 71 | * Close the log file 72 | */ 73 | void 74 | close_log_file(void) 75 | { 76 | close(log_file_fd); 77 | } 78 | 79 | /* 80 | * Truncate log file to a zero length. 81 | */ 82 | void 83 | truncate_log_file(void) 84 | { 85 | lseek(log_file_fd, 0, SEEK_SET); 86 | ftruncate(log_file_fd, 0); 87 | } 88 | 89 | /* 90 | * Set the log level for writing to the log file. 91 | */ 92 | void 93 | set_log_level(int level) 94 | { 95 | log_level = level; 96 | } 97 | 98 | /* 99 | * This routine logs messages to either the log file or the syslog function. 100 | */ 101 | void 102 | log_message(int level, char *fmt, ...) 103 | { 104 | va_list args; 105 | time_t nowtime; 106 | 107 | char time_string[TIME_LENGTH]; 108 | char str[STRING_LENGTH]; 109 | 110 | #ifdef NDEBUG 111 | /* 112 | * Figure out if we should write the message or not. 113 | */ 114 | if (log_level == LOG_CONN) { 115 | if (level == LOG_INFO) 116 | return; 117 | } else if (log_level == LOG_INFO) { 118 | if (level > LOG_INFO && level != LOG_CONN) 119 | return; 120 | } else if (level > log_level) 121 | return; 122 | #endif 123 | 124 | #ifdef HAVE_SYSLOG_H 125 | if (config.syslog && level == LOG_CONN) 126 | level = LOG_INFO; 127 | #endif 128 | 129 | va_start(args, fmt); 130 | 131 | /* 132 | * If the config file hasn't been processed, then we need to store 133 | * the messages for later processing. 134 | */ 135 | if (!processed_config_file) { 136 | char* entry_buffer; 137 | 138 | if (!log_message_storage) { 139 | log_message_storage = vector_create(); 140 | if (!log_message_storage) 141 | return; 142 | } 143 | 144 | vsnprintf(str, STRING_LENGTH, fmt, args); 145 | 146 | entry_buffer = safemalloc(strlen(str) + 6); 147 | if (!entry_buffer) 148 | return; 149 | 150 | sprintf(entry_buffer, "%d %s", level, str); 151 | vector_append(log_message_storage, entry_buffer, 152 | strlen(entry_buffer) + 1); 153 | 154 | va_end(args); 155 | 156 | return; 157 | } 158 | 159 | #ifdef HAVE_SYSLOG_H 160 | if (config.syslog) { 161 | # ifdef HAVE_VSYSLOG_H 162 | vsyslog(level, fmt, args); 163 | # else 164 | vsnprintf(str, STRING_LENGTH, fmt, args); 165 | syslog(level, "%s", str); 166 | # endif 167 | } else { 168 | #endif 169 | nowtime = time(NULL); 170 | /* Format is month day hour:minute:second (24 time) */ 171 | strftime(time_string, TIME_LENGTH, "%b %d %H:%M:%S", 172 | localtime(&nowtime)); 173 | 174 | snprintf(str, STRING_LENGTH, "%-9s %s [%ld]: ", syslog_level[level], 175 | time_string, (long int) getpid()); 176 | 177 | assert(log_file_fd >= 0); 178 | 179 | write(log_file_fd, str, strlen(str)); 180 | vsnprintf(str, STRING_LENGTH, fmt, args); 181 | write(log_file_fd, str, strlen(str)); 182 | write(log_file_fd, "\n", 1); 183 | 184 | #ifdef HAVE_SYSLOG_H 185 | } 186 | #endif 187 | 188 | va_end(args); 189 | } 190 | 191 | /* 192 | * This needs to send any stored log messages. 193 | */ 194 | void 195 | send_stored_logs(void) 196 | { 197 | char *string; 198 | char *ptr; 199 | 200 | int level; 201 | 202 | int i; 203 | 204 | for (i = 0; i != vector_length(log_message_storage); ++i) { 205 | string = vector_getentry(log_message_storage, i, NULL); 206 | 207 | ptr = strchr(string, ' ') + 1; 208 | level = atoi(string); 209 | 210 | #if NDEBUG 211 | if (log_level == LOG_CONN && level == LOG_INFO) 212 | continue; 213 | else if (log_level == LOG_INFO) { 214 | if (level > LOG_INFO && level != LOG_CONN) 215 | continue; 216 | } else if (level > log_level) 217 | continue; 218 | #endif 219 | 220 | log_message(level, ptr); 221 | } 222 | 223 | vector_delete(log_message_storage); 224 | log_message_storage = NULL; 225 | } 226 | -------------------------------------------------------------------------------- /src/log.h: -------------------------------------------------------------------------------- 1 | /* $Id: log.h,v 1.11 2002/10/03 20:49:57 rjkaes Exp $ 2 | * 3 | * See 'log.c' for a detailed description. 4 | * 5 | * Copyright (C) 1998 Steven Young 6 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #ifndef TINYPROXY_LOG_H 20 | #define TINYPROXY_LOG_H 21 | 22 | #ifdef HAVE_CONFIG_H 23 | # include 24 | #endif 25 | 26 | /* 27 | * Okay, I have modelled the levels for logging off the syslog() interface. 28 | * However, I would really prefer if only five of the levels are used. You 29 | * can see them below and I'll describe what each level should be for. 30 | * Hopefully tinyproxy will remain consistent with these levels. 31 | * -- rjkaes 32 | * Sorry but I had to destroy the hope ;-) There was a need to log 33 | * connections without the INFO stuff and not to have them as NOTICE. 34 | * -- hgb 35 | * 36 | * Level Description 37 | * ----- ----------- 38 | * LOG_CRIT This is catastrophic. Basically, tinyproxy can not recover 39 | * from this and will either close the child (if we're lucky), 40 | * or the entire daemon. I would relegate this to conditions 41 | * like unable to create the listening socket, or unable to 42 | * create a child. If you're going to log at this level provide 43 | * as much information as possible. 44 | * 45 | * LOG_ERR Okay, something bad happened. We can recover from this, but 46 | * the connection will be terminated. This should be for things 47 | * like when we cannot create a socket, or out of memory. 48 | * Basically, the connection will not work, but it's not enough 49 | * to bring the whole daemon down. 50 | * 51 | * LOG_WARNING There is condition which will change the behaviour of 52 | * tinyproxy from what is expected. For example, somebody did 53 | * not specify a port. tinyproxy will handle this (by using 54 | * it's default port), but it's a _higher_ level situation 55 | * which the admin should be aware of. 56 | * 57 | * LOG_NOTICE This is for a special condition. Nothing has gone wrong, but 58 | * it is more important than the common LOG_INFO level. Right 59 | * now it is used for actions like creating/destroying children, 60 | * unauthorized access, signal handling, etc. 61 | * 62 | * LOG_CONN This additional level is for logging connections only, so 63 | * it is easy to control only the requests in the logfile. 64 | * If we log through syslog, this is set to LOG_INFO. 65 | * -- hgb 66 | * 67 | * LOG_INFO Everything else ends up here. Logging for incoming 68 | * connections, denying due to filtering rules, unable to 69 | * connect to remote server, etc. 70 | * 71 | * LOG_DEBUG Don't use this level. :) Use the two DEBUG?() macros 72 | * instead since they can remain in the source if needed. (I 73 | * don't advocate this, but it could be useful at times.) 74 | */ 75 | 76 | #ifdef HAVE_SYSLOG_H 77 | # include 78 | #else 79 | # define LOG_CRIT 2 80 | # define LOG_ERR 3 81 | # define LOG_WARNING 4 82 | # define LOG_NOTICE 5 83 | # define LOG_INFO 6 84 | # define LOG_DEBUG 7 85 | #endif 86 | 87 | #define LOG_CONN 8 /* extra to log connections without the INFO stuff */ 88 | 89 | /* 90 | * Use this for debugging. The format is specific: 91 | * DEBUG1("There was a major problem"); 92 | * DEBUG2("There was a big problem: %s in connptr %p", "hello", connptr); 93 | */ 94 | #ifndef NDEBUG 95 | # define DEBUG1(x) log_message(LOG_DEBUG, "[%s:%d] " x, __FILE__, __LINE__) 96 | # define DEBUG2(x, y...) log_message(LOG_DEBUG, "[%s:%d] " x, __FILE__, __LINE__, ## y) 97 | #else 98 | # define DEBUG1(x) do { } while(0) 99 | # define DEBUG2(x, y...) do { } while(0) 100 | #endif 101 | 102 | extern int open_log_file(const char* file); 103 | extern void close_log_file(void); 104 | extern void truncate_log_file(void); 105 | 106 | extern void log_message(int level, char *fmt, ...); 107 | extern void set_log_level(int level); 108 | extern void send_stored_logs(void); 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /src/network.c: -------------------------------------------------------------------------------- 1 | /* $Id: network.c,v 1.1 2002/05/23 04:41:48 rjkaes Exp $ 2 | * 3 | * The functions found here are used for communicating across a 4 | * network. They include both safe reading and writing (which are 5 | * the basic building blocks) along with two functions for 6 | * easily reading a line of text from the network, and a function 7 | * to write an arbitrary amount of data to the network. 8 | * 9 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 10 | * 11 | * This program is free software; you can redistribute it and/or modify it 12 | * under the terms of the GNU General Public License as published by the 13 | * Free Software Foundation; either version 2, or (at your option) any 14 | * later version. 15 | * 16 | * This program is distributed in the hope that it will be useful, but 17 | * WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 | * General Public License for more details. 20 | */ 21 | 22 | #include "tinyproxy.h" 23 | 24 | #include "heap.h" 25 | #include "network.h" 26 | 27 | /* 28 | * Write the buffer to the socket. If an EINTR occurs, pick up and try 29 | * again. Keep sending until the buffer has been sent. 30 | */ 31 | ssize_t 32 | safe_write(int fd, const char *buffer, size_t count) 33 | { 34 | ssize_t len; 35 | size_t bytestosend; 36 | 37 | assert(fd >= 0); 38 | assert(buffer != NULL); 39 | assert(count > 0); 40 | 41 | bytestosend = count; 42 | 43 | while (1) { 44 | len = send(fd, buffer, bytestosend, MSG_NOSIGNAL); 45 | 46 | if (len < 0) { 47 | if (errno == EINTR) 48 | continue; 49 | else 50 | return -errno; 51 | } 52 | 53 | if (len == bytestosend) 54 | break; 55 | 56 | buffer += len; 57 | bytestosend -= len; 58 | } 59 | 60 | return count; 61 | } 62 | 63 | /* 64 | * Matched pair for safe_write(). If an EINTR occurs, pick up and try 65 | * again. 66 | */ 67 | ssize_t 68 | safe_read(int fd, char *buffer, size_t count) 69 | { 70 | ssize_t len; 71 | 72 | do { 73 | len = read(fd, buffer, count); 74 | } while (len < 0 && errno == EINTR); 75 | 76 | return len; 77 | } 78 | 79 | /* 80 | * Send a "message" to the file descriptor provided. This handles the 81 | * differences between the various implementations of vsnprintf. This code 82 | * was basically stolen from the snprintf() man page of Debian Linux 83 | * (although I did fix a memory leak. :) 84 | */ 85 | int 86 | write_message(int fd, const char *fmt, ...) 87 | { 88 | ssize_t n; 89 | size_t size = (1024 * 8); /* start with 8 KB and go from there */ 90 | char *buf, *tmpbuf; 91 | va_list ap; 92 | 93 | if ((buf = safemalloc(size)) == NULL) 94 | return -1; 95 | 96 | while (1) { 97 | va_start(ap, fmt); 98 | n = vsnprintf(buf, size, fmt, ap); 99 | va_end(ap); 100 | 101 | /* If that worked, break out so we can send the buffer */ 102 | if (n > -1 && n < size) 103 | break; 104 | 105 | /* Else, try again with more space */ 106 | if (n > -1) 107 | /* precisely what is needed (glibc2.1) */ 108 | size = n + 1; 109 | else 110 | /* twice the old size (glibc2.0) */ 111 | size *= 2; 112 | 113 | if ((tmpbuf = saferealloc(buf, size)) == NULL) { 114 | safefree(buf); 115 | return -1; 116 | } else 117 | buf = tmpbuf; 118 | } 119 | 120 | if (safe_write(fd, buf, n) < 0) { 121 | safefree(buf); 122 | return -1; 123 | } 124 | 125 | safefree(buf); 126 | return 0; 127 | } 128 | 129 | /* 130 | * Read in a "line" from the socket. It might take a few loops through 131 | * the read sequence. The full string is allocate off the heap and stored 132 | * at the whole_buffer pointer. The caller needs to free the memory when 133 | * it is no longer in use. The returned line is NULL terminated. 134 | * 135 | * Returns the length of the buffer on success (not including the NULL 136 | * termination), 0 if the socket was closed, and -1 on all other errors. 137 | */ 138 | #define SEGMENT_LEN (512) 139 | #define MAXIMUM_BUFFER_LENGTH (128 * 1024) 140 | ssize_t 141 | readline(int fd, char **whole_buffer) 142 | { 143 | ssize_t whole_buffer_len; 144 | char buffer[SEGMENT_LEN]; 145 | char *ptr; 146 | 147 | ssize_t ret; 148 | ssize_t diff; 149 | 150 | struct read_lines_s { 151 | char *data; 152 | size_t len; 153 | struct read_lines_s *next; 154 | }; 155 | struct read_lines_s *first_line, *line_ptr; 156 | 157 | first_line = safecalloc(sizeof(struct read_lines_s), 1); 158 | if (!first_line) 159 | return -ENOMEM; 160 | 161 | line_ptr = first_line; 162 | 163 | whole_buffer_len = 0; 164 | for (;;) { 165 | ret = recv(fd, buffer, SEGMENT_LEN, MSG_PEEK); 166 | if (ret <= 0) 167 | goto CLEANUP; 168 | 169 | ptr = memchr(buffer, '\n', ret); 170 | if (ptr) 171 | diff = ptr - buffer + 1; 172 | else 173 | diff = ret; 174 | 175 | whole_buffer_len += diff; 176 | 177 | /* 178 | * Don't allow the buffer to grow without bound. If we 179 | * get to more than MAXIMUM_BUFFER_LENGTH close. 180 | */ 181 | if (whole_buffer_len > MAXIMUM_BUFFER_LENGTH) { 182 | ret = -ERANGE; 183 | goto CLEANUP; 184 | } 185 | 186 | line_ptr->data = safemalloc(diff); 187 | if (!line_ptr->data) { 188 | ret = -ENOMEM; 189 | goto CLEANUP; 190 | } 191 | 192 | recv(fd, line_ptr->data, diff, 0); 193 | line_ptr->len = diff; 194 | 195 | if (ptr) { 196 | line_ptr->next = NULL; 197 | break; 198 | } 199 | 200 | line_ptr->next = safecalloc(sizeof(struct read_lines_s), 1); 201 | if (!line_ptr->next) { 202 | ret = -ENOMEM; 203 | goto CLEANUP; 204 | } 205 | line_ptr = line_ptr->next; 206 | } 207 | 208 | *whole_buffer = safemalloc(whole_buffer_len + 1); 209 | if (!*whole_buffer) { 210 | ret = -ENOMEM; 211 | goto CLEANUP; 212 | } 213 | 214 | *(*whole_buffer + whole_buffer_len) = '\0'; 215 | 216 | whole_buffer_len = 0; 217 | line_ptr = first_line; 218 | while (line_ptr) { 219 | memcpy(*whole_buffer + whole_buffer_len, line_ptr->data, 220 | line_ptr->len); 221 | whole_buffer_len += line_ptr->len; 222 | 223 | line_ptr = line_ptr->next; 224 | } 225 | 226 | ret = whole_buffer_len; 227 | 228 | CLEANUP: 229 | do { 230 | line_ptr = first_line->next; 231 | if (first_line->data) 232 | safefree(first_line->data); 233 | safefree(first_line); 234 | first_line = line_ptr; 235 | } while (first_line); 236 | 237 | return ret; 238 | } 239 | -------------------------------------------------------------------------------- /src/network.h: -------------------------------------------------------------------------------- 1 | /* $Id: network.h,v 1.1 2002/05/23 04:41:48 rjkaes Exp $ 2 | * 3 | * See 'network.c' for a detailed description. 4 | * 5 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_NETWORK_H 19 | #define TINYPROXY_NETWORK_H 20 | 21 | extern ssize_t safe_write(int fd, const char *buffer, size_t count); 22 | extern ssize_t safe_read(int fd, char *buffer, size_t count); 23 | 24 | extern int write_message(int fd, const char *fmt, ...); 25 | extern ssize_t readline(int fd, char **whole_buffer); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/regexp.h: -------------------------------------------------------------------------------- 1 | /* $Id: regexp.h,v 1.3 2001/11/25 22:06:54 rjkaes Exp $ 2 | * 3 | * We need this little header to help distinguish whether to use the REGEX 4 | * library installed in the system, or to include our own version (the GNU 5 | * version to be exact.) 6 | * 7 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published by the 11 | * Free Software Foundation; either version 2, or (at your option) any 12 | * later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | */ 19 | 20 | #ifndef _TINYPROXY_REGEXP_H_ 21 | #define _TINYPROXY_REGEXP_H_ 22 | 23 | #ifdef HAVE_CONFIG_H 24 | # include 25 | #endif 26 | 27 | #ifdef USE_GNU_REGEX 28 | # include "gnuregex.h" 29 | #else 30 | # ifdef HAVE_REGEX_H 31 | # include 32 | # endif 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/reqs.h: -------------------------------------------------------------------------------- 1 | /* $Id: reqs.h,v 1.4 2003/05/29 19:43:57 rjkaes Exp $ 2 | * 3 | * See 'reqs.c' for a detailed description. 4 | * 5 | * Copyright (C) 1998 Steven Young 6 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #ifndef _TINYPROXY_REQS_H_ 20 | #define _TINYPROXY_REQS_H_ 21 | 22 | extern void handle_connection(int fd); 23 | extern void add_connect_port_allowed(int port); 24 | extern void upstream_add(const char *host, int port, const char *domain, proxy_type type); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/scanner.l: -------------------------------------------------------------------------------- 1 | /* $Id: scanner.l,v 1.22 2003/06/26 18:26:10 rjkaes Exp $ 2 | * 3 | * This builds the scanner for the tinyproxy configuration file. This 4 | * file needs to stay in sync with grammar.y. If someone knows lex and yacc 5 | * better than I do, please update these files. 6 | * 7 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published by the 11 | * Free Software Foundation; either version 2, or (at your option) any 12 | * later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, but 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * General Public License for more details. 18 | */ 19 | %{ 20 | 21 | #include "tinyproxy.h" 22 | 23 | #include "grammar.h" 24 | 25 | struct keyword { 26 | char *kw_name; 27 | int kw_token; 28 | }; 29 | 30 | static struct keyword keywords[] = { 31 | /* statements */ 32 | { "port", KW_PORT }, 33 | { "logfile", KW_LOGFILE }, 34 | { "syslog", KW_SYSLOG }, 35 | { "maxclients", KW_MAXCLIENTS }, 36 | { "maxspareservers", KW_MAXSPARESERVERS }, 37 | { "minspareservers", KW_MINSPARESERVERS }, 38 | { "startservers", KW_STARTSERVERS }, 39 | { "maxrequestsperchild", KW_MAXREQUESTSPERCHILD }, 40 | { "pidfile", KW_PIDFILE }, 41 | { "timeout", KW_TIMEOUT }, 42 | { "listen", KW_LISTEN }, 43 | { "user", KW_USER }, 44 | { "group", KW_GROUP }, 45 | { "anonymous", KW_ANONYMOUS }, 46 | { "filter", KW_FILTER }, 47 | { "filterurls", KW_FILTERURLS }, 48 | { "filterextended", KW_FILTEREXTENDED }, 49 | { "filterdefaultdeny", KW_FILTER_DEFAULT_DENY }, 50 | { "filtercasesensitive", KW_FILTER_CASESENSITIVE }, 51 | { "xtinyproxy", KW_XTINYPROXY }, 52 | { "upstream", KW_UPSTREAM }, 53 | { "allow", KW_ALLOW }, 54 | { "deny", KW_DENY }, 55 | { "connectport", KW_CONNECTPORT }, 56 | { "bind", KW_BIND }, 57 | { "viaproxyname", KW_VIA_PROXY_NAME }, 58 | { "stathost", KW_STATHOST }, 59 | { "errorfile", KW_ERRORPAGE }, 60 | { "defaulterrorfile", KW_DEFAULT_ERRORPAGE }, 61 | { "statfile", KW_STATPAGE }, 62 | 63 | /* proxy types */ 64 | { "http", KW_PROXY_HTTP }, 65 | { "socks4", KW_PROXY_SOCKS4 }, 66 | { "socks5", KW_PROXY_SOCKS5 }, 67 | 68 | /* loglevel and the settings */ 69 | { "loglevel", KW_LOGLEVEL }, 70 | { "critical", KW_LOG_CRITICAL }, 71 | { "error", KW_LOG_ERROR }, 72 | { "warning", KW_LOG_WARNING }, 73 | { "notice", KW_LOG_NOTICE }, 74 | { "connect", KW_LOG_CONNECT }, 75 | { "info", KW_LOG_INFO }, 76 | 77 | /* on/off switches */ 78 | { "yes", KW_YES }, 79 | { "on", KW_YES }, 80 | { "no", KW_NO }, 81 | { "off", KW_NO } 82 | 83 | }; 84 | 85 | #define YY_NO_UNPUT 1 86 | 87 | #define MAX_REGEXP_LEN 1024 88 | 89 | char tiny_buf[MAX_REGEXP_LEN]; 90 | char *tiny_str; 91 | 92 | static int check_reserved_words(char *token); 93 | static void append_string(int length, char *str); 94 | static void append_char(char c); 95 | 96 | %} 97 | 98 | %option noyywrap batch yylineno 99 | 100 | white [ \t] 101 | digit [0-9] 102 | alpha [a-zA-Z] 103 | alphanum [a-zA-Z0-9] 104 | word [^ \#'"\(\)\{\}\\;\n\t,|\.] 105 | 106 | %x string 107 | 108 | %% 109 | 110 | \#.*$ ; 111 | \n { return '\n'; } 112 | ":" { return ':'; } 113 | {white}+ ; 114 | 0x{digit}+ { yylval.num = strtol(yytext, NULL, 16); return NUMBER; } 115 | 0{digit}+ { yylval.num = strtol(yytext, NULL, 8); return NUMBER; } 116 | {digit}+ { yylval.num = atoi(yytext); return NUMBER; } 117 | {alpha}({alphanum}|[-._])+ { return check_reserved_words(yytext); } 118 | 119 | \" { 120 | tiny_str = tiny_buf; 121 | BEGIN(string); 122 | } 123 | \\a { append_char(7); } 124 | \\n { append_char(10); } 125 | \\r { append_char(13); } 126 | \\t { append_char(9); } 127 | \\v { append_char(11); } 128 | \\[^anrtv] { append_string(1, yytext + 1); } 129 | \" { 130 | BEGIN(INITIAL); 131 | yylval.cptr = strdup(tiny_buf); 132 | return STRING; 133 | } 134 | [^"\\]+ { append_string(strlen(yytext), yytext); } 135 | 136 | 137 | ({digit}{1,3}\.){3}{digit}{1,3} { yylval.cptr = strdup(yytext); return NUMERIC_ADDRESS; } 138 | ({digit}{1,3}\.){3}{digit}{1,3}\/{digit}+ { yylval.cptr = strdup(yytext); return NETMASK_ADDRESS; } 139 | 140 | 141 | %% 142 | 143 | int 144 | check_reserved_words(char *token) 145 | { 146 | int i; 147 | 148 | for (i = 0; i < (sizeof(keywords) / sizeof(struct keyword)); i++) { 149 | if (strcasecmp(keywords[i].kw_name, token) == 0) { 150 | return keywords[i].kw_token; 151 | } 152 | } 153 | yylval.cptr = strdup(token); 154 | return IDENTIFIER; 155 | } 156 | 157 | static void 158 | append_string(int length, char *s) 159 | { 160 | int to_copy = min(MAX_REGEXP_LEN - (tiny_str - tiny_buf) - 1, length); 161 | 162 | memcpy(tiny_str, s, to_copy); 163 | tiny_str += to_copy; 164 | *tiny_str = 0; 165 | } 166 | 167 | static void 168 | append_char(char c) 169 | { 170 | *tiny_str = c; 171 | tiny_str++; 172 | *tiny_str = 0; 173 | } 174 | -------------------------------------------------------------------------------- /src/sock.c: -------------------------------------------------------------------------------- 1 | /* $Id: sock.c,v 1.39 2002/10/03 20:50:59 rjkaes Exp $ 2 | * 3 | * Sockets are created and destroyed here. When a new connection comes in from 4 | * a client, we need to copy the socket and the create a second socket to the 5 | * remote server the client is trying to connect to. Also, the listening 6 | * socket is created and destroyed here. Sounds more impressive than it 7 | * actually is. 8 | * 9 | * Copyright (C) 1998 Steven Young 10 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 11 | * Copyright (C) 2000 Chris Lightfoot (chris@ex-parrot.com) 12 | * 13 | * This program is free software; you can redistribute it and/or modify it 14 | * under the terms of the GNU General Public License as published by the 15 | * Free Software Foundation; either version 2, or (at your option) any 16 | * later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, but 19 | * WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | * General Public License for more details. 22 | */ 23 | 24 | #include "tinyproxy.h" 25 | 26 | #include "log.h" 27 | #include "heap.h" 28 | #include "sock.h" 29 | #include "text.h" 30 | 31 | /* 32 | * Take a string host address and return a struct in_addr so we can connect 33 | * to the remote host. 34 | * 35 | * Return a negative if there is a problem. 36 | */ 37 | static int 38 | lookup_domain(struct in_addr *addr, const char *domain) 39 | { 40 | struct hostent* result; 41 | 42 | assert(domain != NULL); 43 | 44 | result = gethostbyname(domain); 45 | if (result) { 46 | memcpy(addr, result->h_addr_list[0], result->h_length); 47 | return 0; 48 | } else 49 | return -1; 50 | } 51 | 52 | /* This routine is so old I can't even remember writing it. But I do 53 | * remember that it was an .h file because I didn't know putting code in a 54 | * header was bad magic yet. anyway, this routine opens a connection to a 55 | * system and returns the fd. 56 | * - steve 57 | * 58 | * Cleaned up some of the code to use memory routines which are now the 59 | * default. Also, the routine first checks to see if the address is in 60 | * dotted-decimal form before it does a name lookup. 61 | * - rjkaes 62 | */ 63 | int 64 | opensock(char *ip_addr, uint16_t port) 65 | { 66 | int sock_fd; 67 | struct sockaddr_in port_info; 68 | struct sockaddr_in bind_addr; 69 | int ret; 70 | 71 | assert(ip_addr != NULL); 72 | assert(port > 0); 73 | 74 | memset((struct sockaddr *) &port_info, 0, sizeof(port_info)); 75 | 76 | port_info.sin_family = AF_INET; 77 | 78 | /* Lookup and return the address if possible */ 79 | ret = lookup_domain(&port_info.sin_addr, ip_addr); 80 | 81 | if (ret < 0) { 82 | log_message(LOG_ERR, 83 | "opensock: Could not lookup address \"%s\".", 84 | ip_addr); 85 | return -1; 86 | } 87 | 88 | port_info.sin_port = htons(port); 89 | 90 | if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 91 | log_message(LOG_ERR, "opensock: socket() error \"%s\".", 92 | strerror(errno)); 93 | return -1; 94 | } 95 | 96 | /* Bind to the specified address */ 97 | if (config.bind_address) { 98 | memset(&bind_addr, 0, sizeof(bind_addr)); 99 | bind_addr.sin_family = AF_INET; 100 | bind_addr.sin_addr.s_addr = inet_addr(config.bind_address); 101 | 102 | ret = bind(sock_fd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)); 103 | if (ret < 0) { 104 | log_message(LOG_ERR, "Could not bind local address \"%\" because of %s", 105 | config.bind_address, 106 | strerror(errno)); 107 | return -1; 108 | } 109 | } 110 | 111 | if (connect(sock_fd, (struct sockaddr *) &port_info, sizeof(port_info)) < 0) { 112 | log_message(LOG_ERR, "opensock: connect() error \"%s\".", 113 | strerror(errno)); 114 | return -1; 115 | } 116 | 117 | return sock_fd; 118 | } 119 | 120 | /* 121 | * Set the socket to non blocking -rjkaes 122 | */ 123 | int 124 | socket_nonblocking(int sock) 125 | { 126 | int flags; 127 | 128 | assert(sock >= 0); 129 | 130 | flags = fcntl(sock, F_GETFL, 0); 131 | return fcntl(sock, F_SETFL, flags | O_NONBLOCK); 132 | } 133 | 134 | /* 135 | * Set the socket to blocking -rjkaes 136 | */ 137 | int 138 | socket_blocking(int sock) 139 | { 140 | int flags; 141 | 142 | assert(sock >= 0); 143 | 144 | flags = fcntl(sock, F_GETFL, 0); 145 | return fcntl(sock, F_SETFL, flags & ~O_NONBLOCK); 146 | } 147 | 148 | /* 149 | * Start listening to a socket. Create a socket with the selected port. 150 | * The size of the socket address will be returned to the caller through 151 | * the pointer, while the socket is returned as a default return. 152 | * - rjkaes 153 | */ 154 | int 155 | listen_sock(uint16_t port, socklen_t* addrlen) 156 | { 157 | int listenfd; 158 | const int on = 1; 159 | struct sockaddr_in addr; 160 | 161 | assert(port > 0); 162 | assert(addrlen != NULL); 163 | 164 | listenfd = socket(AF_INET, SOCK_STREAM, 0); 165 | setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 166 | 167 | memset(&addr, 0, sizeof(addr)); 168 | addr.sin_family = AF_INET; 169 | addr.sin_port = htons(port); 170 | 171 | if (config.ipAddr) { 172 | addr.sin_addr.s_addr = inet_addr(config.ipAddr); 173 | } else { 174 | addr.sin_addr.s_addr = inet_addr("0.0.0.0"); 175 | } 176 | 177 | if (bind(listenfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 178 | log_message(LOG_ERR, "Unable to bind listening socket because of %s", 179 | strerror(errno)); 180 | return -1; 181 | } 182 | 183 | if (listen(listenfd, MAXLISTEN) < 0) { 184 | log_message(LOG_ERR, "Unable to start listening socket because of %s", 185 | strerror(errno)); 186 | return -1; 187 | } 188 | 189 | *addrlen = sizeof(addr); 190 | 191 | return listenfd; 192 | } 193 | 194 | /* 195 | * Return the peer's socket information. 196 | */ 197 | int 198 | getpeer_information(int fd, char* ipaddr, char* string_addr) 199 | { 200 | struct sockaddr_in name; 201 | size_t namelen = sizeof(name); 202 | struct hostent* result; 203 | 204 | assert(fd >= 0); 205 | assert(ipaddr != NULL); 206 | assert(string_addr != NULL); 207 | 208 | /* 209 | * Clear the memory. 210 | */ 211 | memset(ipaddr, '\0', PEER_IP_LENGTH); 212 | memset(string_addr, '\0', PEER_STRING_LENGTH); 213 | 214 | if (getpeername(fd, (struct sockaddr *)&name, &namelen) != 0) { 215 | log_message(LOG_ERR, "getpeer_information: getpeername() error: %s", 216 | strerror(errno)); 217 | return -1; 218 | } else { 219 | strlcpy(ipaddr, 220 | inet_ntoa(*(struct in_addr *)&name.sin_addr.s_addr), 221 | PEER_IP_LENGTH); 222 | } 223 | 224 | result = gethostbyaddr((char *)&name.sin_addr.s_addr, 4, AF_INET); 225 | if (result) { 226 | strlcpy(string_addr, result->h_name, PEER_STRING_LENGTH); 227 | return 0; 228 | } else { 229 | return -1; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /src/sock.h: -------------------------------------------------------------------------------- 1 | /* $Id: sock.h,v 1.11 2003/01/27 18:45:25 rjkaes Exp $ 2 | * 3 | * See 'sock.c' for a detailed description. 4 | * 5 | * Copyright (C) 1998 Steven Young 6 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #ifndef TINYPROXY_SOCK_H 20 | #define TINYPROXY_SOCK_H 21 | 22 | #define PEER_IP_LENGTH 16 23 | #define PEER_STRING_LENGTH 256 24 | 25 | #define MAXLINE (1024 * 4) 26 | 27 | extern int opensock(char *ip_addr, uint16_t port); 28 | extern int listen_sock(uint16_t port, socklen_t* addrlen); 29 | 30 | extern int socket_nonblocking(int sock); 31 | extern int socket_blocking(int sock); 32 | 33 | extern int getpeer_information(int fd, char* ipaddr, char* string_addr); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/stats.c: -------------------------------------------------------------------------------- 1 | /* $Id: stats.c,v 1.13 2003/03/13 21:31:03 rjkaes Exp $ 2 | * 3 | * This module handles the statistics for tinyproxy. There are only two 4 | * public API functions. The reason for the functions, rather than just a 5 | * external structure is that tinyproxy is now multi-threaded and we can 6 | * not allow more than one child to access the statistics at the same 7 | * time. This is prevented by a mutex. If there is a need for more 8 | * statistics in the future, just add to the structure, enum (in the header), 9 | * and the switch statement in update_stats(). 10 | * 11 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 12 | * 13 | * This program is free software; you can redistribute it and/or modify it 14 | * under the terms of the GNU General Public License as published by the 15 | * Free Software Foundation; either version 2, or (at your option) any 16 | * later version. 17 | * 18 | * This program is distributed in the hope that it will be useful, but 19 | * WITHOUT ANY WARRANTY; without even the implied warranty of 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | * General Public License for more details. 22 | */ 23 | 24 | #include "tinyproxy.h" 25 | 26 | #include "log.h" 27 | #include "heap.h" 28 | #include "htmlerror.h" 29 | #include "stats.h" 30 | #include "utils.h" 31 | 32 | struct stat_s { 33 | unsigned long int num_reqs; 34 | unsigned long int num_badcons; 35 | unsigned long int num_open; 36 | unsigned long int num_refused; 37 | unsigned long int num_denied; 38 | }; 39 | 40 | static struct stat_s *stats; 41 | 42 | /* 43 | * Initialize the statistics information to zero. 44 | */ 45 | void 46 | init_stats(void) 47 | { 48 | stats = malloc_shared_memory(sizeof(struct stat_s)); 49 | if (stats == MAP_FAILED) 50 | return; 51 | 52 | memset(stats, 0, sizeof(struct stat)); 53 | } 54 | 55 | /* 56 | * Display the statics of the tinyproxy server. 57 | */ 58 | int 59 | showstats(struct conn_s *connptr) 60 | { 61 | static char *msg = 62 | "%s (%s) stats\r\n" 63 | "\r\n" 64 | "

%s (%s) run-time statistics


\r\n" 65 | "
\r\n" 66 | "Number of open connections: %lu
\r\n" 67 | "Number of requests: %lu
\r\n" 68 | "Number of bad connections: %lu
\r\n" 69 | "Number of denied connections: %lu
\r\n" 70 | "Number of refused connections due to high load: %lu\r\n" 71 | "
\r\n\r\n"; 72 | 73 | char *message_buffer; 74 | char opens[16], reqs[16], badconns[16], denied[16], refused[16]; 75 | FILE *statfile; 76 | 77 | snprintf(opens, sizeof(opens), "%lu", stats->num_open); 78 | snprintf(reqs, sizeof(reqs), "%lu", stats->num_reqs); 79 | snprintf(badconns, sizeof(badconns), "%lu", stats->num_badcons); 80 | snprintf(denied, sizeof(denied), "%lu", stats->num_denied); 81 | snprintf(refused, sizeof(refused), "%lu", stats->num_refused); 82 | 83 | if (!config.statpage || (!(statfile = fopen(config.statpage, "r")))) { 84 | message_buffer = safemalloc(MAXBUFFSIZE); 85 | if (!message_buffer) 86 | return -1; 87 | 88 | snprintf(message_buffer, MAXBUFFSIZE, msg, 89 | PACKAGE, VERSION, PACKAGE, VERSION, 90 | stats->num_open, 91 | stats->num_reqs, 92 | stats->num_badcons, stats->num_denied, stats->num_refused); 93 | 94 | if (send_http_message(connptr, 200, "OK", message_buffer) < 0) { 95 | safefree(message_buffer); 96 | return -1; 97 | } 98 | 99 | safefree(message_buffer); 100 | return 0; 101 | } 102 | 103 | add_error_variable(connptr, "opens", opens); 104 | add_error_variable(connptr, "reqs", reqs); 105 | add_error_variable(connptr, "badconns", badconns); 106 | add_error_variable(connptr, "denied", denied); 107 | add_error_variable(connptr, "refused", refused); 108 | add_standard_vars(connptr); 109 | send_http_headers(connptr, 200, "Statistic requested"); 110 | send_html_file(statfile, connptr); 111 | fclose(statfile); 112 | 113 | return 0; 114 | } 115 | 116 | /* 117 | * Update the value of the statistics. The update_level is defined in 118 | * stats.h 119 | */ 120 | int 121 | update_stats(status_t update_level) 122 | { 123 | switch (update_level) { 124 | case STAT_BADCONN: 125 | ++stats->num_badcons; 126 | break; 127 | case STAT_OPEN: 128 | ++stats->num_open; 129 | ++stats->num_reqs; 130 | break; 131 | case STAT_CLOSE: 132 | --stats->num_open; 133 | break; 134 | case STAT_REFUSE: 135 | ++stats->num_refused; 136 | break; 137 | case STAT_DENIED: 138 | ++stats->num_denied; 139 | break; 140 | default: 141 | return -1; 142 | } 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /src/stats.h: -------------------------------------------------------------------------------- 1 | /* $Id: stats.h,v 1.4 2001/11/22 00:31:10 rjkaes Exp $ 2 | * 3 | * See 'stats.h' for a detailed description. 4 | * 5 | * Copyright (C) 2000 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef _TINYPROXY_STATS_H_ 19 | #define _TINYPROXY_STATS_H_ 20 | 21 | #include "conns.h" 22 | 23 | /* 24 | * Various logable statistics 25 | */ 26 | typedef enum { 27 | STAT_BADCONN, /* bad connection, for unknown reason */ 28 | STAT_OPEN, /* connection opened */ 29 | STAT_CLOSE, /* connection closed */ 30 | STAT_REFUSE, /* connection refused (to outside world) */ 31 | STAT_DENIED /* connection denied to tinyproxy itself */ 32 | } status_t; 33 | 34 | /* 35 | * Public API to the statistics for tinyproxy 36 | */ 37 | extern void init_stats(void); 38 | extern int showstats(struct conn_s *connptr); 39 | extern int update_stats(status_t update_level); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/text.c: -------------------------------------------------------------------------------- 1 | /* $Id: text.c,v 1.3 2003/03/13 05:20:06 rjkaes Exp $ 2 | * 3 | * The functions included here are useful for text manipulation. They 4 | * replace or augment the standard C string library. These functions 5 | * are either safer replacements, or they provide services not included 6 | * with the standard C string library. 7 | * 8 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 9 | * 10 | * This program is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2, or (at your option) any 13 | * later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, but 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * General Public License for more details. 19 | */ 20 | 21 | #include "tinyproxy.h" 22 | 23 | #include "text.h" 24 | 25 | #ifndef HAVE_STRLCPY 26 | /* 27 | * Function API taken from OpenBSD. Like strncpy(), but does not 0 fill the 28 | * buffer, and always NULL terminates the buffer. size is the size of the 29 | * destination buffer. 30 | */ 31 | size_t 32 | strlcpy(char *dst, const char *src, size_t size) 33 | { 34 | size_t len = strlen(src); 35 | size_t ret = len; 36 | 37 | if (len >= size) 38 | len = size - 1; 39 | 40 | memcpy(dst, src, len); 41 | dst[len] = '\0'; 42 | 43 | return ret; 44 | } 45 | #endif 46 | 47 | #ifndef HAVE_STRLCAT 48 | /* 49 | * Function API taken from OpenBSD. Like strncat(), but does not 0 fill the 50 | * buffer, and always NULL terminates the buffer. size is the length of the 51 | * buffer, which should be one more than the maximum resulting string 52 | * length. 53 | */ 54 | size_t 55 | strlcat(char *dst, const char *src, size_t size) 56 | { 57 | size_t len1 = strlen(dst); 58 | size_t len2 = strlen(src); 59 | size_t ret = len1 + len2; 60 | 61 | if (len1 + len2 >= size) 62 | len2 = size - len1 - 1; 63 | if (len2 > 0) { 64 | memcpy(dst + len1, src, len2); 65 | dst[len1 + len2] = '\0'; 66 | } 67 | 68 | return ret; 69 | } 70 | #endif 71 | 72 | /* 73 | * Removes any new-line or carriage-return characters from the end of the 74 | * string. This function is named after the same function in Perl. 75 | * "length" should be the number of characters in the buffer, not including 76 | * the trailing NULL. 77 | * 78 | * Returns the number of characters removed from the end of the string. A 79 | * negative return value indicates an error. 80 | */ 81 | ssize_t 82 | chomp(char *buffer, size_t length) 83 | { 84 | size_t chars; 85 | 86 | assert(buffer != NULL); 87 | assert(length > 0); 88 | 89 | /* Make sure the arguments are valid */ 90 | if (buffer == NULL) return -EFAULT; 91 | if (length < 1) return -ERANGE; 92 | 93 | chars = 0; 94 | 95 | --length; 96 | while (buffer[length] == '\r' || buffer[length] == '\n') { 97 | buffer[length] = '\0'; 98 | chars++; 99 | 100 | /* Stop once we get to zero to prevent wrap-around */ 101 | if (length-- == 0) break; 102 | } 103 | 104 | return chars; 105 | } 106 | -------------------------------------------------------------------------------- /src/text.h: -------------------------------------------------------------------------------- 1 | /* $Id: text.h,v 1.2 2003/03/13 05:20:06 rjkaes Exp $ 2 | * 3 | * See 'text.c' for a detailed description. 4 | * 5 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify it 8 | * under the terms of the GNU General Public License as published by the 9 | * Free Software Foundation; either version 2, or (at your option) any 10 | * later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, but 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | */ 17 | 18 | #ifndef TINYPROXY_TEXT_H 19 | #define TINYPROXY_TEXT_H 20 | 21 | #ifndef HAVE_STRLCAT 22 | extern size_t strlcat(char *dst, const char *src, size_t size); 23 | #endif /* HAVE_STRLCAT */ 24 | 25 | #ifndef HAVE_STRLCPY 26 | extern size_t strlcpy(char *dst, const char *src, size_t size); 27 | #endif /* HAVE_STRLCPY */ 28 | 29 | extern ssize_t chomp(char *buffer, size_t length); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/tinyproxy.h: -------------------------------------------------------------------------------- 1 | /* $Id: tinyproxy.h,v 1.41.2.1 2004/08/06 16:56:55 rjkaes Exp $ 2 | * 3 | * See 'tinyproxy.c' for a detailed description. 4 | * 5 | * Copyright (C) 1998 Steven Young 6 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #ifndef TINYPROXY_TINYPROXY_H 20 | #define TINYPROXY_TINYPROXY_H 21 | 22 | #include "common.h" 23 | 24 | /* Global variables for the main controls of the program */ 25 | #define MAXBUFFSIZE ((size_t)(1024 * 96)) /* Max size of buffer */ 26 | #define MAX_IDLE_TIME (60 * 10) /* 10 minutes of no activity */ 27 | 28 | /* 29 | * Even if upstream support is not compiled into tinyproxy, this 30 | * structure still needs to be defined. 31 | */ 32 | typedef enum {HTTP_TYPE, SOCKS4_TYPE, SOCKS5_TYPE} proxy_type; 33 | struct upstream { 34 | struct upstream *next; 35 | char *domain; /* optional */ 36 | char *host; 37 | int port; 38 | in_addr_t ip, mask; 39 | proxy_type type; 40 | }; 41 | 42 | struct config_s { 43 | char *logf_name; 44 | char *config_file; 45 | unsigned int syslog; /* boolean */ 46 | int port; 47 | char *stathost; 48 | unsigned int quit; /* boolean */ 49 | char *username; 50 | char *group; 51 | char *ipAddr; 52 | #ifdef FILTER_ENABLE 53 | char *filter; 54 | unsigned int filter_url; /* boolean */ 55 | unsigned int filter_extended; /* boolean */ 56 | unsigned int filter_casesensitive; /* boolean */ 57 | #endif /* FILTER_ENABLE */ 58 | #ifdef XTINYPROXY_ENABLE 59 | char *my_domain; 60 | #endif 61 | #ifdef UPSTREAM_SUPPORT 62 | struct upstream *upstream_list; 63 | #endif /* UPSTREAM_SUPPORT */ 64 | char *pidpath; 65 | unsigned int idletimeout; 66 | char* bind_address; 67 | 68 | /* 69 | * The configured name to use in the HTTP "Via" header field. 70 | */ 71 | char* via_proxy_name; 72 | 73 | /* 74 | * Error page support. This is an array of pointers to structures 75 | * which describe the error page path, and what HTTP error it handles. 76 | * an example would be { "/usr/local/etc/tinyproxy/404.html", 404 } 77 | * Ending of array is noted with NULL, 0. 78 | */ 79 | struct error_pages_s { 80 | char *errorpage_path; 81 | unsigned int errorpage_errnum; 82 | } **errorpages; 83 | /* 84 | * Error page to be displayed if appropriate page cannot be located 85 | * in the errorpages structure. 86 | */ 87 | char *errorpage_undef; 88 | 89 | /* 90 | * The HTML statistics page. 91 | */ 92 | char *statpage; 93 | 94 | char *vpnHost; 95 | int vpnPort; 96 | }; 97 | 98 | /* Global Structures used in the program */ 99 | extern struct config_s config; 100 | extern unsigned int received_sighup; /* boolean */ 101 | extern unsigned int processed_config_file; /* boolean */ 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | /* $Id: utils.c,v 1.38 2003/03/14 06:15:27 rjkaes Exp $ 2 | * 3 | * Misc. routines which are used by the various functions to handle strings 4 | * and memory allocation and pretty much anything else we can think of. Also, 5 | * the load cutoff routine is in here. Could not think of a better place for 6 | * it, so it's in here. 7 | * 8 | * Copyright (C) 1998 Steven Young 9 | * Copyright (C) 1999,2001,2003 by 10 | * Robert James Kaes (rjkaes@flarenet.com) 11 | * 12 | * This program is free software; you can redistribute it and/or modify it 13 | * under the terms of the GNU General Public License as published by the 14 | * Free Software Foundation; either version 2, or (at your option) any 15 | * later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, but 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | * General Public License for more details. 21 | */ 22 | 23 | #include "tinyproxy.h" 24 | 25 | #include "conns.h" 26 | #include "heap.h" 27 | #include "http_message.h" 28 | #include "utils.h" 29 | 30 | /* 31 | * Build the data for a complete HTTP & HTML message for the client. 32 | */ 33 | int 34 | send_http_message(struct conn_s *connptr, int http_code, 35 | const char *error_title, const char *message) 36 | { 37 | static char* headers[] = { 38 | "Server: " PACKAGE "/" VERSION, 39 | "Content-type: text/html", 40 | "Connection: close" 41 | }; 42 | 43 | http_message_t msg; 44 | 45 | msg = http_message_create(http_code, error_title); 46 | if (msg == NULL) 47 | return -1; 48 | 49 | http_message_add_headers(msg, headers, 3); 50 | http_message_set_body(msg, message, strlen(message)); 51 | http_message_send(msg, connptr->client_fd); 52 | http_message_destroy(msg); 53 | 54 | return 0; 55 | } 56 | 57 | /* 58 | * Safely creates filename and returns the low-level file descriptor. 59 | */ 60 | int 61 | create_file_safely(const char *filename, unsigned int truncate_file) 62 | { 63 | struct stat lstatinfo; 64 | int fildes; 65 | 66 | /* 67 | * lstat() the file. If it doesn't exist, create it with O_EXCL. 68 | * If it does exist, open it for writing and perform the fstat() 69 | * check. 70 | */ 71 | if (lstat(filename, &lstatinfo) < 0) { 72 | /* 73 | * If lstat() failed for any reason other than "file not 74 | * existing", exit. 75 | */ 76 | if (errno != ENOENT) { 77 | fprintf(stderr, 78 | "%s: Error checking file %s: %s\n", 79 | PACKAGE, filename, strerror(errno)); 80 | return -EACCES; 81 | } 82 | 83 | /* 84 | * The file doesn't exist, so create it with O_EXCL to make 85 | * sure an attacker can't slip in a file between the lstat() 86 | * and open() 87 | */ 88 | if ((fildes = 89 | open(filename, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) { 90 | fprintf(stderr, 91 | "%s: Could not create file %s: %s\n", 92 | PACKAGE, filename, strerror(errno)); 93 | return fildes; 94 | } 95 | } else { 96 | struct stat fstatinfo; 97 | int flags; 98 | 99 | flags = O_RDWR; 100 | if (!truncate_file) 101 | flags |= O_APPEND; 102 | 103 | /* 104 | * Open an existing file. 105 | */ 106 | if ((fildes = open(filename, flags)) < 0) { 107 | fprintf(stderr, 108 | "%s: Could not open file %s: %s\n", 109 | PACKAGE, filename, strerror(errno)); 110 | return fildes; 111 | } 112 | 113 | /* 114 | * fstat() the opened file and check that the file mode bits, 115 | * inode, and device match. 116 | */ 117 | if (fstat(fildes, &fstatinfo) < 0 118 | || lstatinfo.st_mode != fstatinfo.st_mode 119 | || lstatinfo.st_ino != fstatinfo.st_ino 120 | || lstatinfo.st_dev != fstatinfo.st_dev) { 121 | fprintf(stderr, 122 | "%s: The file %s has been changed before it could be opened\n", 123 | PACKAGE, filename); 124 | close(fildes); 125 | return -EIO; 126 | } 127 | 128 | /* 129 | * If the above check was passed, we know that the lstat() 130 | * and fstat() were done on the same file. Now we check that 131 | * there's only one link, and that it's a normal file (this 132 | * isn't strictly necessary because the fstat() vs lstat() 133 | * st_mode check would also find this) 134 | */ 135 | if (fstatinfo.st_nlink > 1 || !S_ISREG(lstatinfo.st_mode)) { 136 | fprintf(stderr, 137 | "%s: The file %s has too many links, or is not a regular file: %s\n", 138 | PACKAGE, filename, strerror(errno)); 139 | close(fildes); 140 | return -EMLINK; 141 | } 142 | 143 | /* 144 | * Just return the file descriptor if we _don't_ want the file 145 | * truncated. 146 | */ 147 | if (!truncate_file) 148 | return fildes; 149 | 150 | /* 151 | * On systems which don't support ftruncate() the best we can 152 | * do is to close the file and reopen it in create mode, which 153 | * unfortunately leads to a race condition, however "systems 154 | * which don't support ftruncate()" is pretty much SCO only, 155 | * and if you're using that you deserve what you get. 156 | * ("Little sympathy has been extended") 157 | */ 158 | #ifdef HAVE_FTRUNCATE 159 | ftruncate(fildes, 0); 160 | #else 161 | close(fildes); 162 | if ((fildes = 163 | open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) { 164 | fprintf(stderr, 165 | "%s: Could not open file %s: %s.", 166 | PACKAGE, filename, strerror(errno)); 167 | return fildes; 168 | } 169 | #endif /* HAVE_FTRUNCATE */ 170 | } 171 | 172 | return fildes; 173 | } 174 | 175 | /* 176 | * Write the PID of the program to the specified file. 177 | */ 178 | int 179 | pidfile_create(const char *filename) 180 | { 181 | int fildes; 182 | FILE *fd; 183 | 184 | /* 185 | * Create a new file 186 | */ 187 | if ((fildes = create_file_safely(filename, TRUE)) < 0) 188 | return fildes; 189 | 190 | /* 191 | * Open a stdio file over the low-level one. 192 | */ 193 | if ((fd = fdopen(fildes, "w")) == NULL) { 194 | fprintf(stderr, 195 | "%s: Could not write PID file %s: %s.", 196 | PACKAGE, filename, strerror(errno)); 197 | close(fildes); 198 | unlink(filename); 199 | return -EIO; 200 | } 201 | 202 | fprintf(fd, "%ld\n", (long) getpid()); 203 | fclose(fd); 204 | return 0; 205 | } 206 | -------------------------------------------------------------------------------- /src/utils.h: -------------------------------------------------------------------------------- 1 | /* $Id: utils.h,v 1.23 2003/03/13 21:34:37 rjkaes Exp $ 2 | * 3 | * See 'utils.h' for a detailed description. 4 | * 5 | * Copyright (C) 1998 Steven Young 6 | * Copyright (C) 1999 Robert James Kaes (rjkaes@flarenet.com) 7 | * 8 | * This program is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU General Public License as published by the 10 | * Free Software Foundation; either version 2, or (at your option) any 11 | * later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | */ 18 | 19 | #ifndef TINYPROXY_UTILS_H 20 | #define TINYPROXY_UTILS_H 21 | 22 | /* 23 | * Forward declaration. 24 | */ 25 | struct conn_s; 26 | 27 | extern int send_http_message(struct conn_s *connptr, int http_code, 28 | const char *error_title, const char *message); 29 | 30 | extern int pidfile_create(const char *path); 31 | extern int create_file_safely(const char *filename, unsigned int truncate_file); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/vector.c: -------------------------------------------------------------------------------- 1 | /* $Id: vector.c,v 1.9 2003/05/30 16:21:48 rjkaes Exp $ 2 | * 3 | * A vector implementation. The vector can be of an arbitrary length, and 4 | * the data for each entry is an lump of data (the size is stored in the 5 | * vector.) 6 | * 7 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #include "tinyproxy.h" 25 | 26 | #include "heap.h" 27 | #include "vector.h" 28 | 29 | /* 30 | * These structures are the storage for the "vector". Entries are 31 | * stored in struct vectorentry_s (the data and the length), and the 32 | * "vector" structure is implemented as a linked-list. The struct 33 | * vector_s stores a pointer to the first vector (vector[0]) and a 34 | * count of the number of entries (or how long the vector is.) 35 | */ 36 | struct vectorentry_s { 37 | void *data; 38 | size_t len; 39 | 40 | struct vectorentry_s *next; 41 | }; 42 | 43 | struct vector_s { 44 | size_t num_entries; 45 | struct vectorentry_s *head; 46 | struct vectorentry_s *tail; 47 | }; 48 | 49 | /* 50 | * Create an vector. The vector initially has no elements and no 51 | * storage has been allocated for the entries. 52 | * 53 | * A NULL is returned if memory could not be allocated for the 54 | * vector. 55 | */ 56 | vector_t 57 | vector_create(void) 58 | { 59 | vector_t vector; 60 | 61 | vector = safemalloc(sizeof(struct vector_s)); 62 | if (!vector) 63 | return NULL; 64 | 65 | vector->num_entries = 0; 66 | vector->head = vector->tail = NULL; 67 | 68 | return vector; 69 | } 70 | 71 | /* 72 | * Deletes an vector. All the entries when this function is run. 73 | * 74 | * Returns: 0 on success 75 | * negative if a NULL vector is supplied 76 | */ 77 | int 78 | vector_delete(vector_t vector) 79 | { 80 | struct vectorentry_s *ptr, *next; 81 | 82 | if (!vector) 83 | return -EINVAL; 84 | 85 | ptr = vector->head; 86 | while (ptr) { 87 | next = ptr->next; 88 | safefree(ptr->data); 89 | safefree(ptr); 90 | 91 | ptr = next; 92 | } 93 | 94 | safefree(vector); 95 | 96 | return 0; 97 | } 98 | 99 | /* 100 | * Appends an entry into the vector. The entry is an arbitrary 101 | * collection of bytes of _len_ octets. The data is copied into the 102 | * vector, so the original data must be freed to avoid a memory leak. 103 | * The "data" must be non-NULL and the "len" must be greater than zero. 104 | * "pos" is either 0 to prepend the data, or 1 to append the data. 105 | * 106 | * Returns: 0 on success 107 | * negative number if there are errors 108 | */ 109 | #define INSERT_PREPEND 0 110 | #define INSERT_APPEND 1 111 | 112 | static int 113 | vector_insert(vector_t vector, void *data, ssize_t len, int pos) 114 | { 115 | struct vectorentry_s *entry; 116 | 117 | if (!vector || !data || len <= 0 || 118 | (pos != INSERT_PREPEND && pos != INSERT_APPEND)) 119 | return -EINVAL; 120 | 121 | entry = safemalloc(sizeof(struct vectorentry_s)); 122 | if (!entry) 123 | return -ENOMEM; 124 | 125 | entry->data = safemalloc(len); 126 | if (!entry->data) { 127 | safefree(entry); 128 | return -ENOMEM; 129 | } 130 | 131 | memcpy(entry->data, data, len); 132 | entry->len = len; 133 | entry->next = NULL; 134 | 135 | /* If there is no head or tail, create them */ 136 | if (!vector->head && !vector->tail) 137 | vector->head = vector->tail = entry; 138 | else if (pos == 0) { 139 | /* prepend the entry */ 140 | entry->next = vector->head; 141 | vector->head = entry; 142 | } else { 143 | /* append the entry */ 144 | vector->tail->next = entry; 145 | vector->tail = entry; 146 | } 147 | 148 | vector->num_entries++; 149 | 150 | return 0; 151 | } 152 | 153 | /* 154 | * The following two function are used to make the API clearer. As you 155 | * can see they simply call the vector_insert() function with appropriate 156 | * arguments. 157 | */ 158 | int 159 | vector_append(vector_t vector, void *data, ssize_t len) 160 | { 161 | return vector_insert(vector, data, len, INSERT_APPEND); 162 | } 163 | 164 | int 165 | vector_prepend(vector_t vector, void *data, ssize_t len) 166 | { 167 | return vector_insert(vector, data, len, INSERT_PREPEND); 168 | } 169 | 170 | /* 171 | * A pointer to the data at position "pos" (zero based) is returned. 172 | * If the vector is out of bound, data is set to NULL. 173 | * 174 | * Returns: negative upon an error 175 | * length of data if position is valid 176 | */ 177 | void * 178 | vector_getentry(vector_t vector, size_t pos, size_t* size) 179 | { 180 | struct vectorentry_s *ptr; 181 | size_t loc; 182 | 183 | if (!vector || pos < 0 || pos >= vector->num_entries) 184 | return NULL; 185 | 186 | loc = 0; 187 | ptr = vector->head; 188 | 189 | while (loc != pos) { 190 | ptr = ptr->next; 191 | loc++; 192 | } 193 | 194 | if (size) 195 | *size = ptr->len; 196 | 197 | return ptr->data; 198 | } 199 | 200 | /* 201 | * Returns the number of entries (or the length) of the vector. 202 | * 203 | * Returns: negative if vector is not valid 204 | * positive length of vector otherwise 205 | */ 206 | ssize_t 207 | vector_length(vector_t vector) 208 | { 209 | if (!vector) 210 | return -EINVAL; 211 | 212 | return vector->num_entries; 213 | } 214 | -------------------------------------------------------------------------------- /src/vector.h: -------------------------------------------------------------------------------- 1 | /* $Id: vector.h,v 1.4.2.1 2003/08/06 20:46:04 rjkaes Exp $ 2 | * 3 | * A vector implementation. The vector can be of an arbritrary length, and 4 | * the data for each entry is an lump of data (the size is stored in the 5 | * vector.) 6 | * 7 | * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 2 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with this program; if not, write to the Free Software 21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | 24 | #ifndef _VECTOR_H 25 | #define _VECTOR_H 26 | 27 | /* Allow the use in C++ code. */ 28 | #if defined(__cplusplus) 29 | extern "C" { 30 | #endif 31 | 32 | /* 33 | * We're using a typedef here to "hide" the implementation details of the 34 | * vector. Sure, it's a pointer, but the struct is hidden in the C file. 35 | * So, just use the vector_t like it's a cookie. :) 36 | */ 37 | typedef struct vector_s *vector_t; 38 | 39 | /* 40 | * vector_create() takes no arguments. 41 | * vector_delete() is self explanatory. 42 | */ 43 | extern vector_t vector_create(void); 44 | extern int vector_delete(vector_t vector); 45 | 46 | /* 47 | * When you insert a piece of data into the vector, the data will be 48 | * duplicated, so you must free your copy if it was created on the heap. 49 | * The data must be non-NULL and the length must be greater than zero. 50 | * 51 | * Returns: negative on error 52 | * 0 upon successful insert. 53 | */ 54 | extern int vector_append(vector_t vector, void *data, ssize_t len); 55 | extern int vector_prepend(vector_t vector, void *data, ssize_t len); 56 | 57 | /* 58 | * A pointer to the data at position "pos" (zero based) is returned and the 59 | * size pointer contains the length of the data stored. 60 | * 61 | * The pointer points to the actual data in the vector, so you have 62 | * the power to modify the data, but do it responsibly since the 63 | * library doesn't take any steps to prevent you from messing up the 64 | * vector. (A better rule is, don't modify the data since you'll 65 | * likely mess up the "length" parameter of the data.) However, DON'T 66 | * try to realloc or free the data; doing so will break the vector. 67 | * 68 | * If "size" is NULL the size of the data is not returned. 69 | * 70 | * Returns: NULL on error 71 | * valid pointer to data 72 | */ 73 | extern void* vector_getentry(vector_t vector, size_t pos, size_t* size); 74 | 75 | /* 76 | * Returns the number of enteries (or the length) of the vector. 77 | * 78 | * Returns: negative if vector is not valid 79 | * positive length of vector otherwise 80 | */ 81 | extern ssize_t vector_length(vector_t vector); 82 | 83 | #if defined(__cplusplus) 84 | } 85 | #endif /* C++ */ 86 | 87 | #endif /* _VECTOR_H */ 88 | -------------------------------------------------------------------------------- /stamp-h.in: -------------------------------------------------------------------------------- 1 | timestamp 2 | -------------------------------------------------------------------------------- /tiny/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | MODULE=tiny 4 | 5 | cd / 6 | cp -f /tmp/$MODULE/tinyproxy /koolshare/bin/ 7 | cp -f /tmp/$MODULE/tiny.sh /koolshare/scripts/ 8 | cp -f /tmp/$MODULE/tinyproxy.conf /koolshare/configs/ 9 | 10 | cd /koolshare/init.d/ 11 | rm -f ./S90tiny.sh 12 | ln -sf /koolshare/scripts/tiny.sh ./S90tiny.sh 13 | cd / 14 | 15 | rm -f /tmp/tiny* >/dev/null 2>&1 16 | rm -rf /tmp/tiny >/dev/null 2>&1 17 | 18 | chmod 755 /koolshare/bin/tinyproxy 19 | chmod 755 /koolshare/scripts/tiny.sh 20 | 21 | -------------------------------------------------------------------------------- /tiny/tiny.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | source /koolshare/scripts/base.sh 4 | 5 | start_http(){ 6 | sleep 1 7 | tinyproxy -c /koolshare/configs/tinyproxy.conf 8 | } 9 | 10 | case $ACTION in 11 | start) 12 | start_http 13 | ;; 14 | stop | kill ) 15 | killall tinyproxy 16 | ;; 17 | restart) 18 | killall tinyproxy 19 | sleep 1 20 | start_http 21 | ;; 22 | *) 23 | echo "Usage: $0 (start|stop|restart)" 24 | exit 1 25 | ;; 26 | esac 27 | -------------------------------------------------------------------------------- /tiny/tinyproxy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/koolshare/tinyproxy/959d3faa9267893c576013ae05a7ae5a404bab5c/tiny/tinyproxy -------------------------------------------------------------------------------- /tiny/tinyproxy.conf: -------------------------------------------------------------------------------- 1 | ## 2 | ## tinyproxy.conf -- tinyproxy daemon configuration file 3 | ## 4 | 5 | # 6 | # Name of the user the tinyproxy daemon should switch to after the port 7 | # has been bound. 8 | # 9 | #User root 10 | #Group root 11 | 12 | # 13 | # Port to listen on. 14 | # 15 | Port 8888 16 | 17 | # 18 | # If you have multiple interfaces this allows you to bind to only one. If 19 | # this is commented out, tinyproxy will bind to all interfaces present. 20 | # 21 | #Listen 192.168.0.1 22 | 23 | # 24 | # The Bind directive allows you to bind the outgoing connections to a 25 | # particular IP address. 26 | # 27 | #Bind 192.168.0.1 28 | 29 | # 30 | # Timeout: The number of seconds of inactivity a connection is allowed to 31 | # have before it closed by tinyproxy. 32 | # 33 | Timeout 600 34 | 35 | # 36 | # ErrorFile: Defines the HTML file to send when a given HTTP error 37 | # occurs. You will probably need to customize the location to your 38 | # particular install. The usual locations to check are: 39 | # /usr/local/share/tinyproxy 40 | # /usr/share/tinyproxy 41 | # /etc/tinyproxy 42 | # 43 | # ErrorFile 404 "/usr/share/tinyproxy/404.html" 44 | # ErrorFile 400 "/usr/share/tinyproxy/400.html" 45 | # ErrorFile 503 "/usr/share/tinyproxy/503.html" 46 | # ErrorFile 403 "/usr/share/tinyproxy/403.html" 47 | # ErrorFile 408 "/usr/share/tinyproxy/408.html" 48 | 49 | # 50 | # DefaultErrorFile: The HTML file that gets sent if there is no 51 | # HTML file defined with an ErrorFile keyword for the HTTP error 52 | # that has occured. 53 | # 54 | DefaultErrorFile "/usr/share/tinyproxy/default.html" 55 | 56 | # 57 | # StatFile: The HTML file that gets sent when a request is made 58 | # for the stathost. If this file doesn't exist a basic page is 59 | # hardcoded in tinyproxy. 60 | # 61 | StatFile "/usr/share/tinyproxy/stats.html" 62 | 63 | # 64 | # Where to log the information. Either LogFile or Syslog should be set, 65 | # but not both. 66 | # 67 | #Logfile "/var/log/tinyproxy.log" 68 | Syslog On 69 | 70 | # 71 | # Set the logging level. Allowed settings are: 72 | # Critical (least verbose) 73 | # Error 74 | # Warning 75 | # Notice 76 | # Connect (to log connections without Info's noise) 77 | # Info (most verbose) 78 | # The LogLevel logs from the set level and above. For example, if the LogLevel 79 | # was set to Warning, than all log messages from Warning to Critical would be 80 | # output, but Notice and below would be suppressed. 81 | # 82 | LogLevel Error 83 | 84 | # 85 | # PidFile: Write the PID of the main tinyproxy thread to this file so it 86 | # can be used for signalling purposes. 87 | # 88 | PidFile "/var/run/tinyproxy.pid" 89 | 90 | # 91 | # Include the X-Tinyproxy header, which has the client's IP address when 92 | # connecting to the sites listed. 93 | # 94 | #XTinyproxy mydomain.com 95 | 96 | # 97 | # Turns on upstream proxy support. 98 | # 99 | # The upstream rules allow you to selectively route upstream connections 100 | # based on the host/domain of the site being accessed. 101 | # 102 | # For example: 103 | # # connection to test domain goes through testproxy 104 | # upstream testproxy:8008 ".test.domain.invalid" 105 | # upstream testproxy:8008 ".our_testbed.example.com" 106 | # upstream testproxy:8008 "192.168.128.0/255.255.254.0" 107 | # 108 | # # no upstream proxy for internal websites and unqualified hosts 109 | # no upstream ".internal.example.com" 110 | # no upstream "www.example.com" 111 | # no upstream "10.0.0.0/8" 112 | # no upstream "192.168.0.0/255.255.254.0" 113 | # no upstream "." 114 | # 115 | # # connection to these boxes go through their DMZ firewalls 116 | # upstream cust1_firewall:8008 "testbed_for_cust1" 117 | # upstream cust2_firewall:8008 "testbed_for_cust2" 118 | # 119 | # # default upstream is internet firewall 120 | # upstream firewall.internal.example.com:80 121 | # 122 | # The LAST matching rule wins the route decision. As you can see, you 123 | # can use a host, or a domain: 124 | # name matches host exactly 125 | # .name matches any host in domain "name" 126 | # . matches any host with no domain (in 'empty' domain) 127 | # IP/bits matches network/mask 128 | # IP/mask matches network/mask 129 | # 130 | Upstream socks5 127.0.0.1:23456 131 | 132 | # 133 | # This is the absolute highest number of threads which will be created. In 134 | # other words, only MaxClients number of clients can be connected at the 135 | # same time. 136 | # 137 | MaxClients 100 138 | 139 | # 140 | # These settings set the upper and lower limit for the number of 141 | # spare servers which should be available. If the number of spare servers 142 | # falls below MinSpareServers then new ones will be created. If the number 143 | # of servers exceeds MaxSpareServers then the extras will be killed off. 144 | # 145 | MinSpareServers 5 146 | MaxSpareServers 20 147 | 148 | # 149 | # Number of servers to start initially. 150 | # 151 | StartServers 10 152 | 153 | # 154 | # MaxRequestsPerChild is the number of connections a thread will handle 155 | # before it is killed. In practise this should be set to 0, which disables 156 | # thread reaping. If you do notice problems with memory leakage, then set 157 | # this to something like 10000 158 | # 159 | MaxRequestsPerChild 0 160 | 161 | # 162 | # The following is the authorization controls. If there are any access 163 | # control keywords then the default action is to DENY. Otherwise, the 164 | # default action is ALLOW. 165 | # 166 | # Also the order of the controls are important. The incoming connections 167 | # are tested against the controls based on order. 168 | # 169 | #Allow 127.0.0.1 170 | #Allow 192.168.1.0/25 171 | 172 | # 173 | # The "Via" header is required by the HTTP RFC, but using the real host name 174 | # is a security concern. If the following directive is enabled, the string 175 | # supplied will be used as the host name in the Via header; otherwise, the 176 | # server's host name will be used. 177 | # 178 | ViaProxyName "tinyproxy" 179 | 180 | # 181 | # The location of the filter file. 182 | # 183 | #Filter "/etc/tinyproxy/filter" 184 | 185 | # 186 | # Filter based on URLs rather than domains. 187 | # 188 | #FilterURLs On 189 | 190 | # 191 | # Use POSIX Extended regular expressions rather than basic. 192 | # 193 | #FilterExtended On 194 | 195 | # 196 | # Use case sensitive regular expressions. 197 | # 198 | #FilterCaseSensitive On 199 | 200 | # 201 | # Change the default policy of the filtering system. If this directive is 202 | # commented out, or is set to "No" then the default policy is to allow 203 | # everything which is not specifically denied by the filter file. 204 | # 205 | # However, by setting this directive to "Yes" the default policy becomes to 206 | # deny everything which is _not_ specifically allowed by the filter file. 207 | # 208 | #FilterDefaultDeny Yes 209 | 210 | # 211 | # If an Anonymous keyword is present, then anonymous proxying is enabled. 212 | # The headers listed are allowed through, while all others are denied. If 213 | # no Anonymous keyword is present, then all header are allowed through. 214 | # You must include quotes around the headers. 215 | # 216 | #Anonymous "Host" 217 | #Anonymous "Authorization" 218 | 219 | # 220 | # This is a list of ports allowed by tinyproxy when the CONNECT method 221 | # is used. To disable the CONNECT method altogether, set the value to 0. 222 | # If no ConnectPort line is found, all ports are allowed (which is not 223 | # very secure.) 224 | # 225 | # The following two ports are used by SSL. 226 | # 227 | ConnectPort 443 228 | ConnectPort 563 229 | --------------------------------------------------------------------------------