diff --git a/Dockerfile b/Dockerfile index 5baa909..e9d005d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,29 @@ -FROM jaschac/debian-gcc +FROM alpine:3.4 MAINTAINER Jascha Casadio + +RUN apk update \ + && apk upgrade \ + && apk add g++ \ + make \ + curl \ + bash \ + autoconf \ + && mkdir -p /usr/local/src/ \ + && cd /usr/local/src/ \ + && curl -L -O http://downloads.sourceforge.net/sourceforge/cntlm/cntlm-0.92.3.tar.gz \ + && tar zxvf cntlm-0.92.3.tar.gz \ + && cd cntlm-0.92.3 \ + && ./configure \ + && make \ + && make install \ + && rm /usr/local/src/cntlm-0.92.3.tar.gz \ + && apk del curl \ + g++ \ + autoconf \ + make \ + && rm -rf /var/lib/apt/lists/* + ADD scripts/init_container.sh /usr/local/sbin/init_container.sh ADD files/etc/cntlm.conf /etc/cntlm.conf -ADD files/cntlm-0.92.3/ /usr/local/src/cntlm-0.92.3/ EXPOSE 3128 CMD init_container.sh diff --git a/README b/README deleted file mode 100644 index 95053db..0000000 --- a/README +++ /dev/null @@ -1 +0,0 @@ -See README.md. diff --git a/files/cntlm-0.92.3/COPYRIGHT b/files/cntlm-0.92.3/COPYRIGHT deleted file mode 100644 index bf952e7..0000000 --- a/files/cntlm-0.92.3/COPYRIGHT +++ /dev/null @@ -1,21 +0,0 @@ - CNTLM - Authenticating HTTP Proxy - Copyright (C) 2007-2010 David Kubicek - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - If you would like to negotiate alternate licensing terms, you may do - so by contacting: David Kubicek , - - diff --git a/files/cntlm-0.92.3/LICENSE b/files/cntlm-0.92.3/LICENSE deleted file mode 100644 index d60c31a..0000000 --- a/files/cntlm-0.92.3/LICENSE +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/files/cntlm-0.92.3/Makefile b/files/cntlm-0.92.3/Makefile deleted file mode 100644 index df253ce..0000000 --- a/files/cntlm-0.92.3/Makefile +++ /dev/null @@ -1,146 +0,0 @@ -# -# You can tweak these three variables to make things install where you -# like, but do not touch more unless you know what you are doing. ;) -# -DESTDIR= -SYSCONFDIR=$(DESTDIR)/etc -BINDIR=$(DESTDIR)/usr/sbin -MANDIR=$(DESTDIR)/usr/share/man - -# -# Careful now... -# __BSD_VISIBLE is for FreeBSD AF_* constants -# _ALL_SOURCE is for AIX 5.3 LOG_PERROR constant -# -NAME=cntlm -CC=gcc -VER=`cat VERSION` -CFLAGS+=$(FLAGS) -std=c99 -Wall -Wno-unused-but-set-variable -pedantic -O3 -D__BSD_VISIBLE -D_ALL_SOURCE -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112 -D_ISOC99_SOURCE -D_REENTRANT -D_BSD_SOURCE -DVERSION=\"`cat VERSION`\" -OS=$(shell uname -s) -OSLDFLAGS=$(shell [ $(OS) = "SunOS" ] && echo "-lrt -lsocket -lnsl") -LDFLAGS:=-lpthread $(OSLDFLAGS) - -ifeq ($(findstring CYGWIN,$(OS)),) - OBJS=utils.o ntlm.o xcrypt.o config.o socket.o acl.o auth.o http.o forward.o direct.o scanner.o pages.o main.o -else - OBJS=utils.o ntlm.o xcrypt.o config.o socket.o acl.o auth.o http.o forward.o direct.o scanner.o pages.o main.o win/resources.o -endif - -$(NAME): configure-stamp $(OBJS) - @echo "Linking $@" - @$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -main.o: main.c - @echo "Compiling $<" - @if [ -z "$(SYSCONFDIR)" ]; then \ - $(CC) $(CFLAGS) -c main.c -o $@; \ - else \ - $(CC) $(CFLAGS) -DSYSCONFDIR=\"$(SYSCONFDIR)\" -c main.c -o $@; \ - fi - -.c.o: - @echo "Compiling $<" - @$(CC) $(CFLAGS) -c -o $@ $< - -install: $(NAME) - # Special handling for install(1) - if [ "`uname -s`" = "AIX" ]; then \ - install -M 755 -S -f $(BINDIR) $(NAME); \ - install -M 644 -f $(MANDIR)/man1 doc/$(NAME).1; \ - install -M 600 -c $(SYSCONFDIR) doc/$(NAME).conf; \ - elif [ "`uname -s`" = "Darwin" ]; then \ - install -d -m 755 -s $(NAME) $(BINDIR)/$(NAME); \ - install -d -m 644 doc/$(NAME).1 $(MANDIR)/man1/$(NAME).1; \ - [ -f $(SYSCONFDIR)/$(NAME).conf -o -z "$(SYSCONFDIR)" ] \ - || install -d -m 600 doc/$(NAME).conf $(SYSCONFDIR)/$(NAME).conf; \ - else \ - install -D -m 755 -s $(NAME) $(BINDIR)/$(NAME); \ - install -D -m 644 doc/$(NAME).1 $(MANDIR)/man1/$(NAME).1; \ - [ -f $(SYSCONFDIR)/$(NAME).conf -o -z "$(SYSCONFDIR)" ] \ - || install -D -m 600 doc/$(NAME).conf $(SYSCONFDIR)/$(NAME).conf; \ - fi - @echo; echo "Cntlm will look for configuration in $(SYSCONFDIR)/$(NAME).conf" - -tgz: - mkdir -p tmp - rm -rf tmp/$(NAME)-$(VER) - svn export . tmp/$(NAME)-$(VER) - tar zcvf $(NAME)-$(VER).tar.gz -C tmp/ $(NAME)-$(VER) - rm -rf tmp/$(NAME)-$(VER) - rmdir tmp 2>/dev/null || true - -tbz2: - mkdir -p tmp - rm -rf tmp/$(NAME)-$(VER) - svn export . tmp/$(NAME)-$(VER) - tar jcvf $(NAME)-$(VER).tar.bz2 -C tmp/ $(NAME)-$(VER) - rm -rf tmp/$(NAME)-$(VER) - rmdir tmp 2>/dev/null || true - -deb: builddeb -builddeb: - sed -i "s/^\(cntlm *\)([^)]*)/\1($(VER))/g" debian/changelog - if [ `id -u` = 0 ]; then \ - debian/rules binary; \ - debian/rules clean; \ - else \ - fakeroot debian/rules binary; \ - fakeroot debian/rules clean; \ - fi - mv ../cntlm_$(VER)*.deb . - -rpm: buildrpm -buildrpm: - sed -i "s/^\(Version:[\t ]*\)\(.*\)/\1$(VER)/g" rpm/cntlm.spec - if [ `id -u` = 0 ]; then \ - rpm/rules binary; \ - rpm/rules clean; \ - else \ - fakeroot rpm/rules binary; \ - fakeroot rpm/rules clean; \ - fi - -win: buildwin -buildwin: - @echo - @echo "* This build target must be run from a Cywgin shell on Windows *" - @echo "* and you also need InnoSetup installed *" - @echo - rm -f win/cntlm_manual.pdf - groff -t -e -mandoc -Tps doc/cntlm.1 | ps2pdf - win/cntlm_manual.pdf - cat doc/cntlm.conf | unix2dos > win/cntlm.ini - cat COPYRIGHT LICENSE | unix2dos > win/license.txt - sed "s/\$$VERSION/$(VER)/g" win/setup.iss.in > win/setup.iss - cp /bin/cygwin1.dll /bin/cyggcc_s-1.dll /bin/cygrunsrv.exe win/ - cp cntlm.exe win/ - strip win/cntlm.exe - ln -s win $(NAME)-$(VER) - zip -9 $(NAME)-$(VER).zip $(NAME)-$(VER)/cntlm.exe $(NAME)-$(VER)/cyggcc_s-1.dll $(NAME)-$(VER)/cygwin1.dll $(NAME)-$(VER)/cygrunsrv.exe $(NAME)-$(VER)/cntlm.ini $(NAME)-$(VER)/README.txt $(NAME)-$(VER)/license.txt - rm -f $(NAME)-$(VER) - @echo - @echo Now open folder "win", right-click "setup.iss", then "Compile". - @echo InnoSetup will generate a new installer cntlm-X.XX-setup.exe - @echo - -win/resources.o: win/resources.rc - @echo Adding EXE resources - @windres $^ -o $@ - -uninstall: - rm -f $(BINDIR)/$(NAME) $(MANDIR)/man1/$(NAME).1 2>/dev/null || true - -clean: - @rm -f *.o cntlm cntlm.exe configure-stamp build-stamp config/config.h 2>/dev/null - @rm -f win/*.exe win/*.dll win/*.iss win/*.pdf win/cntlm.ini win/license.txt win/resouces.o 2>/dev/null - @rm -f config/endian config/gethostname config/strdup config/socklen_t config/*.exe - @if [ -h Makefile ]; then rm -f Makefile; mv Makefile.gcc Makefile; fi - -distclean: clean - if [ `id -u` = 0 ]; then \ - debian/rules clean; \ - rpm/rules clean; \ - else \ - fakeroot debian/rules clean; \ - fakeroot rpm/rules clean; \ - fi - @rm -f *.exe *.deb *.rpm *.tgz *.tar.gz *.tar.bz2 tags ctags pid 2>/dev/null diff --git a/files/cntlm-0.92.3/Makefile.xlc b/files/cntlm-0.92.3/Makefile.xlc deleted file mode 100644 index 067c606..0000000 --- a/files/cntlm-0.92.3/Makefile.xlc +++ /dev/null @@ -1,49 +0,0 @@ -# -# You can tweak these three variables to make things install where you -# like, but do not touch more unless you know what you are doing. ;) -# -SYSCONFDIR=/usr/local/etc -BINDIR=/usr/local/bin -MANDIR=/usr/local/man - -# -# -CC=xlc_r -OBJS=utils.o ntlm.o xcrypt.o config.o socket.o acl.o auth.o http.o forward.o direct.o scanner.o pages.o main.o -CFLAGS=$(FLAGS) -O3 -D_POSIX_C_SOURCE=200112 -D_ISOC99_SOURCE -D_REENTRANT -DVERSION=\"`cat VERSION`\" -LDFLAGS=-lpthread -NAME=cntlm - -$(NAME): $(OBJS) - $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -main.o: main.c - if [ -z "$(SYSCONFDIR)" ]; then \ - $(CC) $(CFLAGS) -c main.c -o $@; \ - else \ - $(CC) $(CFLAGS) -DSYSCONFDIR=\"$(SYSCONFDIR)\" -c main.c -o $@; \ - fi - -install: $(NAME) - if [ -f /usr/bin/oslevel ]; then \ - install -M 0755 -S -f $(BINDIR) $(NAME); \ - install -M 0644 -f $(MANDIR)/man1 doc/$(NAME).1; \ - install -M 0600 -c $(SYSCONFDIR) doc/$(NAME).conf; \ - else \ - install -D -m 0755 -s $(NAME) $(BINDIR)/$(NAME); \ - install -D -m 0644 doc/$(NAME).1 $(MANDIR)/man1/$(NAME).1; \ - [ -f $(SYSCONFDIR)/$(NAME).conf -o -z "$(SYSCONFDIR)" ] \ - || install -D -m 0600 doc/$(NAME).conf $(SYSCONFDIR)/$(NAME).conf; \ - fi - -uninstall: - rm -f $(BINDIR)/$(NAME) $(MANDIR)/man1/$(NAME).1 2>/dev/null || true - -clean: - @rm -f *.o cntlm cntlm.exe configure-stamp build-stamp config/config.h 2>/dev/null - @rm -f cntlm-install win/cyg* win/cntlm* 2>/dev/null - @rm -f config/endian config/gethostname config/strdup config/socklen_t config/*.exe - @if [ -h Makefile ]; then rm -f Makefile; mv Makefile.gcc Makefile; fi - -distclean: clean - @rm -f *.deb *.rpm *.tgz *.tar.gz *.tar.bz2 tags ctags pid 2>/dev/null diff --git a/files/cntlm-0.92.3/README b/files/cntlm-0.92.3/README deleted file mode 100644 index c09be23..0000000 --- a/files/cntlm-0.92.3/README +++ /dev/null @@ -1,157 +0,0 @@ -Installation using packages -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Most of the popular distros contain cntlm packages.n their repositories. -You can use the procedures described below to prepare a package of current cntlm -version if desired. - -NOTE: generating packages traditionally requires root privileges (to be able to set -proper ownership and permissions on package members). You can overcome that using -fakeroot. However, to install your packages you have to be root. - -*** SOURCE TARBALL *** - - $ make tgz - or - $ make tbz2 - -*** DEBIAN PACKAGES *** - -1) Quick way: - - $ make deb - -2) From Debian/Ubuntu repository: - - Get these files (e.g. apt-get source cntlm): - - cntlm_0.XX-X.diff.gz - cntlm_0.XX-X.dsc - cntlm_0.XX.orig.tar.gz - - Compile: - - $ dpkg-source -x cntlm_0.XX-Y.dsc - $ cd cntlm-0.XX/ - $ dpkg-buildpackage -b -rfakeroot - - Upon installation, the package takes care of creating a dedicated user for - cntlm, init script integration, manages eventual configuration file updates - with new upstream versions, things like restart of the daemon after future - updates, etc. You can later revert all these changes with one command, should - you decide to remove cntlm from your system. - - -*** RPM FROM SCRATCH *** - -1) Quick way: - - $ make rpm # you'll need root privs. or fakeroot utility - -2) Detailed howto (or if make rpm doesn't work for you) - - To build an RPM package from scratch, as root change to - /usr/src/[redhat|rpm|whatever]/SOURCES - - Copy there all files from cntlm's rpm/ directory plus appropriate version of - the source tar.bz2 (see SOURCE TARBALL section above) and type: - - $ rpmbuild -ba cntlm.spec - - Shortly after, you'll have source and binary RPMs ready in your ../SRPMS, resp. - ../RPMS directories. - - If your build cannot find the default config file in /etc, you probably have - broken RPM build environment. You should add this to your ~/.rpmmacros: - %_sysconfdir /etc - -*** RPM FROM *.src.rpm *** - - If you just want to create a binary package from src.rpm, as root type: - - $ rpmbuild --rebuild pkgname.src.rpm - - Resulting binary RPM will be at /usr/src/..../RPMS - - If your build cannot find the default config file in /etc, you probably have - broken RPM build environment. You should add this to your ~/.rpmmacros: - %_sysconfdir /etc - -*** WINDOWS INSTALLER *** - - Traditional compilation steps: - - $ ./configure - $ make - - Prepare all binaries, manuals, config templates, Start Menu links and InnoSetup - project definition file: - - $ make win - - Then run InnoSetup compiler to pack it all into an automatic installer EXE: - - $ /your/path/to/ISCC.exe win/setup.iss - or - Open folder "win" in explorer, right click "setup.iss" and select "Compile". - - Both with generate an installer in the "win" folder. - -Traditional installation -~~~~~~~~~~~~~~~~~~~~~~~~ -First, you have to compile cntlm. Using the Makefile, this should be very easy: - -$ ./configure -$ make -$ make install - -Cntlm does not require any dynamic libraries and there are no dependencies you -have to satisfy before compilation, except for libpthreads. This library is -required for all threaded applications and is very likely to be part of your -system already, because it comes with libc. Next, install cntlm onto your -system like so: - -Default installation directories are /usr/sbin, /usr/share/man and /etc. Should -you want to install cntlm into a different location, change the DESTDIR -installation prefix (from "/") to add a different installation prefix (e.g. -/usr/local). To change individual directories, use BINDIR, MANDIR and -SYSCONFDIR: - -$ make SYSCONFDIR=/etc BINDIR=/usr/bin MANDIR=/usr/share/man -$ make install SYSCONFDIR=/etc BINDIR=/usr/bin MANDIR=/usr/share/man - -Cntlm is compiled with system-wide configuration file by default. That means -whenever you run cntlm, it looks into a hardcoded path (SYSCONFDIR) and tries -to load cntml.conf. You cannot make it not to do so, unless you use -c with an -alternative file or /dev/null. This is standard behaviour and probably what you -want. On the other hand, some of you might not want to use cntlm as a daemon -started by init scripts and you would prefer setting up everything on the -command line. This is possible, just comment out SYSCONFDIR variable definition -in the Makefile before you compile cntlm and it will remove this feature. - -Installation includes the main binary, the man page (see "man cntlm") and if -the default config feature was not removed, it also installs a configuration -template. Please note that unlike bin and man targets, existing configuration -is never overwritten during installation. In the doc/ directory you can find -among other things a file called "cntlmd". It can be used as an init.d script. - - -Architectures -~~~~~~~~~~~~~ -The build system now has an autodetection of the build arch endianness. Every -common CPU and OS out there is supported, including Windows, MacOS X, Linux, -*BSD, AIX. - - -Compilers -~~~~~~~~~ -Cntlm is tested against GCC and IBM XL C/C++, other C compilers will work -for you too. There are no compiler specific directives and options AFAIK. -compilers might work for you (then again, they might not). Specific -Makefiles for different compilers are supported by the ./configure script -(e.g. Makefile.xlc) - - -Contact -~~~~~~~ -David Kubicek diff --git a/files/cntlm-0.92.3/VERSION b/files/cntlm-0.92.3/VERSION deleted file mode 100644 index 4d47d83..0000000 --- a/files/cntlm-0.92.3/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.92.3 diff --git a/files/cntlm-0.92.3/acl.c b/files/cntlm-0.92.3/acl.c deleted file mode 100644 index 81aad9d..0000000 --- a/files/cntlm-0.92.3/acl.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * These are ACL routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "acl.h" -#include "socket.h" -#include "swap.h" - -/* - * TODO: retest ACLs on big-endian - */ - -/* - * Add the rule spec to the ACL list. - */ -int acl_add(plist_t *rules, char *spec, enum acl_t acl) { - struct in_addr source; - network_t *aux; - int i, mask = 32; - char *tmp; - - if (rules == NULL) - return 0; - - spec = strdup(spec); - aux = (network_t *)new(sizeof(network_t)); - i = strcspn(spec, "/"); - if (i < strlen(spec)) { - spec[i] = 0; - mask = strtol(spec+i+1, &tmp, 10); - if (mask < 0 || mask > 32 || spec[i+1] == 0 || *tmp != 0) { - syslog(LOG_ERR, "ACL netmask for %s is invalid\n", spec); - free(aux); - free(spec); - return 0; - } - } - - if (!strcmp("*", spec)) { - source.s_addr = 0; - mask = 0; - } else { - if (!strcmp("0", spec)) { - source.s_addr = 0; - } else if (!so_resolv(&source, spec)) { - syslog(LOG_ERR, "ACL source address %s is invalid\n", spec); - free(aux); - free(spec); - return 0; - } - } - - aux->ip = source.s_addr; - aux->mask = mask; - mask = swap32(~(((uint64_t)1 << (32-mask)) - 1)); - if ((source.s_addr & mask) != source.s_addr) - syslog(LOG_WARNING, "Subnet definition might be incorrect: %s/%d\n", inet_ntoa(source), aux->mask); - - syslog(LOG_INFO, "New ACL rule: %s %s/%d\n", (acl == ACL_ALLOW ? "allow" : "deny"), inet_ntoa(source), aux->mask); - *rules = plist_add(*rules, acl, (char *)aux); - - free(spec); - return 1; -} - -/* - * Takes client IP address (network order) and walks the - * ACL rules until a match is found, returning ACL_ALLOW - * or ACL_DENY accordingly. If no rule matches, connection - * is allowed (such is the case with no ACLs). - * - * Proper policy should always end with a default rule, - * targetting either "*" or "0/0" to explicitly express - * one's intentions. - */ -enum acl_t acl_check(plist_t rules, struct in_addr naddr) { - network_t *aux; - int mask; - - while (rules) { - aux = (network_t *)rules->aux; - mask = swap32(~(((uint64_t)1 << (32-aux->mask)) - 1)); - - if ((naddr.s_addr & mask) == (aux->ip & mask)) - return rules->key; - - rules = rules->next; - } - - return ACL_ALLOW; -} diff --git a/files/cntlm-0.92.3/acl.h b/files/cntlm-0.92.3/acl.h deleted file mode 100644 index f44bc6b..0000000 --- a/files/cntlm-0.92.3/acl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * These are ACL routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _ACL_H -#define _ACL_H - -#include - -#include "utils.h" - -/* - * ACL rule datatypes. - */ -enum acl_t { - ACL_ALLOW = 0, - ACL_DENY -}; - -typedef struct { - unsigned int ip; - int mask; -} network_t; - -extern int acl_add(plist_t *rules, char *spec, enum acl_t acl); -extern enum acl_t acl_check(plist_t rules, struct in_addr naddr); - -#endif /* _ACL_H */ diff --git a/files/cntlm-0.92.3/auth.c b/files/cntlm-0.92.3/auth.c deleted file mode 100644 index 8714510..0000000 --- a/files/cntlm-0.92.3/auth.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Credentials related structures and routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include - -#include "utils.h" -#include "auth.h" - -struct auth_s *new_auth(void) { - struct auth_s *tmp; - - tmp = (struct auth_s *)malloc(sizeof(struct auth_s)); - if (tmp == NULL) - return NULL; - - memset(tmp->user, 0, MINIBUF_SIZE); - memset(tmp->domain, 0, MINIBUF_SIZE); - memset(tmp->workstation, 0, MINIBUF_SIZE); - memset(tmp->passntlm2, 0, MINIBUF_SIZE); - memset(tmp->passnt, 0, MINIBUF_SIZE); - memset(tmp->passlm, 0, MINIBUF_SIZE); - tmp->hashntlm2 = 1; - tmp->hashnt = 0; - tmp->hashlm = 0; - tmp->flags = 0; - - return tmp; -} - -struct auth_s *copy_auth(struct auth_s *dst, struct auth_s *src, int fullcopy) { - dst->hashntlm2 = src->hashntlm2; - dst->hashnt = src->hashnt; - dst->hashlm = src->hashlm; - dst->flags = src->flags; - - strlcpy(dst->domain, src->domain, MINIBUF_SIZE); - strlcpy(dst->workstation, src->workstation, MINIBUF_SIZE); - - if (fullcopy) { - strlcpy(dst->user, src->user, MINIBUF_SIZE); - if (src->passntlm2) - memcpy(dst->passntlm2, src->passntlm2, MINIBUF_SIZE); - if (src->passnt) - memcpy(dst->passnt, src->passnt, MINIBUF_SIZE); - if (src->passlm) - memcpy(dst->passlm, src->passlm, MINIBUF_SIZE); - } else { - memset(dst->user, 0, MINIBUF_SIZE); - memset(dst->passntlm2, 0, MINIBUF_SIZE); - memset(dst->passnt, 0, MINIBUF_SIZE); - memset(dst->passlm, 0, MINIBUF_SIZE); - } - - return dst; -} - -struct auth_s *dup_auth(struct auth_s *creds, int fullcopy) { - struct auth_s *tmp; - - tmp = new_auth(); - if (tmp == NULL) - return NULL; - - return copy_auth(tmp, creds, fullcopy); -} - -void dump_auth(struct auth_s *creds) { - char *tmp; - - printf("Credentials structure dump:\n"); - if (creds == NULL) { - printf("Struct is not allocated!\n"); - return; - } - - printf("User: %s\n", creds->user); - printf("Domain: %s\n", creds->domain); - printf("Wks: %s\n", creds->workstation); - printf("HashNTLMv2: %d\n", creds->hashntlm2); - printf("HashNT: %d\n", creds->hashnt); - printf("HashLM: %d\n", creds->hashlm); - printf("Flags: %X\n", creds->flags); - if (creds->passntlm2) { - tmp = printmem(creds->passntlm2, 16, 8); - printf("PassNTLMv2: %s\n", tmp); - free(tmp); - } - - if (creds->passnt) { - tmp = printmem(creds->passnt, 16, 8); - printf("PassNT: %s\n", tmp); - free(tmp); - } - - if (creds->passlm) { - tmp = printmem(creds->passlm, 16, 8); - printf("PassLM: %s\n\n", tmp); - free(tmp); - } -} diff --git a/files/cntlm-0.92.3/auth.h b/files/cntlm-0.92.3/auth.h deleted file mode 100644 index f083afa..0000000 --- a/files/cntlm-0.92.3/auth.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Credentials related structures and routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _AUTH_H -#define _AUTH_H - -#include - -#include "utils.h" - -/* - * Although I always prefer structs with pointer refs, I need direct storage - * here to be able to alloc/free it in one go. It is used in a plist_t which - * frees its items, but not recursively. - */ -struct auth_s { - char user[MINIBUF_SIZE]; - char domain[MINIBUF_SIZE]; - char workstation[MINIBUF_SIZE]; - char passlm[MINIBUF_SIZE]; - char passnt[MINIBUF_SIZE]; - char passntlm2[MINIBUF_SIZE]; - int hashntlm2; - int hashnt; - int hashlm; - uint32_t flags; -}; - -#define auth_strcpy(creds, var, value) \ - if ((creds) && (value)) { \ - strlcpy(((creds)->var), (value), MINIBUF_SIZE); \ - } - -#define auth_memcpy(creds, var, value, len) \ - if ((creds) && (value)) { \ - memcpy(((creds)->var), (value), MIN(len, MINIBUF_SIZE)); \ - } - -/* - * No free_auth() required, just use free() - * new_auth() is also just a convenience malloc/memset() wrapper - */ -extern struct auth_s *new_auth(void); -extern struct auth_s *copy_auth(struct auth_s *dst, struct auth_s *src, int fullcopy); -extern struct auth_s *dup_auth(struct auth_s *creds, int fullcopy); -extern void dump_auth(struct auth_s *creds); - -#endif /* _AUTH_H */ diff --git a/files/cntlm-0.92.3/config.c b/files/cntlm-0.92.3/config.c deleted file mode 100644 index e23ae20..0000000 --- a/files/cntlm-0.92.3/config.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * These are very basic config file routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include - -#include "globals.h" -#include "config.h" -#include "utils.h" - -/* -static const char *globals[] = { - "Allow", - "Deny", - "Gateway", - "Listen", - "SOCKS5Proxy", - "SOCKS5User", - "NTLMToBasic", - "Tunnel" }; -*/ - -config_t config_open(const char *fname) { - config_t rc; - FILE *fp; - char *buf, *tmp, *key, *value; - char section[MINIBUF_SIZE] = "global"; - int i, j, slen, len, quote; - - //printf("sizeof = %d\n", sizeof(globals) / sizeof(char *)); - - fp = fopen(fname, "r"); - if (!fp) - return NULL; - - buf = new(BUFSIZE); - rc = (config_t)new(sizeof(struct config_s)); - rc->options = NULL; - - while (!feof(fp)) { - quote = 0; - tmp = fgets(buf, BUFSIZE, fp); - if (!tmp) - break; - - len = MIN(BUFSIZE, strlen(buf)); - if (!len || feof(fp)) - continue; - - /* - * Find first non-empty character - */ - for (i = j = 0; j < len && isspace(buf[j]); ++j); - - /* - * Comment? - */ - if (j >= len || buf[j] == '#' || buf[j] == ';') - continue; - - /* - * Find end of keyword - */ - for (i = j; j < len && isalnum(buf[j]); ++j); - - /* - * Malformed? - */ - if (j >= len) - continue; - - /* - * Is it a section? - */ - if (buf[j] == '[') { - for (++j; j < len && isspace(buf[j]); ++j); - for (slen = j; j < len && j-slen < MINIBUF_SIZE-1 && buf[j] != ']' && !isspace(buf[j]); ++j); - if (j-slen > 0) { - strlcpy(section, buf+slen, j-slen+1); - } - continue; - } - - /* - * It's an OK keyword - */ - key = substr(buf, i, j-i); - - /* - * Find next non-empty character - */ - for (i = j; j < len && isspace(buf[j]); ++j); - if (j >= len || buf[j] == '#' || buf[j] == ';') - continue; - - /* - * Is value quoted? - */ - if (buf[j] == '"') { - quote = 1; - for (i = ++j; j < len && buf[i] != '"'; ++i); - if (i >= len) - continue; - } else - i = len; - - /* - * Get value as quoted or until EOL/comment - */ - value = substr(buf, j, i-j); - if (!quote) { - i = strcspn(value, "#"); - if (i != strlen(value)) - value[i] = 0; - trimr(value); - } - - if (debug) - printf("section: %s, %s = '%s'\n", section, key, value); - rc->options = hlist_add(rc->options, key, value, HLIST_NOALLOC, HLIST_NOALLOC); - } - - free(buf); - fclose(fp); - - return rc; -} - -void config_set(config_t cf, char *option, char *value) { - cf->options = hlist_mod(cf->options, option, value, 1); -} - -char *config_pop(config_t cf, const char *option) { - char *tmp; - - tmp = hlist_get(cf->options, option); - if (tmp) { - tmp = strdup(tmp); - cf->options = hlist_del(cf->options, option); - } - - return tmp; -} - -int config_count(config_t cf) { - return hlist_count(cf->options); -} - -void config_close(config_t cf) { - if (cf == NULL) - return; - - cf->options = hlist_free(cf->options); - free(cf); -} diff --git a/files/cntlm-0.92.3/config.h b/files/cntlm-0.92.3/config.h deleted file mode 100644 index 2b1e38d..0000000 --- a/files/cntlm-0.92.3/config.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * These are very basic config file routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _CONFIG_H -#define _CONFIG_H - -#include - -#include "utils.h" - -#define CFG_OPTION(cf, opt, var, size) { char *__tmp = NULL; if ((__tmp=config_pop(cf, opt))) { strlcpy(var, __tmp, size); } if (__tmp) free(__tmp); } -#define CFG_DEFAULT(cf, opt, var, size) { char *__tmp = NULL; if ((__tmp=config_pop(cf, opt)) && !strlen(var)) { strlcpy(var, __tmp, size); } if (__tmp) free(__tmp); } - -typedef struct config_s *config_t; -struct config_s { - hlist_t options; -}; - -extern config_t config_open(const char *fname); -extern void config_set(config_t cf, char *option, char *value); -extern char *config_pop(config_t cf, const char *option); -extern int config_count(config_t cf); -extern void config_close(config_t cf); - -#endif /* _CONFIG_H */ diff --git a/files/cntlm-0.92.3/config/endian.c b/files/cntlm-0.92.3/config/endian.c deleted file mode 100644 index 717f14f..0000000 --- a/files/cntlm-0.92.3/config/endian.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -uint8_t num[] = { 0xEF, 0xBE }; - -/* - * RC: 1 = LE, 0 = BE - */ -int main(int argc, char **argv) { - int rc; - - rc = (*((uint16_t *)num) == 0xBEEF); - printf("%s\n", rc ? "little endian" : "big endian"); - - return rc; -} diff --git a/files/cntlm-0.92.3/config/gethostname.c b/files/cntlm-0.92.3/config/gethostname.c deleted file mode 100644 index 3e76762..0000000 --- a/files/cntlm-0.92.3/config/gethostname.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -int main(int argc, char **argv) { - char *tmp[300]; - - memset(tmp, 0, sizeof(tmp)); - gethostname(tmp, sizeof(tmp)-1); - if (strlen(tmp)) - printf("%s", tmp); - - return !(!strlen(tmp)); -} - diff --git a/files/cntlm-0.92.3/config/socklen_t.c b/files/cntlm-0.92.3/config/socklen_t.c deleted file mode 100644 index 16f8e4c..0000000 --- a/files/cntlm-0.92.3/config/socklen_t.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(int argc, char **argv) { - socklen_t len; - return !!sizeof(len); -} diff --git a/files/cntlm-0.92.3/config/strdup.c b/files/cntlm-0.92.3/config/strdup.c deleted file mode 100644 index af70193..0000000 --- a/files/cntlm-0.92.3/config/strdup.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -int main(int argc, char **argv) { - return !strcmp("hello", strdup("hello")); -} diff --git a/files/cntlm-0.92.3/configure b/files/cntlm-0.92.3/configure deleted file mode 100755 index 107f2d4..0000000 --- a/files/cntlm-0.92.3/configure +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -# -# Search for GCC or XL C/C++, former if both exist -# -# To add another compiler, just create Makefile.XXX and add XXX to $CCS -# -# To prevent ugly Makefile extensions, underscore and chars following it -# in the name XXX are automatically removed before locating relevant -# Makefile. This is why compiler "xlc_r" has Makefile extension "xlc". -# This can be disabled if neccessary. -# - -CCS="xlc_r gcc" - -# -# Look for supported compilers -# -for c in $CCS; do - if CCPATH=`which $c 2>&1` && [ -z "${CCPATH%%/*}" ]; then - CC="$c" - break - fi -done - -# -# Make a link to a proper Makefile.* -# -if [ -z "$CC" ]; then - echo "Unable to find GNU GCC or IBM XL C/C++. Fix your PATH!" - exit 1 -else - echo "Using $CCPATH to compile Cntlm" - [ -h Makefile ] && rm -f Makefile 2>/dev/null - case "$CC" in - gcc) - # default Makefile is for GCC; just revert back to - # GCC if Makefile is linked to other compiler version - if [ ! -f Makefile ]; then - mv Makefile.gcc Makefile - fi - ;; - *) - # backup default GCC Makefile and create a link to other - if [ -f Makefile ]; then - mv Makefile Makefile.gcc - fi - - EXT=`echo "$CC" | sed 's/_.*//'` - ln -s Makefile.$EXT Makefile - ;; - esac -fi - -STAMP=configure-stamp -CONFIG=config/config.h -TESTS="endian strdup socklen_t gethostname" - -#[ -f $STAMP ] && exit 0 -touch $STAMP - -rm -f $CONFIG -for i in $TESTS; do - printf "Checking $i... " - printf "#define config_$i " >> $CONFIG - OUT=`$CC -D_POSIX_C_SOURCE=199506L -D_ISOC99_SOURCE -D_REENTRANT -o config/$i config/$i.c 2>&1` - rc=$? - - if [ $rc -ne 0 ]; then # -o -n "$OUT" ]; then - rc=0 - RET=no - else - RET=`./config/$i` - rc=$? - [ -z "$RET" ] && if [ $rc -eq 0 ]; then RET="no"; else RET=yes; fi - fi - - echo $rc >> $CONFIG - echo $RET -done diff --git a/files/cntlm-0.92.3/debian/changelog b/files/cntlm-0.92.3/debian/changelog deleted file mode 100644 index 551bd41..0000000 --- a/files/cntlm-0.92.3/debian/changelog +++ /dev/null @@ -1,6 +0,0 @@ -cntlm (0.92.3) unstable; urgency=low - - * Ad-hoc source build, not a Debian maintained package! - - -- David Kubicek Fri, 14 Mar 2010 02:16:39 +0100 - diff --git a/files/cntlm-0.92.3/debian/cntlm.default b/files/cntlm-0.92.3/debian/cntlm.default deleted file mode 100644 index 6f94a49..0000000 --- a/files/cntlm-0.92.3/debian/cntlm.default +++ /dev/null @@ -1,3 +0,0 @@ -# Additional options that are passed to the Daemon. -TIMEOUT=1 -RUNAS=cntlm diff --git a/files/cntlm-0.92.3/debian/cntlm.init b/files/cntlm-0.92.3/debian/cntlm.init deleted file mode 100644 index 04871a8..0000000 --- a/files/cntlm-0.92.3/debian/cntlm.init +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/sh -# -### BEGIN INIT INFO -# Provides: cntlm -# Required-Start: $syslog $time -# Required-Stop: $syslog $time -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Authenticating HTTP accelerator for NTLM secured proxies -# Description: Cntlm is meant to be given your proxy address and becomming -# the primary proxy then, listening on a selected local port. -# You point all your proxy-aware programs to it and don't ever -# have to deal with proxy authentication again. -### END INIT INFO -# -# DAEMON Location of the binary -# PIDFILE Make sure that you or, if used, -U uid can create/write it -# TIMEOUT How long to wait for active connections to finish before -# forcing cntlm to stop with a second signal -# RUNAS Name or number of the non-privileged account to run as -# - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin -DAEMON=/usr/sbin/cntlm -NAME=cntlm -DESC="CNTLM Authentication Proxy" - -# Set default values -PIDFILE=/var/run/cntlm/cntlm.pid -TIMEOUT=1 -RUNAS=cntlm - -test -x $DAEMON || exit 0 - -# Include custom values if available -if [ -f /etc/default/cntlm ] ; then - . /etc/default/cntlm -fi - -DAEMON_OPTS="$DAEMON_OPTS -U $RUNAS -P $PIDFILE" -PIDDIR=`dirname $PIDFILE 2>/dev/null` - -start() { - echo -n "Starting $DESC: " - - if [ -n "$PIDDIR" -a ! -d "$PIDDIR" ]; then - mkdir -p "$PIDDIR" 2>/dev/null - chown "$RUNAS" "$PIDDIR" 2>/dev/null - chmod 755 "$PIDDIR" 2>/dev/null - fi - - start-stop-daemon --oknodo --quiet --start --pidfile $PIDFILE --name $NAME --startas $DAEMON -- $DAEMON_OPTS 2>/dev/null - if [ $? -eq 0 ]; then - echo "$NAME." - else - echo "failed!" - fi -} - -stop() { - echo -n "Stopping $DESC: " - start-stop-daemon --oknodo --quiet --stop --retry -HUP/$TIMEOUT/-KILL/2 --pidfile $PIDFILE --name $NAME 2>/dev/null - if [ $? -eq 0 ]; then - echo "$NAME." - else - echo "failed!" - fi -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart|reload|force-reload) - stop - start - ;; - *) - echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2 - exit 2 - ;; -esac - -exit 0 diff --git a/files/cntlm-0.92.3/debian/compat b/files/cntlm-0.92.3/debian/compat deleted file mode 100644 index 7ed6ff8..0000000 --- a/files/cntlm-0.92.3/debian/compat +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/files/cntlm-0.92.3/debian/control b/files/cntlm-0.92.3/debian/control deleted file mode 100644 index c2ff7e7..0000000 --- a/files/cntlm-0.92.3/debian/control +++ /dev/null @@ -1,20 +0,0 @@ -Source: cntlm -Section: net -Priority: optional -Maintainer: David Watson -Build-Depends: debhelper (>= 5) -Standards-Version: 3.8.0 -Vcs-Git: git://planetwatson.co.uk/cntlm -Vcs-Browser: http://projects.planetwatson.co.uk/repositories/show/cntlm -Homepage: http://cntlm.sourceforge.net/ - -Package: cntlm -Architecture: any -Depends: adduser, ${misc:Depends}, ${shlibs:Depends} -Replaces: ntlmaps -Description: Fast NTLM authentication proxy with tunneling - Cntlm is a fast and efficient NTLM proxy, with support for TCP/IP tunneling, - authenticated connection caching, ACLs, proper daemon logging and behaviour - and much more. It has up to ten times faster responses than similar NTLM - proxies, while using by orders or magnitude less RAM and CPU. Manual page - contains detailed information. diff --git a/files/cntlm-0.92.3/debian/copyright b/files/cntlm-0.92.3/debian/copyright deleted file mode 100644 index 78318bf..0000000 --- a/files/cntlm-0.92.3/debian/copyright +++ /dev/null @@ -1,32 +0,0 @@ -This package was debianized by David Kubicek on -Fri, 01 Jun 2007 10:46:26 +0200. - -The current Debian maintainer is David Watson - -It was downloaded from - -Copyright: - - Copyright (C) 2007 David Kubicek - -License: - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License (verison 2) as published -by the Free Software Foundation; either version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License with -the Debian GNU/Linux distribution in file /usr/share/common-licenses/GPL; -if not, write to the Free Software Foundation, Inc., 51 Franklin St, -Fifth Floor, Boston, MA 02110-1301, USA. - -On Debian systems, the complete text of the GNU General Public -License, version 2, can be found in /usr/share/common-licenses/GPL-2. - -The Debian packaging is (C) 2007, David Kubicek and -is licensed under the GPL, see `/usr/share/common-licenses/GPL'. diff --git a/files/cntlm-0.92.3/debian/dirs b/files/cntlm-0.92.3/debian/dirs deleted file mode 100644 index 0091546..0000000 --- a/files/cntlm-0.92.3/debian/dirs +++ /dev/null @@ -1,2 +0,0 @@ -usr/sbin -usr/share/lintian/overrides diff --git a/files/cntlm-0.92.3/debian/docs b/files/cntlm-0.92.3/debian/docs deleted file mode 100644 index e845566..0000000 --- a/files/cntlm-0.92.3/debian/docs +++ /dev/null @@ -1 +0,0 @@ -README diff --git a/files/cntlm-0.92.3/debian/lintian-override b/files/cntlm-0.92.3/debian/lintian-override deleted file mode 100644 index 8679857..0000000 --- a/files/cntlm-0.92.3/debian/lintian-override +++ /dev/null @@ -1,2 +0,0 @@ -# Use a non-standard permission to help protect passwords -cntlm binary: non-standard-file-perm etc/cntlm.conf 0600 != 0644 diff --git a/files/cntlm-0.92.3/debian/postinst b/files/cntlm-0.92.3/debian/postinst deleted file mode 100644 index d1c780d..0000000 --- a/files/cntlm-0.92.3/debian/postinst +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh -# -# Postinst script for cntlm -# - -set -e - -NAME=cntlm -HOME=/var/run/cntlm - -# Create cntlm user and its homedir -if ! getent passwd $NAME >/dev/null; then - adduser --system --home $HOME --shell /bin/sh --disabled-password $NAME -fi - -if ! [ -d $HOME ]; then - mkdir -p $HOME - chmod 755 $HOME - chown -h -R $NAME $HOME -fi - -#DEBHELPER# - -# Automatically added by dh_installinit -if [ -x "/etc/init.d/cntlm" ]; then - update-rc.d cntlm defaults >/dev/null - if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then - invoke-rc.d cntlm start || exit $? - else - /etc/init.d/cntlm start || exit $? - fi -fi -# End automatically added section diff --git a/files/cntlm-0.92.3/debian/postrm b/files/cntlm-0.92.3/debian/postrm deleted file mode 100644 index 3ec0f03..0000000 --- a/files/cntlm-0.92.3/debian/postrm +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# -# Postrm script for cntlm -# - -set -e - -NAME=cntlm - -if [ "$1" = "purge" ]; then - #if [ -e /usr/share/debconf/confmodule ]; then - # . /usr/share/debconf/confmodule - # db_purge - #fi - - # Remove SysV initscript - #update-rc.d $NAME remove >/dev/null || true - - # Remove user cntlm - home=`getent passwd $NAME | cut -d : -f 6` - rm -f "$home/$NAME.pid" >/dev/null 2>&1 || true - userdel $NAME || true - rmdir "$home" >/dev/null 2>&1 || true -fi - -#DEBHELPER# - -# Automatically added by dh_installinit -if [ "$1" = "purge" ] ; then - update-rc.d cntlm remove >/dev/null || exit $? -fi -# End automatically added section diff --git a/files/cntlm-0.92.3/debian/prerm b/files/cntlm-0.92.3/debian/prerm deleted file mode 100644 index 80e9110..0000000 --- a/files/cntlm-0.92.3/debian/prerm +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -set -e - -#DEBHELPER# - -# Automatically added by dh_installinit -if [ -x "/etc/init.d/cntlm" ]; then - if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then - invoke-rc.d cntlm stop || exit $? - else - /etc/init.d/cntlm stop || exit $? - fi -fi -# End automatically added section diff --git a/files/cntlm-0.92.3/debian/rules b/files/cntlm-0.92.3/debian/rules deleted file mode 100755 index 27bdc5f..0000000 --- a/files/cntlm-0.92.3/debian/rules +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/make -f -# -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -#export DH_VERBOSE=1 - -CFLAGS = -Wall - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O3 -endif - -configure: configure-stamp -configure-stamp: - dh_testdir - # Add here commands to configure the package. - ./configure - touch configure-stamp - -build: build-stamp - -build-stamp: configure-stamp - dh_testdir - - # Add here commands to compile the package. - $(MAKE) - - touch $@ - -clean: - dh_testdir - dh_testroot - rm -f build-stamp configure-stamp - - # Add here commands to clean up after the build process. - [ ! -f Makefile ] || $(MAKE) clean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - # Add here commands to install the package into debian/cntlm. - $(MAKE) DESTDIR=$(CURDIR)/debian/cntlm install - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_install - cp debian/lintian-override debian/cntlm/usr/share/lintian/overrides/cntlm - dh_installdebconf - dh_installinit -n - dh_installman doc/cntlm.1 - dh_link - dh_strip - dh_compress - dh_fixperms -Xcntlm.conf - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/files/cntlm-0.92.3/debian/watch b/files/cntlm-0.92.3/debian/watch deleted file mode 100644 index 5f84f2a..0000000 --- a/files/cntlm-0.92.3/debian/watch +++ /dev/null @@ -1,2 +0,0 @@ -version=3 -http://sf.net/cntlm/cntlm-([\.\d]+)\.tar\.gz diff --git a/files/cntlm-0.92.3/direct.c b/files/cntlm-0.92.3/direct.c deleted file mode 100644 index c0f86ef..0000000 --- a/files/cntlm-0.92.3/direct.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern int h_errno; - -#include "utils.h" -#include "globals.h" -#include "auth.h" -#include "http.h" -#include "socket.h" -#include "ntlm.h" -#include "direct.h" -#include "pages.h" - -int host_connect(const char *hostname, int port) { - struct in_addr addr; - - errno = 0; - if (!so_resolv(&addr, hostname)) { - //if (debug) - // printf("so_resolv: %s failed (%d: %s)\n", hostname, h_errno, hstrerror(h_errno)); - return -1; - } - - return so_connect(addr, port); - -} - -int www_authenticate(int sd, rr_data_t request, rr_data_t response, struct auth_s *creds) { - char *tmp, *buf, *challenge; - rr_data_t auth; - int len; - - int rc = 0; - - buf = new(BUFSIZE); - - strcpy(buf, "NTLM "); - len = ntlm_request(&tmp, creds); - if (len) { - to_base64(MEM(buf, uint8_t, 5), MEM(tmp, uint8_t, 0), len, BUFSIZE-5); - free(tmp); - } - - auth = dup_rr_data(request); - auth->headers = hlist_mod(auth->headers, "Connection", "keep-alive", 1); - auth->headers = hlist_mod(auth->headers, "Authorization", buf, 1); - auth->headers = hlist_mod(auth->headers, "Content-Length", "0", 1); - auth->headers = hlist_del(auth->headers, "Transfer-Encoding"); - - /* - * Drop whatever error page server returned - */ - if (!http_body_drop(sd, response)) - goto bailout; - - if (debug) { - printf("\nSending WWW auth request...\n"); - hlist_dump(auth->headers); - } - - if (!headers_send(sd, auth)) - goto bailout; - - if (debug) - printf("\nReading WWW auth response...\n"); - - /* - * Get NTLM challenge - */ - reset_rr_data(auth); - if (!headers_recv(sd, auth)) { - goto bailout; - } - - if (debug) - hlist_dump(auth->headers); - - /* - * Auth required? - */ - if (auth->code == 401) { - if (!http_body_drop(sd, auth)) - goto bailout; - - tmp = hlist_get(auth->headers, "WWW-Authenticate"); - if (tmp && strlen(tmp) > 6 + 8) { - challenge = new(strlen(tmp) + 5 + 1); - len = from_base64(challenge, tmp + 5); - if (len > NTLM_CHALLENGE_MIN) { - len = ntlm_response(&tmp, challenge, len, creds); - if (len > 0) { - strcpy(buf, "NTLM "); - to_base64(MEM(buf, uint8_t, 5), MEM(tmp, uint8_t, 0), len, BUFSIZE-5); - request->headers = hlist_mod(request->headers, "Authorization", buf, 1); - free(tmp); - } else { - syslog(LOG_ERR, "No target info block. Cannot do NTLMv2!\n"); - response->errmsg = "Invalid NTLM challenge from web server"; - free(challenge); - goto bailout; - } - } else { - syslog(LOG_ERR, "Server returning invalid challenge!\n"); - response->errmsg = "Invalid NTLM challenge from web server"; - free(challenge); - goto bailout; - } - - free(challenge); - } else { - syslog(LOG_WARNING, "No challenge in WWW-Authenticate!\n"); - response->errmsg = "Web server reply missing NTLM challenge"; - goto bailout; - } - } else { - goto bailout; - } - - if (debug) - printf("\nSending WWW auth...\n"); - - if (!headers_send(sd, request)) { - goto bailout; - } - - if (debug) - printf("\nReading final server response...\n"); - - reset_rr_data(auth); - if (!headers_recv(sd, auth)) { - goto bailout; - } - - rc = 1; - - if (debug) - hlist_dump(auth->headers); - -bailout: - if (rc) - response = copy_rr_data(response, auth); - free_rr_data(auth); - free(buf); - - return rc; -} - -rr_data_t direct_request(void *cdata, rr_data_t request) { - rr_data_t data[2], rc = NULL; - struct auth_s *tcreds = NULL; - int *rsocket[2], *wsocket[2]; - int w, loop, sd; - char *tmp; - - char *hostname = NULL; - int port = 0; - int conn_alive = 0; - - int cd = ((struct thread_arg_s *)cdata)->fd; - struct sockaddr_in caddr = ((struct thread_arg_s *)cdata)->addr; - - if (debug) - printf("Direct thread processing...\n"); - - sd = host_connect(request->hostname, request->port); - if (sd < 0) { - syslog(LOG_WARNING, "Connection failed for %s:%d (%s)", request->hostname, request->port, strerror(errno)); - tmp = gen_502_page(request->http, strerror(errno)); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - - rc = (void *)-1; - goto bailout; - } - - /* - * Now save NTLM credentials for purposes of this thread. - * If web auth fails, we'll rewrite them like with NTLM-to-Basic in proxy mode. - */ - tcreds = dup_auth(g_creds, /* fullcopy */ 1); - - if (request->hostname) { - hostname = strdup(request->hostname); - port = request->port; - } else { - tmp = gen_502_page(request->http, "Invalid request URL"); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - - rc = (void *)-1; - goto bailout; - } - - do { - if (request) { - data[0] = dup_rr_data(request); - request = NULL; - } else { - data[0] = new_rr_data(); - } - data[1] = new_rr_data(); - - rsocket[0] = wsocket[1] = &cd; - rsocket[1] = wsocket[0] = &sd; - - conn_alive = 0; - - for (loop = 0; loop < 2; ++loop) { - if (data[loop]->empty) { // Isn't this the first loop with request supplied by caller? - if (debug) { - printf("\n******* Round %d C: %d, S: %d *******\n", loop+1, cd, sd); - printf("Reading headers (%d)...\n", *rsocket[loop]); - } - if (!headers_recv(*rsocket[loop], data[loop])) { - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - } - - /* - * Check whether this new request still talks to the same server as previous. - * If no, return request to caller, he must decide on forward or direct - * approach. - */ - if (loop == 0 && hostname && data[0]->hostname - && (strcasecmp(hostname, data[0]->hostname) || port != data[0]->port)) { - if (debug) - printf("\n******* D RETURN: %s *******\n", data[0]->url); - - rc = dup_rr_data(data[0]); - free_rr_data(data[0]); - free_rr_data(data[1]); - goto bailout; - } - - if (debug) - hlist_dump(data[loop]->headers); - - if (loop == 0 && data[0]->req) { - syslog(LOG_DEBUG, "%s %s %s", inet_ntoa(caddr.sin_addr), data[0]->method, data[0]->url); - - /* - * Convert full proxy request URL into a relative URL - * Host header is already inserted by headers_recv() - */ - if (data[0]->rel_url) { - if (data[0]->url) - free(data[0]->url); - data[0]->url = strdup(data[0]->rel_url); - } - - data[0]->headers = hlist_mod(data[0]->headers, "Connection", "keep-alive", 1); - data[0]->headers = hlist_del(data[0]->headers, "Proxy-Authorization"); - - /* - * Try to get auth from client if present - */ - if (http_parse_basic(data[0]->headers, "Authorization", tcreds) > 0 && debug) - printf("NTLM-to-basic: Credentials parsed: %s\\%s at %s\n", tcreds->domain, tcreds->user, tcreds->workstation); - } - - /* - * Is this a CONNECT request? - */ - if (loop == 0 && CONNECT(data[0])) { - if (debug) - printf("CONNECTing...\n"); - - data[1]->empty = 0; - data[1]->req = 0; - data[1]->code = 200; - data[1]->msg = strdup("Connection established"); - data[1]->http = strdup(data[0]->http); - - if (headers_send(cd, data[1])) - tunnel(cd, sd); - - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - - if (loop == 1 && data[1]->code == 401 && hlist_subcmp_all(data[1]->headers, "WWW-Authenticate", "NTLM")) { - /* - * Server closing the connection after 401? - * Should never happen. - */ - if (hlist_subcmp(data[1]->headers, "Connection", "close")) { - if (debug) - printf("Reconnect before WWW auth\n"); - close(sd); - sd = host_connect(data[0]->hostname, data[0]->port); - if (sd < 0) { - tmp = gen_502_page(data[0]->http, "WWW authentication reconnect failed"); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - - rc = (void *)-1; - goto bailout; - } - } - if (!www_authenticate(*wsocket[0], data[0], data[1], tcreds)) { - if (debug) - printf("WWW auth connection error.\n"); - - tmp = gen_502_page(data[1]->http, data[1]->errmsg ? data[1]->errmsg : "Error during WWW-Authenticate"); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - - free_rr_data(data[0]); - free_rr_data(data[1]); - - rc = (void *)-1; - goto bailout; - } else if (data[1]->code == 401) { - /* - * Server giving 401 after auth? - * Request basic auth - */ - tmp = gen_401_page(data[1]->http, data[0]->hostname, data[0]->port); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - - free_rr_data(data[0]); - free_rr_data(data[1]); - - rc = (void *)-1; - goto bailout; - } - } - - /* - * Check if we should loop for another request. Required for keep-alive - * connections, client might really need a non-interrupted conversation. - * - * We default to keep-alive server connections, unless server explicitly - * flags closing the connection or we detect a body with unknown size - * (end marked by server closing). - */ - if (loop == 1) { - conn_alive = !hlist_subcmp(data[1]->headers, "Connection", "close") - && http_has_body(data[0], data[1]) != -1; - if (conn_alive) { - data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Connection", "keep-alive", 1); - data[1]->headers = hlist_mod(data[1]->headers, "Connection", "keep-alive", 1); - } else { - data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Connection", "close", 1); - rc = (void *)-1; - } - } - - if (debug) - printf("Sending headers (%d)...\n", *wsocket[loop]); - - /* - * Send headers - */ - if (!headers_send(*wsocket[loop], data[loop])) { - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - - if (!http_body_send(*wsocket[loop], *rsocket[loop], data[0], data[1])) { - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - } - - free_rr_data(data[0]); - free_rr_data(data[1]); - - } while (conn_alive && !so_closed(sd) && !so_closed(cd) && !serialize); - -bailout: - if (tcreds) - free(tcreds); - if (hostname) - free(hostname); - - close(sd); - - return rc; -} - -void direct_tunnel(void *thread_data) { - int sd, port = 0; - char *pos, *hostname; - - int cd = ((struct thread_arg_s *)thread_data)->fd; - char *thost = ((struct thread_arg_s *)thread_data)->target; - struct sockaddr_in caddr = ((struct thread_arg_s *)thread_data)->addr; - - hostname = strdup(thost); - if ((pos = strchr(hostname, ':')) != NULL) { - *pos = 0; - port = atoi(++pos); - } - - sd = host_connect(hostname, port); - if (sd <= 0) - goto bailout; - - syslog(LOG_DEBUG, "%s FORWARD %s", inet_ntoa(caddr.sin_addr), thost); - if (debug) - printf("Portforwarding to %s for client %d...\n", thost, cd); - - tunnel(cd, sd); - -bailout: - free(hostname); - close(sd); - close(cd); - - return; -} - diff --git a/files/cntlm-0.92.3/direct.h b/files/cntlm-0.92.3/direct.h deleted file mode 100644 index 3aa5942..0000000 --- a/files/cntlm-0.92.3/direct.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _DIRECT_H -#define _DIRECT_H - -#include "utils.h" - -extern int host_connect(const char *hostname, int port); -extern rr_data_t direct_request(void *cdata, rr_data_t request); -extern void direct_tunnel(void *thread_data); - -#endif /* _DIRECT_H */ diff --git a/files/cntlm-0.92.3/doc/cntlm.1 b/files/cntlm-0.92.3/doc/cntlm.1 deleted file mode 100644 index 8657877..0000000 --- a/files/cntlm-0.92.3/doc/cntlm.1 +++ /dev/null @@ -1,529 +0,0 @@ -.TH CNTLM 1 "Nov 2010" "cntlm 0.90" "Accelerating NTLM/NTLMv2 Authentication Proxy" -.SH NAME -\fBcntlm\fP - authenticating HTTP(S) proxy with TCP/IP tunneling and acceleration - -.SH SYNOPSIS -.B cntlm -[ -.B -AaBcDdFfgHhILlMPprSsTUuvw -] [ \fIhost1\fP \fIport1\fP | \fIhost1\fP:\fIport1\fP ] ... \fIhostN\fP \fIportN\fP - -.SH DESCRIPTION -\fBCntlm\fP is an NTLM/NTLM SR/NTLMv2 authenticating HTTP proxy. It stands between your applications and the -corporate proxy, adding NTLM authentication on-the-fly. You can specify several "parent" proxies and Cntlm -will try one after another until one works. All auth'd connections are cached and reused to achieve high -efficiency. Just point your apps proxy settings at Cntlm, fill in cntlm.conf (cntlm.ini) and you're ready to -do. This is useful on Windows, but essential for non-Microsoft OS's. Proxy IP addresses can be specified via -CLI (\fIhost1:port1\fP to \fIhostN:portN\fP) or the configuration file. - -Another option is to have \fBcntlm\fP authenticate your local web connections without any parent proxies. It -can work in a stand-alone mode, just like Squid or ISA. By default, all requests are forwarded to parent -proxies, but the user can set a "NoProxy" list, a list of URL matching wild-card patterns, that route between -direct and forward modes. \fBCntlm\fP can also recognize when all your corporate proxies are unavailable and -switch to stand-alone mode automatically (and then back again). Aside from \fIWWW\fP and \fIPROXY\fP -authentication, \fBcntlm\fP provides a useful feature enabling users migrate their laptops between work and -home without changing proxy settings in their applications (using \fBcntlm\fP all the time). \fBCntlm\fP also -integrates transparent TCP/IP port forwarding (tunneling). Each tunnel opens a new listening socket on local -machine and and forwards all connections to the target host behind the parent proxy. Instead of these SSH-like -tunnels, user can also choose a limited SOCKS5 interface. - -.PP -Core \fBcntlm\fP function had been similar to the late NTLMAPS, but today, \fBcntlm\fP has evolved way beyond -anything any other application of this type can offer. The feature list below speaks for itself. \fBCntlm\fP -has many security/privacy features like \fBNTLMv2\fP support and password protection - it is possible to -substitute password hashes (which can be obtained using\ \fB-H\fP) in place of the actual password or to enter -the password interactively (on start-up or via "basic" HTTP auth translation). If plaintext password is used, -it is automatically hashed during the startup and all traces of it are removed from the process memory. - -.PP -In addition to minimal use of system resources, \fBcntlm\fP achieves higher throughput on a given link. By -caching authenticated connections, it acts as an HTTP accelerator; This way, the 5-way auth handshake for -each connection is transparently eliminated, providing immediate access most of the time. \fBCntlm\fP never -caches a request/reply body in memory, in fact, no traffic is generated except for the exchange of auth headers -until the client <-> server connection is fully negotiated. Only then real data transfer takes place. -\fBCntlm\fP is written in optimized C and easily achieves fifteen times faster responses than others. - -.PP -An example of \fBcntlm\fP compared to NTLMAPS: \fBcntlm\fP gave avg 76 kB/s with peak CPU usage of 0.3% -whereas with NTLMAPS it was avg 48 kB/s with peak CPU at 98% (Pentium M 1.8 GHz). The extreme difference in -resource usage is one of many important benefits for laptop use. Peak memory consumption (several complex -sites, 50 paralell connections/threads; values are in KiB): -.nf -.ft C - - VSZ RSS CMD - 3204 1436 ./cntlm \-f \-c ./cntlm.conf \-P pid - 411604 6264 /usr/share/ntlmaps/main.py \-c /etc/ntlmaps/server.cfg -.ft P -.fi - -.ne 6 -.PP -Inherent part of the development is profiling and memory management screening using Valgrind. The source -distribution contains a file called \fIvalgrind.txt\fP, where you can see the report confirming zero leaks, no -access to unallocated memory, no usage of uninitialized data - all traced down to each instruction emulated in -Valgrind's virtual CPU during a typical production lifetime of the proxy. - -.SH OPTIONS -Most options can be pre-set in a configuration file. Specifying an option more than once is not an error, but -\fBcntlm\fP ignores all occurences except the last one. This does not apply to options like\ \fB-L\fP, each of -which creates a new instance of some feature. \fBCntlm\fP can be built with a hardcoded configuration file -(e.g. /etc/cntlm.conf), which is always loaded, if possible. See\ \fB-c\fP option on how to override some or -all of its settings. - -Use \fB-h\fP to see available options with short description. - -.TP -.B -A IP/mask\ \ \ \ (Allow) -Allow ACL rule. Together with \fB-D\fP (Deny) they are the two rules allowed in ACL policy. It is more usual -to have this in a configuration file, but \fBCntlm\fP follows the premise that you can do the same on the -command-line as you can using the config file. When \fBCntlm\fP receives a connection request, it decides -whether to allow or deny it. All ACL rules are stored in a list in the same order as specified. \fBCntlm\fP -then walks the list and the first \fIIP/mask\fP rule that matches the request source address is applied. The -\fImask\fP can be any number from 0 to 32, where 32 is the default (that is exact IP match). This notation is -also known as CIDR. If you want to match everything, use \fB0/0\fP or an asterix. ACLs on the command-line -take precedence over those in the config file. In such case, you will see info about that in the log (among -the list of unused options). There you can also see warnings about possibly incorrect subnet spec, that's when -the \fIIP\fP part has more bits than you declare by \fImask\fP (e.g. 10.20.30.40/24 should be 10.20.30.0/24). - -.TP -.B -a NTLMv2 | NTLM2SR | NT | NTLM | LM\ \ \ \ (Auth) -Authentication type. NTLM(v2) comprises of one or two hashed responses, NT and LM or NTLM2SR or NTv2 and LMv2, -which are computed from the password hash. Each response uses a different hashing algorithm; as new response -types were invented, stronger algorithms were used. When you first install \fBcntlm\fP, find the strongest one -which works for you (preferably using\ \fB-M\fP). Above they are listed from strongest to weakest. Very old -servers or dedicated HW proxies might be unable to process anything but LM. If none of those work, see -compatibility flags option\ \fB-F\fP or submit a Support Request. - -.br -\fBIMPORTANT:\fP Although NTLMv2 is not widely adopted (i.e. enforced), it is supported on all Windows since -NT\ 4.0\ SP4. That's for \fBa very long time\fP! I strongly suggest you use it to protect your credentials -on-line. You should also replace plaintext \fBPassword\fP options with hashed \fBPass[NTLMv2|NT|LM]\fP -equivalents. NTLMv2 is the most and possibly the only secure authentication of the NTLM family. - -.ne 4 -.TP -.B -B\ \ \ \ (NTLMToBasic) -This option enables "NTLM-to-basic", which allows you to use one \fBcntlm\fP for multiple users. Please note -that all security of NTLM is lost this way. Basic auth uses just a simple encoding algorithm to "hide" your -credentials and it is moderately easy to sniff them. - -.ne 6 -IMPORTANT: HTTP protocol obviously has means to negotiate authorization before letting you through, but TCP/IP -doesn't (i.e. open port is open port). If you use NTLM-to-basic and DON'T specify some username/password in -the configuration file, you are bound to loose tunneling features, because \fBcntlm\fP alone won't know your -credentials. - -Because NTLM identification has at least three parts (username, password, domain) and the basic authentication -provides fields for only two (username, password), you have to smuggle the domain part somewhere. You can set -the \fBDomain\fP config/cmd-line parameter, which will then be used for all users, who don't specify their -domain as a part of the username. To do that and override the global domain setting, use this instead of plain -username in the password dialog: "domain\\username". - -.TP -.B -c -Configuration file. Command-line options, if used, override its single options or are added at the top of the -list for multi options (tunnels, parent proxies, etc) with the exception of ACLs, which are completely -overriden. Use \fI/dev/null\fP to disable any config file. - -.TP -.B -D IP/mask\ \ \ \ (Deny) -Deny ACL rule. See option \fB-A\fP above. - -.TP -.B -d \ \ \ \ (Domain) -The domain or workgroup of the proxy account. This value can also be specified as a part of the username with -\fB-u\fP. - -.TP -.B -F \ \ \ \ (Flags) -NTLM authentication flags. This option is rater delicate and I do not recommend to change the default built-in -values unless you had no success with parent proxy auth and tried magic autodetection (\fB-M\fP) and all -possible values for the \fBAuth\fP option (\fB-a\fP). Remember that each NT/LM hash combination requires -different flags. This option is sort of a complete "manual override" and you'll have to deal with it yourself. - -.ne 5 -.TP -.B -f -Run in console as a foreground job, do not fork into background. In this mode, all syslog messages will be -echoed to the console (on platforms which support syslog LOG_PERROR option). Though \fBcntlm\fP is primarily -designed as a classic UNIX daemon with syslogd logging, it provides detailed verbose mode without detaching -from the controlling terminal; see \fB-v\fP. In any case, all error and diagnostic messages are always sent to -the system logger. - -.ne 6 -.TP -.B -G \ \ \ \ (ISAScannerAgent) -User-Agent matching (case insensitive) for trans-isa-scan plugin (see \fB-S\fP for explanation). Positive -match identifies requests (applications) for which the plugin should be enabled without considering the size -of the download (see \fB-S\fP). You can use shell wildcard characters, namely "*", "?" and "[]". If used -without \fB-S\fP or \fBISAScannerSize\fP, the \fImax_size_in_kb\fP is internally set to infinity, so the -plugin will be active ONLY for selected User-Agents, regardless of download size. - -.ne 6 -.TP -.B -g\ \ \ \ (Gateway) -Gateway mode, \fBcntlm\fP listens on all network interfaces. Default is to bind just loopback. That way, only -local processes can connect to \fBcntlm\fP. In the gateway mode though, \fBcntlm\fP listens on all interfaces -and is accessible to other machines on the network. Please note that with this option the command-line order -matters when specifying proxy or tunnel local (listening) ports. Those positioned before it will bind only -loopback; those after will be public. -.br -IMPORTANT: All of the above applies only to local ports for which you didn't specify any source address. If -you did, \fBcntlm\fP tries to bind the given port only on the specified interface (or rather IP address). - -.TP -.B -H -Use this option to get hashes for password-less configuration. In this mode, \fBcntlm\fP prints the results -and exits. You can just copy & paste right into the config file. You ought to use this option with explicit -\fB-u\fP and \fB-d\fP, because some hashes include the username and domain name in the calculation. Do see -\fB-a\fP for security recommendations. - -.TP -.B -h -Display help (available options with a short description) and exit. - -.TP -.B -I -Interactive password prompt. Any password settings from the command line or config file is ignored and a -password prompt is issued. Use this option only from shell. - -.TP -.B -L [:]::\ \ \ \ (Tunnel) -Tunnel definition. The syntax is the same as in OpenSSH's local forwarding (\fB-L\fP), with a new optional -prefix, \fIsaddr\fP - the source IP address to bind the \fIlport\fP to. \fBCntlm\fP will listen for incomming -connections on the local port \fIlport\fP, forwarding every new connection through the parent proxy to the -\fIrhost\fP:\fIrport\fP (authenticating on the go). This option can be used multiple times for unlimited -number of tunnels, with or without the \fIsaddr\fP option. See \fB-g\fP for the details concerning local port -binding when \fIsaddr\fP is not used. - -Please note that many corporate proxies do not allow connections to ports other than 443 (https), but if you -run your target service on this port, you should be safe. Connect to HTTPS is "always" allowed, otherwise -nobody would be able to browse https:// sites. In any case, first try if you can establish a connection -through the tunnel, before you rely on it. This feature does the same job as tools like \fBcorkscrew(1)\fP, -but instead of communicating over a terminal, \fBcntlm\fP keeps it TCP/IP. - -.ne 5 -.TP -.B -l [:]\ \ \ \ (Listen) -Local port for the \fBcntlm\fP proxy service. Use the number you have chosen here and the hostname of the -machine running \fBcntlm\fP (possibly localhost) as proxy settings in your browser and/or the environment. -Most applications (including console) support the notion of proxy to connect to other hosts. On POSIX, set the -following variables to use e.g. \fBwget(1)\fP without any trouble (fill in the actual address of \fBcntlm\fP): -.nf -.ft C - - $ export ftp_proxy=http://localhost:3128 - $ export http_proxy=$ftp_proxy - $ export https_proxy=$ftp_proxy -.ft P -.fi - -.ne 6 -You can choose to run the proxy service on more than one port, in such case just use this option as many times -as necessary. But unlike tunnel definition, \fBcntlm\fP fails to start if it cannot bind all of the proxy -service ports. Proxy service port can also be bound selectively. Use \fIsaddr\fP to pick source IP address to -bind the \fIlport\fP to. This allows you, for example, to run the service on different ports for subnet A and -B and make it invisible for subnet C. See \fB-g\fP for the details concerning local port binding when -\fIsaddr\fP is not used. - -.TP -.B -M -Run magic NTLM dialect detection. In this mode, \fBcntlm\fP tries some known working presets against your -proxy. Probe requests are made for the specified \fItesturl\fP, with the strongest hashes going first. -When finished, settings for the most secure setup are printed. Although the detection will tell you which and -how to use \fBAuth\fP, \fBFlags\fP and password-hash options, you have to configure at least your credentials -and proxy address first. You can use \fB-I\fP to enter your password interactively. - -.ne 5 -.TP -.B -N [,:]\ \ \ \ (SOCKS5Proxy) -Enable SOCKS5 proxy and make it listen on local port \fIport_number\fP (source IP spec is also possible, as -with all options). By default, there will be no restrictions as to who can use this service. Some clients -don't even support SOCKS5 authentication (e.g. almost all browsers). If you wish to enforce authentication, -use \fB-R\fP or its equivalent option, \fBSOCKS5User\fP. As with port tunneling, it is up to the parent proxy -whether it will allow connection to any requested host:port. This feature can be used with \fBtsocks(1)\fP to -make most TCP/IP applications go thru the proxy rather than directly (only outgoing connections will work, -obviously). To make apps work without DNS server, it is important that they don't resolve themselves, but -using SOCKS. E.g. Firefox has this option available through URI "about:config", key name -\fBnetwork.proxy.socks_remote_dns\fP, which must be set to \fBtrue\fP. Proxy-unaware \fBtsocks\fPified apps, -will have to be configured using IP addresses to prevent them from DNS resolving. - -.ne 5 -.TP -.B -P -Create a PID file \fIpidfile\fP upon startup. If the specified file exists, it is truncated and overwritten. -This option is intended for use with \fBstart-stop-daemon(8)\fP and other servicing mechanisms. Please note -that the PID file is created AFTER the process drops its privileges and forks. When the daemon finishes -cleanly, the file is removed. - -.ne 5 -.TP -.B -p \ \ \ \ (Password, PassNT, ...) -Proxy account password. \fBCntlm\fP deletes the password from the memory, to make it invisible in /proc or -with inspection tools like \fBps(1)\fP, but the preferable way of setting password is the configuration file. -To that end, you can use \fBPassword\fP option (for plaintext, human readable format), or "encrypt" your -password via \fB-H\fP and then use \fBPassNTLMv2\fP, \fBPassNT\fP and/or \fBPassLM\fP. - -.ne 3 -.TP -.B -R :\ \ \ \ (SOCKS5User) -If SOCKS5 proxy is enabled, this option can make it accessible only to those who have been authorized. -It can be used several times, to create a whole list of accounts (allowed user:pass combinations). - -.TP -.B -S \ \ \ \ (ISAScannerSize) -Enables the plugin for transparent handling of the dreaded ISA AV scanner, which returns an interactive HTTP -page (displaying the scanning progress) instead of the file/data you've requested, every time it feels like -scanning the contents. This presumptuous behavior breaks every automated downloader, updater and basically -EVERY application relying on downloads (e.g. wget, apt-get). - -.ne 6 -The parameter \fImax_size_in_kb\fP allows you to choose maximum download size you wish to handle by the plugin -(see below why you might want that). If the file size is bigger than this, \fBcntlm\fP forwards you the -interactive page, effectively disabling the plugin for that download. Zero means no limit. Use -\fB-G\fP/\fBISAScannerAgent\fP to identify applications for which \fImax_size_in_kb\fP should be ignored -(forcing the plugin). It works by matching User-Agent header and is necessary for e.g. wget, apt-get and yum, -which would fail if the response is some HTTP page instead of requested data. - -.ne 8 -How it works: the client asks for a file, \fBcntlm\fP detects ISA's bullshit response and waits for the secret -link to ISA's cache, which comes no sooner than the file is downloaded and scanned by ISA. Only then can -\fBcntlm\fP make the second request for the real file and forward it along with correct headers to the client. -The client doesn't timeout while waiting for it, b/c \fBcntlm\fP is periodically sending an extra "keepalive" -header, but the user might get nervous not seeing the progress bar move. It's of course \fBpurely -psychological\fP matter, there's no difference if \fBcntlm\fP or your browser requests the scanned file - you -must wait for ISA to do it's job and download then. You just expect to see some progress indicator move, which -is all what the ISA's page does: it shows HTML countdown. - -.ne 2 -If the plugin cannot parse the interactive page for some reason (unknown formatting, etc.), it quits and the -page is forwarded to you - it's never "lost". - -.ne 6 -The keepalive header is called \fCISA-Scanner\fP and shows ISA's progress, e.g.: -.nf -.ft C - - HTTP/1.1 200 OK - ISA-Scanner: 1000 of 10000 - ISA-Scanner: 2000 of 10000 - ... -.ft P -.fi - -.TP -.B -r \fB": "\fP\ \ \ \ (Header) -Header substitution. Every client's request will be processed and any headers defined using \fB-r\fP or in the -configuration file will be added to it. In case the header is already present, its value will be replaced. - -.TP -.B -s -Serializes all requests by not using concurrent threads for proxy (tunneling still works in parallel). This -has a horrible impact on performance and is available only for debugging purposes. When used with \fB-v\fP, -it yields nice sequential debug log, where requests take turns. - -.TP -.B -T -Used in combination with \fB-v\fP to save the debug output into a trace file. It should be placed as the -first parameter on the command line. To prevent data loss, it never overwrites an existing file. You have to -pick a unique name or manually delete the old file. - -.ne 7 -.TP -.B -U -When executed as root, do the stuff that needs such permissions (read config, bind ports, etc.) and then -immediately drop privileges and change to \fIuid\fP. This parameter can be either number or system username. -If you use a number, both uid and gid of the process will be set to this value; if you specify a username, uid -and gid will be set according to that user's uid and primary gid as defined in \fI/etc/passwd\fP. You should -use the latter, possibly using a dedicated \fBcntlm\fP account. As with any daemon, you are \fBstrongly\fP -advised to run \fBcntlm\fP under a non-privileged account. - -.TP -.B -u [@]\ \ \ \ (Username) -Proxy account/user name. Domain can be be entered as well. - -.TP -.B -v -Print debugging information. Automatically enables (\fB-f\fP). - -.TP -.B -w \ \ \ \ (Workstation) -Workstation NetBIOS name. Do not use full qualified domain name (FQDN) here. Just the first part. -If not specified, \fBcntlm\fP tries to get the system hostname and if that fails, uses "cntlm" - it's because -some proxies require this field non-empty. - -.SH CONFIGURATION -Configuration file is basically an INI file, except there are no "=" between keys and values. It comprises of -whitespace delimited keyword and value pairs. Apart from that, there are sections as well, they have the usual -"[section_name]" syntax. Comment begins with a hash "#" or a semicolon ";" and can be anywhere in the file. -Everything after the mark up until EOL is a comment. Values can contain any characters, including whitespace. -You \fIcan\fP use double quotes around the value to set a string containing special characters like spaces, -pound signs, etc. No escape sequences are allowed in quoted strings. - -There are two types of keywords, \fIlocal\fP and \fIglobal\fP. Local options specify authentication details -per domain (or location). Global keywords apply to all sections and proxies. They should be placed before all -sections, but it's not necessary. They are: \fCAllow, Deny, Gateway, Listen, SOCKS5Proxy, SOCKS5User, -NTLMToBasic, Tunnel\fP. - -All available keywords are listed here, full descriptions are in the OPTIONS section: - -.TP -.B Allow [/] -ACL allow rule, see \fB-A\fP. - -.TP -.B Auth NTLMv2 | NTLM2SR | NT | NTLM | LM -Select any possible combination of NTLM hashes using a single parameter. - -.TP -.B Deny [/] -ACL deny rule, see \fB-A\fP. - -.TP -.B Domain -Proxy account domain/workgroup name. - -.TP -.B Flags -NTLM authentication flags. See \fB-F\fP for details. - -.TP -.B Gateway yes|no -Gateway mode. In the configuration file, order doesn't matter. Gateway mode -applies the same to all tunnels. - -.TP -.B Header -Header substitution. See \fB-r\fP for details and remember, no quoting. - -.ne 4 -.TP -.B ISAScannerAgent -Wildcard-enabled (*, ?, []) case insensitive User-Agent string matching for the trans-isa-plugin. If you don't -define \fBISAScannerSize\fP, it is internally set to infinity, i.e. disabling the plugin for all downloads -except those agent-matched ones. See \fB-G\fP. - -.ne 2 -.TP -.B ISAScannerSize -Enable trans-isa-scan plugin. See \fB-S\fP for more. - -.ne 2 -.TP -.B Listen [:] -Local port number for the \fBcntlm\fP's proxy service. See \fB-l\fP for more. - -.TP -.B Password -Proxy account password. As with any other option, the value (password) can be enclosed in double quotes (") -in case it contains special characters like spaces, pound signs, etc. - -.ne 11 -.TP -.B PassNTLMv2, PassNT, PassLM -Hashes of the proxy account password (see \fB-H\fP and \fB-a\fP). When you want to use hashes in the config -(instead of plaintext password), each \fBAuth\fP settings requires different options: -.nf -.ft C - - Settings | Requires - -------------+----------------- - Auth NTLMv2 | PassNTLMv2 - Auth NTLM2SR | PassNT - Auth NT | PassNT - Auth NTLM | PassNT + PassLM - Auth LM | PassLM -.ft P -.fi - -.TP -.B Proxy -Parent proxy, which requires authentication. The same as proxy on the command-line, can be used more than -once to specify an arbitrary number of proxies. Should one proxy fail, \fBcntlm\fP automatically moves on to the -next one. The connect request fails only if the whole list of proxies is scanned and (for each request) and -found to be invalid. Command-line takes precedence over the configuration file. - -.TP -.B NoProxy , , ... -Avoid parent proxy for these host names. All matching URL's will be proxied \fIdirectly\fP by \fBcntlm\fP as a -stand-alone proxy. \fBCntlm\fP supports WWW authentication in this mode, thus allowing you to access local -intranet sites with corporate NTLM authentication. Hopefully, you won't need that virtualized MSIE any more. :) -See \fB-N\fP for more. - -.TP -.B SOCKS5Proxy [:] -Enable SOCKS5 proxy. See \fB-O\fP for more. - -.TP -.B SOCKS5User : -Create a new SOCKS5 proxy account. See \fB-R\fP for more. - -.TP -.B NTLMToBasic yes|no -Enable/disable NTLM-to-basic authenticatoin. See \fB-B\fP for more. - -.TP -.B Tunnel [:]:: -Tunnel definition. See \fB-L\fP for more. - -.TP -.B Username -Proxy account name, without the possibility to include domain name ('at' sign -is interpreted literally). - -.TP -.B Workstation -The hostname of your workstation. - -.ne 7 -.SH FILES -The optional location of the configuration file is defined in the Makefile, with the default for 1) deb/rpm -package, 2) traditional "make; make install" and 3) Windows installer, respectively, being: -.nf -.ft C - - 1) /etc/cntlm.conf - 2) /usr/local/etc/cntlm.conf - 3) %PROGRAMFILES%\\Cntlm\\cntlm.ini -.ft P -.fi - -.SH PORTING -\fBCntlm\fP is being used on many platforms, little and big endian machines, so users should not have any -problems with compilation. Nowadays, \fBcntlm\fP is a standard tool in most Linux distributions and there are -various repositories for other UNIX-like systems. Personally, I release Debian Linux (deb), RedHat Linux (rpm) -and Windows (exe) binaries, but most people get \fBcntlm\fP from their OS distributor. - -.ne 2 -For compilation details, see README in the source distribution. Porting to any POSIX conforming OS shouldn't -be more than a matter of a Makefile rearrangement. \fBCntlm\fP uses strictly POSIX.1-2001 interfaces with -ISO C99 libc and is also compliant with SUSv3. Since version 0.33, \fBcntlm\fP supports Windows using a POSIX -emulation layer called \fBCygwin\fP. - -.SH BUGS -\fBTo report a bug\fP, enable the debug output, save it to a file and submit on-line along with a detailed -description of the problem and how to reproduce it. Visit the home page for more. -.nf -.ft C - - cntlm \-T cntlmtrace.log \-v \-s ... the rest ... -.ft P -.fi - -.SH AUTHOR -Written by David Kubicek -.br -Homepage: http://cntlm.sourceforge.net/ - -.SH COPYRIGHT -Copyright \(co 2007-2010 David Kubicek -.br -\fBCntlm\fP uses DES, MD4, MD5 and HMAC-MD5 routines from \fBgnulib\fP and Base64 routines from \fBmutt(1)\fP. diff --git a/files/cntlm-0.92.3/doc/cntlm.conf b/files/cntlm-0.92.3/doc/cntlm.conf deleted file mode 100644 index de5a78b..0000000 --- a/files/cntlm-0.92.3/doc/cntlm.conf +++ /dev/null @@ -1,92 +0,0 @@ -# -# Cntlm Authentication Proxy Configuration -# -# NOTE: all values are parsed literally, do NOT escape spaces, -# do not quote. Use 0600 perms if you use plaintext password. -# - -Username testuser -Domain corp-uk -Password password -# NOTE: Use plaintext password only at your own risk -# Use hashes instead. You can use a "cntlm -M" and "cntlm -H" -# command sequence to get the right config for your environment. -# See cntlm man page -# Example secure config shown below. -# PassLM 1AD35398BE6565DDB5C4EF70C0593492 -# PassNT 77B9081511704EE852F94227CF48A793 -### Only for user 'testuser', domain 'corp-uk' -# PassNTLMv2 D5826E9C665C37C80B53397D5C07BBCB - -# Specify the netbios hostname cntlm will send to the parent -# proxies. Normally the value is auto-guessed. -# -# Workstation netbios_hostname - -# List of parent proxies to use. More proxies can be defined -# one per line in format : -# -Proxy 10.0.0.41:8080 -Proxy 10.0.0.42:8080 - -# List addresses you do not want to pass to parent proxies -# * and ? wildcards can be used -# -NoProxy localhost, 127.0.0.*, 10.*, 192.168.* - -# Specify the port cntlm will listen on -# You can bind cntlm to specific interface by specifying -# the appropriate IP address also in format : -# Cntlm listens on 127.0.0.1:3128 by default -# -Listen 3128 - -# If you wish to use the SOCKS5 proxy feature as well, uncomment -# the following option. It can be used several times -# to have SOCKS5 on more than one port or on different network -# interfaces (specify explicit source address for that). -# -# WARNING: The service accepts all requests, unless you use -# SOCKS5User and make authentication mandatory. SOCKS5User -# can be used repeatedly for a whole bunch of individual accounts. -# -#SOCKS5Proxy 8010 -#SOCKS5User dave:password - -# Use -M first to detect the best NTLM settings for your proxy. -# Default is to use the only secure hash, NTLMv2, but it is not -# as available as the older stuff. -# -# This example is the most universal setup known to man, but it -# uses the weakest hash ever. I won't have it's usage on my -# conscience. :) Really, try -M first. -# -#Auth LM -#Flags 0x06820000 - -# Enable to allow access from other computers -# -#Gateway yes - -# Useful in Gateway mode to allow/restrict certain IPs -# Specifiy individual IPs or subnets one rule per line. -# -#Allow 127.0.0.1 -#Deny 0/0 - -# GFI WebMonitor-handling plugin parameters, disabled by default -# -#ISAScannerSize 1024 -#ISAScannerAgent Wget/ -#ISAScannerAgent APT-HTTP/ -#ISAScannerAgent Yum/ - -# Headers which should be replaced if present in the request -# -#Header User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98) - -# Tunnels mapping local port to a machine behind the proxy. -# The format is :: -# -#Tunnel 11443:remote.com:443 - diff --git a/files/cntlm-0.92.3/doc/valgrind.txt b/files/cntlm-0.92.3/doc/valgrind.txt deleted file mode 100644 index a4cd793..0000000 --- a/files/cntlm-0.92.3/doc/valgrind.txt +++ /dev/null @@ -1,55 +0,0 @@ -Memory leaks -~~~~~~~~~~~~ -This is Valgrind report on memory usage after some heavy browsing (60 parallel -connections) and daemon termination. ;) - -==741== malloc/free: in use at exit: 0 bytes in 0 blocks. -==741== malloc/free: 2,049 allocs, 2,049 frees, 197,861 bytes allocated. -==741== -==741== All heap blocks were freed -- no leaks are possible. - ---741-- memcheck: sanity checks: 6 cheap, 1 expensive ---741-- memcheck: auxmaps: 0 auxmap entries (0k, 0M) in use ---741-- memcheck: auxmaps: 0 searches, 0 comparisons ---741-- memcheck: SMs: n_issued = 29 (464k, 0M) ---741-- memcheck: SMs: n_deissued = 6 (96k, 0M) ---741-- memcheck: SMs: max_noaccess = 65535 (1048560k, 1023M) ---741-- memcheck: SMs: max_undefined = 0 (0k, 0M) ---741-- memcheck: SMs: max_defined = 782 (12512k, 12M) ---741-- memcheck: SMs: max_non_DSM = 28 (448k, 0M) ---741-- memcheck: max sec V bit nodes: 1 (0k, 0M) ---741-- memcheck: set_sec_vbits8 calls: 1 (new: 1, updates: 0) ---741-- memcheck: max shadow mem size: 752k, 0M ---741-- translate: fast SP updates identified: 4,916 ( 90.1%) ---741-- translate: generic_known SP updates identified: 342 ( 6.2%) ---741-- translate: generic_unknown SP updates identified: 194 ( 3.5%) ---741-- tt/tc: 9,734 tt lookups requiring 10,056 probes ---741-- tt/tc: 9,734 fast-cache updates, 4 flushes ---741-- transtab: new 4,484 (100,307 -> 1,609,941; ratio 160:10) [0 scs] ---741-- transtab: dumped 0 (0 -> ??) ---741-- transtab: discarded 133 (2,418 -> ??) ---741-- scheduler: 1,103,546 jumps (bb entries). ---741-- scheduler: 6/39,639 major/minor sched events. ---741-- sanity: 7 cheap, 1 expensive checks. ---741-- exectx: 30,011 lists, 221 contexts (avg 0 per list) ---741-- exectx: 4,115 searches, 3,894 full compares (946 per 1000) ---741-- exectx: 0 cmp2, 60 cmp4, 0 cmpAll - -Memory usage -~~~~~~~~~~~~ -Heap allocation per function can be seen in memory_consumption_with_reqex.pdf. -It is apparent that in cntlm, regular expression matching accounts for more -that 60% of allocated memory. I don't like that - regex is used for parsing the -option -L at startup and later in header manipulation, once for each request to -parse the first HTTP line. Regex was used there as a convenient and transparent -means to split and partly verify strings, but I'm not willing to pay for it 1.5 -times as much memory as the application would need without it. - -Ok, now I have made it optional to use reqex - using NTLM_REGEX. Without this -#define, everything is parsed by plain C memory manipulation. The graph in -memory_consumption_without_reqex.pdf shows significant drop in memory usage, -overall less than a half, actually. Both test were done by an automated test -with 60 connections in parallel and the same sites fully loaded. - -Regexes have been removed for good. No point in keeping around old unnecessary -code. diff --git a/files/cntlm-0.92.3/forward.c b/files/cntlm-0.92.3/forward.c deleted file mode 100644 index 1c1a2f8..0000000 --- a/files/cntlm-0.92.3/forward.c +++ /dev/null @@ -1,953 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "globals.h" -#include "auth.h" -#include "http.h" -#include "socket.h" -#include "ntlm.h" -#include "forward.h" -#include "scanner.h" -#include "pages.h" - -int parent_curr = 0; -pthread_mutex_t parent_mtx = PTHREAD_MUTEX_INITIALIZER; - -/* - * Connect to the selected proxy. If the request fails, pick next proxy - * in the line. Each request scans the whole list until all items are tried - * or a working proxy is found, in which case it is selected and used by - * all threads until it stops working. Then the search starts again. - * - * Writes required credentials into passed auth_s structure - */ -int proxy_connect(struct auth_s *credentials) { - proxy_t *aux; - int i, prev; - plist_t list, tmp; - int loop = 0; - - prev = parent_curr; - pthread_mutex_lock(&parent_mtx); - if (parent_curr == 0) { - aux = (proxy_t *)plist_get(parent_list, ++parent_curr); - syslog(LOG_INFO, "Using proxy %s:%d\n", aux->hostname, aux->port); - } - pthread_mutex_unlock(&parent_mtx); - - do { - pthread_mutex_lock(&parent_mtx); - aux = (proxy_t *)plist_get(parent_list, parent_curr); - pthread_mutex_unlock(&parent_mtx); - if (aux->resolved == 0) { - if (debug) - syslog(LOG_INFO, "Resolving proxy %s...\n", aux->hostname); - if (so_resolv(&aux->host, aux->hostname)) { - aux->resolved = 1; - } else { - syslog(LOG_ERR, "Cannot resolve proxy %s\n", aux->hostname); - } - } - - i = 0; - if (aux->resolved != 0) - i = so_connect(aux->host, aux->port); - - /* - * Resolve or connect failed? - */ - if (i <= 0) { - pthread_mutex_lock(&parent_mtx); - if (parent_curr >= parent_count) - parent_curr = 0; - aux = (proxy_t *)plist_get(parent_list, ++parent_curr); - pthread_mutex_unlock(&parent_mtx); - syslog(LOG_ERR, "Proxy connect failed, will try %s:%d\n", aux->hostname, aux->port); - } - } while (i <= 0 && ++loop < parent_count); - - if (i <= 0 && loop >= parent_count) - syslog(LOG_ERR, "No proxy on the list works. You lose.\n"); - - /* - * We have to invalidate the cached connections if we moved to a different proxy - */ - if (prev != parent_curr) { - pthread_mutex_lock(&connection_mtx); - list = connection_list; - while (list) { - tmp = list->next; - close(list->key); - list = tmp; - } - plist_free(connection_list); - pthread_mutex_unlock(&connection_mtx); - } - - if (i > 0 && credentials != NULL) - copy_auth(credentials, g_creds, /* fullcopy */ !ntlmbasic); - - return i; -} - -/* - * Send request, read reply, if it contains NTLM challenge, generate final - * NTLM auth message and insert it into the original client header, - * which is then processed by caller himself. - * - * If response is present, we fill in proxy's reply. Caller can tell - * if auth was required or not from response->code. If not, caller has - * a full reply to forward to client. - * - * Return 0 in case of network error, 1 when proxy replies - * - * Caller must init & free "request" and "response" (if supplied) - * - */ -int proxy_authenticate(int *sd, rr_data_t request, rr_data_t response, struct auth_s *credentials) { - char *tmp, *buf, *challenge; - rr_data_t auth; - int len; - - int pretend407 = 0; - int rc = 0; - - buf = new(BUFSIZE); - - strcpy(buf, "NTLM "); - len = ntlm_request(&tmp, credentials); - if (len) { - to_base64(MEM(buf, uint8_t, 5), MEM(tmp, uint8_t, 0), len, BUFSIZE-5); - free(tmp); - } - - auth = dup_rr_data(request); - auth->headers = hlist_mod(auth->headers, "Proxy-Authorization", buf, 1); - - if (HEAD(request) || http_has_body(request, response) != 0) { - /* - * There's a body - make this request just a probe. Do not send any body. If no auth - * is required, we let our caller send the reply directly to the client to avoid - * another duplicate request later (which traditionally finishes the 2nd part of - * NTLM handshake). Without auth, there's no need for the final request. - * - * However, if client has a body, we make this request without it and let caller do - * the second request in full. If we did it here, we'd have to cache the request - * body in memory (even chunked) and carry it around. Not practical. - * - * When caller sees 407, he makes the second request. That's why we pretend a 407 - * in this situation. Without it, caller wouldn't make it, sending the client a - * reply to our PROBE, not the real request. - * - * The same for HEAD requests - at least one ISA doesn't allow making auth - * request using HEAD!! - */ - if (debug) - printf("Will send just a probe request.\n"); - pretend407 = 1; - } - - /* - * For broken ISA's that don't accept HEAD in auth request - */ - if (HEAD(request)) { - free(auth->method); - auth->method = strdup("GET"); - } - - auth->headers = hlist_mod(auth->headers, "Content-Length", "0", 1); - auth->headers = hlist_del(auth->headers, "Transfer-Encoding"); - - if (debug) { - printf("\nSending PROXY auth request...\n"); - hlist_dump(auth->headers); - } - - if (!headers_send(*sd, auth)) { - goto bailout; - } - - if (debug) - printf("\nReading PROXY auth response...\n"); - - /* - * Return response if requested. "auth" is used to get it, - * so make it point to the caller's structure. - */ - if (response) { - free_rr_data(auth); - auth = response; - } - - reset_rr_data(auth); - if (!headers_recv(*sd, auth)) { - goto bailout; - } - - if (debug) - hlist_dump(auth->headers); - - rc = 1; - - /* - * Auth required? - */ - if (auth->code == 407) { - if (!http_body_drop(*sd, auth)) { // FIXME: if below fails, we should forward what we drop here... - rc = 0; - goto bailout; - } - tmp = hlist_get(auth->headers, "Proxy-Authenticate"); - if (tmp) { - challenge = new(strlen(tmp) + 5 + 1); - len = from_base64(challenge, tmp + 5); - if (len > NTLM_CHALLENGE_MIN) { - len = ntlm_response(&tmp, challenge, len, credentials); - if (len > 0) { - strcpy(buf, "NTLM "); - to_base64(MEM(buf, uint8_t, 5), MEM(tmp, uint8_t, 0), len, BUFSIZE-5); - request->headers = hlist_mod(request->headers, "Proxy-Authorization", buf, 1); - free(tmp); - } else { - syslog(LOG_ERR, "No target info block. Cannot do NTLMv2!\n"); - free(challenge); - goto bailout; - } - } else { - syslog(LOG_ERR, "Proxy returning invalid challenge!\n"); - free(challenge); - goto bailout; - } - - free(challenge); - } else { - syslog(LOG_WARNING, "No Proxy-Authenticate, NTLM not supported?\n"); - } - } else if (pretend407) { - if (debug) - printf("Client %s - forcing second request.\n", HEAD(request) ? "sent HEAD" : "has a body"); - if (response) - response->code = 407; // See explanation above - if (!http_body_drop(*sd, auth)) { - rc = 0; - goto bailout; - } - } - - /* - * Did proxy closed connection? It's our fault, reconnect for the caller. - */ - if (so_closed(*sd)) { - if (debug) - printf("Proxy closed on us, reconnect.\n"); - close(*sd); - *sd = proxy_connect(credentials); - if (*sd < 0) { - rc = 0; - goto bailout; - } - } - -bailout: - if (!response) - free_rr_data(auth); - - free(buf); - - return rc; -} - -/* - * Forwarding thread. Connect to the proxy, process auth then request. - * - * First read request, then call proxy_authenticate() which will send - * the request. If proxy returns 407, it will compute NTLM reply and - * return authenticated request to us. If proxy returns full response - * (no auth needed), it returns the full reply. Then we just forward - * the reply to client OR make the request again with properly auth'd - * headers provided by proxy_authenticate(). - * - * We loop while we see Connection: keep-alive, thus making sure clients - * can have uninterrupted conversations with a web server. Proxy-Connection - * is not our concern, it's handled in the caller, proxy_thread(). If it's - * present, however, we cache the auth'd proxy connection for reuse. - * - * Some proxies return Connection: keep-alive even when not requested and - * would make us loop indefinitely. Because of that, we remember which server - * we're talking to and if that changes, we return the request to be processed - * by our caller. - * - * Caller decides which URL's to forward and which to process directly, that's - * also why we return the request if the server name changes. - * - * We return NULL when we're finished or a pointer to another request. - * Returned request means server name has changed and needs to be checked - * agains NoProxy exceptions. - * - * thread_data is NOT freed - * request is NOT freed - */ -rr_data_t forward_request(void *thread_data, rr_data_t request) { - int i, w, loop, plugin, retry = 0; - int *rsocket[2], *wsocket[2]; - rr_data_t data[2], rc = NULL; - hlist_t tl; - char *tmp; - struct auth_s *tcreds = NULL; /* Per-thread credentials */ - char *hostname = NULL; - int proxy_alive; - int conn_alive; - int authok; - int noauth; - int was_cached; - - int sd; - int cd = ((struct thread_arg_s *)thread_data)->fd; - struct sockaddr_in caddr = ((struct thread_arg_s *)thread_data)->addr; - -beginning: - sd = was_cached = noauth = authok = conn_alive = proxy_alive = 0; - - rsocket[0] = wsocket[1] = &cd; - rsocket[1] = wsocket[0] = &sd; - - if (debug) { - printf("Thread processing%s...\n", retry ? " (retry)" : ""); - pthread_mutex_lock(&connection_mtx); - plist_dump(connection_list); - pthread_mutex_unlock(&connection_mtx); - } - - /* - * NTLM credentials for purposes of this thread (tcreds) are given to - * us by proxy_connect() or retrieved from connection cache. - * - * Ultimately, the source for creds is always proxy_connect(), but when - * we cache a connection, we store creds associated with it in the - * cache as well, in case we'll need them. - */ - pthread_mutex_lock(&connection_mtx); - i = plist_pop(&connection_list, (void **)&tcreds); - pthread_mutex_unlock(&connection_mtx); - if (i) { - if (debug) - printf("Found autenticated connection %d!\n", i); - sd = i; - authok = 1; - was_cached = 1; - } else { - tcreds = new_auth(); - sd = proxy_connect(tcreds); - if (sd <= 0) { - tmp = gen_502_page(request->http, "Parent proxy unreacheable"); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - rc = (void *)-1; - goto bailout; - } - } - - /* - * Each thread only serves req's for one hostname. If hostname changes, - * we return request to our caller for a new direct/forward decision. - */ - if (!hostname && request->hostname) { - hostname = strdup(request->hostname); - } - - do { - /* - * data[0] is for the first loop pass - * - first do {} loop iteration uses request passed from caller, - * in subsequent iterations we read the request headers from the client - * - if not already done, we try to authenticate the connection - * - we send the request headers to the proxy with HTTP body, if present - * - * data[1] is for the second pass - * - read proxy response - * - forward it to the client with HTTP body, if present - * - * There two goto's: - * - beginning: jump here to retry request (when cached connection timed out - * or we thought proxy was notauth, but got 407) - * - shortcut: jump here from 1st iter. of inner loop, when we detect - * that auth isn't required by proxy. We do loop++, make the jump and - * the reply to our auth attempt (containing valid response) is sent to - * client directly without us making a request a second time. - */ - if (request) { - if (retry) - data[0] = request; // Got from inside the loop = retry (must free ourselves) - else - data[0] = dup_rr_data(request); // Got from caller (make a dup, caller will free) - request = NULL; // Next time, just alloc empty structure - } else { - data[0] = new_rr_data(); - } - data[1] = new_rr_data(); - - retry = 0; - proxy_alive = 0; - conn_alive = 0; - - for (loop = 0; loop < 2; ++loop) { - if (data[loop]->empty) { // Isn't this the first loop with request supplied by caller? - if (debug) { - printf("\n******* Round %d C: %d, S: %d (authok=%d, noauth=%d) *******\n", loop+1, cd, sd, authok, noauth); - printf("Reading headers (%d)...\n", *rsocket[loop]); - } - if (!headers_recv(*rsocket[loop], data[loop])) { - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - /* error page */ - goto bailout; - } - } - - /* - * Check whether this new request still talks to the same server as previous. - * If no, return request to caller, he must decide on forward or direct - * approach. - * - * If we're here, previous request loop must have been proxy keep-alive - * (we're looping only if proxy_alive) or this is the first loop since - * we were called. If former, set proxy_alive=1 to cache the connection. - */ - if (loop == 0 && hostname && data[0]->hostname - && strcasecmp(hostname, data[0]->hostname)) { - if (debug) - printf("\n******* F RETURN: %s *******\n", data[0]->url); - if (authok) - proxy_alive = 1; - - rc = dup_rr_data(data[0]); - free_rr_data(data[0]); - free_rr_data(data[1]); - goto bailout; - } - - if (debug) - hlist_dump(data[loop]->headers); - - if (loop == 0 && data[0]->req) - syslog(LOG_DEBUG, "%s %s %s", inet_ntoa(caddr.sin_addr), data[0]->method, data[0]->url); - -shortcut: - /* - * Modify request headers. - * - * Try to request keep-alive for every connection. We keep them in a pool - * for future reuse. - */ - if (loop == 0 && data[0]->req) { - /* - * NTLM-to-Basic - */ - if (http_parse_basic(data[loop]->headers, "Proxy-Authorization", tcreds) > 0) { - if (debug) - printf("NTLM-to-basic: Credentials parsed: %s\\%s at %s\n", tcreds->domain, tcreds->user, tcreds->workstation); - } else if (ntlmbasic) { - if (debug) - printf("NTLM-to-basic: Returning client auth request.\n"); - - tmp = gen_407_page(data[loop]->http); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - - /* - * Header replacement implementation - */ - tl = header_list; - while (tl) { - data[0]->headers = hlist_mod(data[0]->headers, tl->key, tl->value, 0); - tl = tl->next; - } - - /* - * Also remove runaway P-A from the client (e.g. Basic from N-t-B), which might - * cause some ISAs to deny us, even if the connection is already auth'd. - */ - data[0]->headers = hlist_mod(data[0]->headers, "Proxy-Connection", "keep-alive", 1); - - /* - * Remove all Proxy-Authorization headers from client - */ - while (hlist_get(data[loop]->headers, "Proxy-Authorization")) { - data[loop]->headers = hlist_del(data[loop]->headers, "Proxy-Authorization"); - } - } - - /* - * Got request from client and connection is not yet authenticated? - * This can happen only with non-cached connections. - */ - if (loop == 0 && data[0]->req && !authok && !noauth) { - if (!proxy_authenticate(wsocket[0], data[0], data[1], tcreds)) { - if (debug) - printf("Proxy auth connection error.\n"); - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - /* error page */ - goto bailout; - } - - /* - * !!! data[1] is now filled by proxy_authenticate() !!! - * !!! with proxy's reply to our first (auth) req. !!! - * !!! that's why we reset data[1] below !!! - * - * Reply to auth request wasn't 407? Then auth is not required, - * let's jump into the next loop and forward it to client - * Also just forward if proxy doesn't reply with keep-alive, - * because without it, NTLM auth wouldn't work anyway. - * - * Let's decide proxy doesn't want any auth if it returns a - * non-error reply. Next rounds will be faster. - */ - if (data[1]->code != 407) { // || !hlist_subcmp(data[1]->headers, "Proxy-Connection", "keep-alive")) { - if (debug) - printf("Proxy auth not requested - just forwarding.\n"); - if (data[1]->code < 400) - noauth = 1; - loop = 1; - goto shortcut; - } - - /* - * If we're continuing normally, we have to free possible - * auth response from proxy_authenticate() in data[1] - */ - reset_rr_data(data[1]); - } - - /* - * Is final reply from proxy still 407 denied? If this is a chached - * connection or we thougth proxy was noauth (so we didn't auth), make a new - * connect and try to auth. - */ - if (loop == 1 && data[1]->code == 407 && (was_cached || noauth)) { - if (debug) - printf("\nFinal reply is 407 - retrying (cached=%d, noauth=%d).\n", was_cached, noauth); - if (tcreds) - free(tcreds); - - retry = 1; - request = data[0]; - free_rr_data(data[1]); - close(sd); - goto beginning; - } - - /* - * Was the request first and did we authenticate with proxy? - * Remember not to authenticate this connection any more. - */ - if (loop == 1 && !noauth && data[1]->code != 407) - authok = 1; - - /* - * This is to make the ISA AV scanner bullshit transparent. If the page - * returned is scan-progress-html-fuck instead of requested file/data, parse - * it, wait for completion, make a new request to ISA for the real data and - * substitute the result for the original response html-fuck response. - */ - plugin = PLUG_ALL; - if (loop == 1 && scanner_plugin) { - plugin = scanner_hook(data[0], data[1], tcreds, *wsocket[loop], rsocket[loop], scanner_plugin_maxsize); - } - - /* - * Check if we should loop for another request. Required for keep-alive - * connections, client might really need a non-interrupted conversation. - * - * We check only server reply for keep-alive, because client may want it, - * but it's not gonna happen unless server agrees. - */ - if (loop == 1) { - conn_alive = hlist_subcmp(data[1]->headers, "Connection", "keep-alive"); - if (!conn_alive) - data[1]->headers = hlist_mod(data[1]->headers, "Connection", "close", 1); - - /* - * Remove all Proxy-Authenticate headers from proxy - */ - while (hlist_get(data[loop]->headers, "Proxy-Authenticate")) { - data[loop]->headers = hlist_del(data[loop]->headers, "Proxy-Authenticate"); - } - - /* - * Are we returning 407 to the client? Substitute his request - * by our BASIC translation request. - */ - if (data[1]->code == 407) { - data[1]->headers = hlist_mod(data[1]->headers, "Proxy-Authenticate", "Basic realm=\"Cntlm for parent\"", 1); - } - } - - if (plugin & PLUG_SENDHEAD) { - if (debug) { - printf("Sending headers (%d)...\n", *wsocket[loop]); - if (loop == 0) - hlist_dump(data[loop]->headers); - } - - /* - * Forward client's headers to the proxy and vice versa; proxy_authenticate() - * might have by now prepared 1st and 2nd auth steps and filled our headers with - * the 3rd, final, NTLM message. - */ - if (!headers_send(*wsocket[loop], data[loop])) { - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - /* error page */ - goto bailout; - } - } - - /* - * Was the request CONNECT and proxy agreed? - */ - if (loop == 1 && CONNECT(data[0]) && data[1]->code == 200) { - if (debug) - printf("Ok CONNECT response. Tunneling...\n"); - - tunnel(cd, sd); - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - - if (plugin & PLUG_SENDDATA) { - if (!http_body_send(*wsocket[loop], *rsocket[loop], data[0], data[1])) { - free_rr_data(data[0]); - free_rr_data(data[1]); - rc = (void *)-1; - goto bailout; - } - } - - /* - * Proxy-Connection: keep-alive is taken care of in our caller as I said, - * but we do return when we see proxy is closing. Next headers_recv() would - * fail and we'd exit anyway. - * - * This way, we also tell our caller that proxy keep-alive is impossible. - */ - if (loop == 1) { - proxy_alive = hlist_subcmp(data[loop]->headers, "Proxy-Connection", "keep-alive"); - if (!proxy_alive) { - if (debug) - printf("PROXY CLOSING CONNECTION\n"); - rc = (void *)-1; - } - } - } - - free_rr_data(data[0]); - free_rr_data(data[1]); - - /* - * Checking conn_alive && proxy_alive is sufficient, - * so_closed() just eliminates loops that we know would fail. - */ - } while (conn_alive && proxy_alive && !so_closed(sd) && !so_closed(cd) && !serialize); - -bailout: - if (hostname) - free(hostname); - - if (debug) { - printf("forward_request: palive=%d, authok=%d, ntlm=%d, closed=%d\n", proxy_alive, authok, ntlmbasic, so_closed(sd)); - printf("\nThread finished.\n"); - } - - if (proxy_alive && authok && !ntlmbasic && !so_closed(sd)) { - if (debug) - printf("Storing the connection for reuse (%d:%d).\n", cd, sd); - pthread_mutex_lock(&connection_mtx); - connection_list = plist_add(connection_list, sd, (void *)tcreds); - pthread_mutex_unlock(&connection_mtx); - } else { - free(tcreds); - close(sd); - } - - return rc; -} - -/* - * Auth connection "sd" and try to return negotiated CONNECT - * connection to a remote host:port (thost). - * - * Return 1 for success, 0 failure. - */ -int prepare_http_connect(int sd, struct auth_s *credentials, const char *thost) { - rr_data_t data1, data2; - int rc = 0; - hlist_t tl; - - if (!sd || !thost || !strlen(thost)) - return 0; - - data1 = new_rr_data(); - data2 = new_rr_data(); - - data1->req = 1; - data1->method = strdup("CONNECT"); - data1->url = strdup(thost); - data1->http = strdup("HTTP/1.1"); - data1->headers = hlist_mod(data1->headers, "Proxy-Connection", "keep-alive", 1); - - /* - * Header replacement - */ - tl = header_list; - while (tl) { - data1->headers = hlist_mod(data1->headers, tl->key, tl->value, 1); - tl = tl->next; - } - - if (debug) - printf("Starting authentication...\n"); - - if (proxy_authenticate(&sd, data1, data2, credentials)) { - /* - * Let's try final auth step, possibly changing data2->code - */ - if (data2->code == 407) { - if (debug) { - printf("Sending real request:\n"); - hlist_dump(data1->headers); - } - if (!headers_send(sd, data1)) { - printf("Sending request failed!\n"); - goto bailout; - } - - if (debug) - printf("\nReading real response:\n"); - reset_rr_data(data2); - if (!headers_recv(sd, data2)) { - if (debug) - printf("Reading response failed!\n"); - goto bailout; - } - if (debug) - hlist_dump(data2->headers); - } - - if (data2->code == 200) { - if (debug) - printf("Ok CONNECT response. Tunneling...\n"); - rc = 1; - } else if (data2->code == 407) { - syslog(LOG_ERR, "Authentication for tunnel %s failed!\n", thost); - } else { - syslog(LOG_ERR, "Request for CONNECT to %s denied!\n", thost); - } - } else - syslog(LOG_ERR, "Tunnel requests failed!\n"); - -bailout: - free_rr_data(data1); - free_rr_data(data2); - - return rc; -} - -void forward_tunnel(void *thread_data) { - struct auth_s *tcreds; - int sd; - - int cd = ((struct thread_arg_s *)thread_data)->fd; - char *thost = ((struct thread_arg_s *)thread_data)->target; - struct sockaddr_in caddr = ((struct thread_arg_s *)thread_data)->addr; - - tcreds = new_auth(); - sd = proxy_connect(tcreds); - - if (sd <= 0) - goto bailout; - - syslog(LOG_DEBUG, "%s TUNNEL %s", inet_ntoa(caddr.sin_addr), thost); - if (debug) - printf("Tunneling to %s for client %d...\n", thost, cd); - - if (prepare_http_connect(sd, tcreds, thost)) - tunnel(cd, sd); - -bailout: - close(sd); - close(cd); - free(tcreds); - - return; -} - -#define MAGIC_TESTS 4 - -void magic_auth_detect(const char *url) { - int i, nc, c, ign = 0, found = -1; - rr_data_t req, res; - char *tmp, *pos, *host = NULL; - - struct auth_s *tcreds; - char *authstr[5] = { "NTLMv2", "NTLM2SR", "NT", "NTLM", "LM" }; - int prefs[MAGIC_TESTS][5] = { - /* NT, LM, NTLMv2, Flags, index to authstr[] */ - { 0, 0, 1, 0, 0 }, - { 1, 1, 0, 0, 3 }, - { 0, 1, 0, 0, 4 }, - { 2, 0, 0, 0, 1 } - }; - - tcreds = new_auth(); - copy_auth(tcreds, g_creds, /* fullcopy */ 1); - - if (!tcreds->passnt || !tcreds->passlm || !tcreds->passntlm2) { - printf("Cannot detect NTLM dialect - password or all its hashes must be defined, try -I\n"); - exit(1); - } - - pos = strstr(url, "://"); - if (pos) { - tmp = strchr(pos+3, '/'); - host = substr(pos+3, 0, tmp ? tmp-pos-3 : 0); - } else { - fprintf(stderr, "Invalid URL (%s)\n", url); - return; - } - - for (i = 0; i < MAGIC_TESTS; ++i) { - res = new_rr_data(); - req = new_rr_data(); - - req->req = 1; - req->method = strdup("GET"); - req->url = strdup(url); - req->http = strdup("HTTP/1.1"); - req->headers = hlist_add(req->headers, "Proxy-Connection", "keep-alive", HLIST_ALLOC, HLIST_ALLOC); - if (host) - req->headers = hlist_add(req->headers, "Host", host, HLIST_ALLOC, HLIST_ALLOC); - - tcreds->hashnt = prefs[i][0]; - tcreds->hashlm = prefs[i][1]; - tcreds->hashntlm2 = prefs[i][2]; - tcreds->flags = prefs[i][3]; - - printf("Config profile %2d/%d... ", i+1, MAGIC_TESTS); - - nc = proxy_connect(NULL); - if (nc <= 0) { - printf("\nConnection to proxy failed, bailing out\n"); - free_rr_data(res); - free_rr_data(req); - close(nc); - if (host) - free(host); - return; - } - - c = proxy_authenticate(&nc, req, res, tcreds); - if (c && res->code != 407) { - ign++; - printf("Auth not required (HTTP code: %d)\n", res->code); - free_rr_data(res); - free_rr_data(req); - close(nc); - continue; - } - - reset_rr_data(res); - if (!headers_send(nc, req) || !headers_recv(nc, res)) { - printf("Connection closed\n"); - } else { - if (res->code == 407) { - if (hlist_subcmp_all(res->headers, "Proxy-Authenticate", "NTLM") || hlist_subcmp_all(res->headers, "Proxy-Authenticate", "BASIC")) { - printf("Credentials rejected\n"); - } else { - printf("Proxy doesn't offer NTLM or BASIC\n"); - break; - } - } else { - printf("OK (HTTP code: %d)\n", res->code); - if (found < 0) { - found = i; - free_rr_data(res); - free_rr_data(req); - close(nc); - break; - } - } - } - - free_rr_data(res); - free_rr_data(req); - close(nc); - } - - if (found > -1) { - printf("----------------------------[ Profile %2d ]------\n", found); - printf("Auth %s\n", authstr[prefs[found][4]]); - if (prefs[found][3]) - printf("Flags 0x%x\n", prefs[found][3]); - if (prefs[found][0]) { - printf("PassNT %s\n", tmp=printmem(tcreds->passnt, 16, 8)); - free(tmp); - } - if (prefs[found][1]) { - printf("PassLM %s\n", tmp=printmem(tcreds->passlm, 16, 8)); - free(tmp); - } - if (prefs[found][2]) { - printf("PassNTLMv2 %s\n", tmp=printmem(tcreds->passntlm2, 16, 8)); - free(tmp); - } - printf("------------------------------------------------\n"); - } else if (ign == MAGIC_TESTS) { - printf("\nYour proxy is open, you don't need another proxy.\n"); - } else - printf("\nWrong credentials, invalid URL or proxy doesn't support NTLM nor BASIC.\n"); - - if (host) - free(host); -} - diff --git a/files/cntlm-0.92.3/forward.h b/files/cntlm-0.92.3/forward.h deleted file mode 100644 index 27d8964..0000000 --- a/files/cntlm-0.92.3/forward.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _FORWARD_H -#define _FORWARD_H - -#include "utils.h" -#include "auth.h" - -extern int proxy_connect(struct auth_s *credentials); -extern int proxy_authenticate(int *sd, rr_data_t request, rr_data_t response, struct auth_s *creds); -extern int prepare_http_connect(int sd, struct auth_s *credentials, const char *thost); -extern rr_data_t forward_request(void *cdata, rr_data_t request); -extern void forward_tunnel(void *thread_data); -extern void magic_auth_detect(const char *url); - -#endif /* _FORWARD_H */ diff --git a/files/cntlm-0.92.3/globals.h b/files/cntlm-0.92.3/globals.h deleted file mode 100644 index 2f01b93..0000000 --- a/files/cntlm-0.92.3/globals.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -/* - * These are globals, mostly run-time options, defined and setup in main module - * proxy.c - */ - -#ifndef _GLOBALS_H -#define _GLOBALS_H - -#include - -#include "utils.h" -#include "auth.h" - -extern int debug; - -extern struct auth_s *g_creds; /* global NTLM credentials */ - -extern int ntlmbasic; /* forward_request() */ -extern int serialize; -extern int scanner_plugin; -extern long scanner_plugin_maxsize; - -extern plist_t threads_list; -extern pthread_mutex_t threads_mtx; - -extern plist_t connection_list; -extern pthread_mutex_t connection_mtx; - -extern int parent_count; -extern plist_t parent_list; - -/* - * just malloc/free sizeof(proxy_t) - */ -typedef struct { - char hostname[64]; - struct auth_s creds; - struct in_addr host; - int port; - int resolved; -} proxy_t; - -extern hlist_t header_list; /* forward_request() */ -extern hlist_t users_list; /* socks5_thread() */ -extern plist_t scanner_agent_list; /* scanner_hook() */ -extern plist_t noproxy_list; /* proxy_thread() */ - -#endif /* _GLOBALS_H */ diff --git a/files/cntlm-0.92.3/http.c b/files/cntlm-0.92.3/http.c deleted file mode 100644 index a6f03e7..0000000 --- a/files/cntlm-0.92.3/http.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * HTTP handling routines and related socket stuff for CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "socket.h" -#include "ntlm.h" -#include "http.h" - -#define BLOCK 2048 - -extern int debug; - -/* - * Ture if src is a header. This is just a basic check - * for the colon delimiter. Might eventually become more - * sophisticated. :) - */ -int is_http_header(const char *src) { - return strcspn(src, ":") != strlen(src); -} - -/* - * Extract the header name from the source. - */ -char *get_http_header_name(const char *src) { - int i; - - i = strcspn(src, ":"); - if (i != strlen(src)) - return substr(src, 0, i); - else - return NULL; -} - -/* - * Extract the header value from the source. - */ -char *get_http_header_value(const char *src) { - char *sub; - - if ((sub = strchr(src, ':'))) { - sub++; - while (*sub == ' ') - sub++; - - return strdup(sub); - } else - return NULL; -} - -/* - * Receive HTTP request/response from the given socket. Fill in pre-allocated - * rr_data_t structure. - * Returns: 1 if OK, 0 in case of socket EOF or other error - */ -int headers_recv(int fd, rr_data_t data) { - int i, bsize; - int len; - char *buf; - char *tok, *s3 = 0; - char *orig = NULL; - char *ccode = NULL; - char *host = NULL; - - bsize = BUFSIZE; - buf = new(bsize); - - i = so_recvln(fd, &buf, &bsize); - if (i <= 0) - goto bailout; - - if (debug) - printf("HEAD: %s", buf); - - /* - * Are we reading HTTP request (from client) or response (from server)? - */ - trimr(buf); - orig = strdup(buf); - len = strlen(buf); - tok = strtok_r(buf, " ", &s3); - if (tok && (!strncasecmp(buf, "HTTP/", 5) || !strncasecmp(tok, "ICY", 3))) { - data->req = 0; - data->empty = 0; - data->http = strdup(tok); - data->msg = NULL; - - tok = strtok_r(NULL, " ", &s3); - if (tok) { - ccode = strdup(tok); - - tok += strlen(ccode); - while (tok < buf+len && *tok++ == ' '); - - if (strlen(tok)) - data->msg = strdup(tok); - } - - if (!data->msg) - data->msg = strdup(""); - - if (!ccode || strlen(ccode) != 3 || (data->code = atoi(ccode)) == 0) { - i = -2; - goto bailout; - } - } else if (strstr(orig, " HTTP/") && tok) { - data->req = 1; - data->empty = 0; - data->method = NULL; - data->url = NULL; - data->rel_url = NULL; - data->http = NULL; - data->hostname = NULL; - - data->method = strdup(tok); - - tok = strtok_r(NULL, " ", &s3); - if (tok) - data->url = strdup(tok); - - tok = strtok_r(NULL, " ", &s3); - if (tok) - data->http = strdup(tok); - - if (!data->url || !data->http) { - i = -3; - goto bailout; - } - - if ((tok = strstr(data->url, "://"))) { - tok += 3; - } else { - tok = data->url; - } - - s3 = strchr(tok, '/'); - if (s3) { - host = substr(tok, 0, s3-tok); - data->rel_url = strdup(s3); - } else { - host = substr(tok, 0, strlen(tok)); - data->rel_url = strdup("/"); - } - - } else { - if (debug) - printf("headers_recv: Unknown header (%s).\n", orig); - i = -4; - goto bailout; - } - - /* - * Read in all headers, do not touch any possible HTTP body - */ - do { - i = so_recvln(fd, &buf, &bsize); - trimr(buf); - if (i > 0 && is_http_header(buf)) { - data->headers = hlist_add(data->headers, get_http_header_name(buf), get_http_header_value(buf), HLIST_NOALLOC, HLIST_NOALLOC); - } - } while (strlen(buf) != 0 && i > 0); - - if (data->req) { - /* - * Fix requests, make sure the Host: header is present - */ - if (host && strlen(host)) { - data->hostname = strdup(host); - if (!hlist_get(data->headers, "Host")) - data->headers = hlist_add(data->headers, "Host", host, HLIST_ALLOC, HLIST_ALLOC); - } else { - if (debug) - printf("headers_recv: no host name (%s)\n", orig); - i = -6; - goto bailout; - } - - /* - * Remove port number from internal host name variable - */ - if (data->hostname && (tok = strchr(data->hostname, ':'))) { - *tok = 0; - data->port = atoi(tok+1); - } else if (data->url) { - if (!strncasecmp(data->url, "https", 5)) - data->port = 443; - else - data->port = 80; - } - - if (!strlen(data->hostname) || !data->port) { - i = -5; - goto bailout; - } - } - -bailout: - if (orig) free(orig); - if (ccode) free(ccode); - if (host) free(host); - free(buf); - - if (i <= 0) { - if (debug) - printf("headers_recv: fd %d error %d\n", fd, i); - return 0; - } - - return 1; -} - -/* - * Send HTTP request/response to the given socket based on what's in "data". - * Returns: 1 if OK, 0 in case of socket error - */ -int headers_send(int fd, rr_data_t data) { - hlist_t t; - char *buf; - int i, len; - - /* - * First compute required buffer size (avoid realloc, etc) - */ - if (data->req) - len = 20 + strlen(data->method) + strlen(data->url) + strlen(data->http); - else - len = 20 + strlen(data->http) + strlen(data->msg); - - t = data->headers; - while (t) { - len += 20 + strlen(t->key) + strlen(t->value); - t = t->next; - } - - /* - * We know how much memory we need now... - */ - buf = new(len); - - /* - * Prepare the first request/response line - */ - len = 0; - if (data->req) - len = sprintf(buf, "%s %s %s\r\n", data->method, data->url, data->http); - else if (!data->skip_http) - len = sprintf(buf, "%s %03d %s\r\n", data->http, data->code, data->msg); - - /* - * Now add all headers. - */ - t = data->headers; - while (t) { - len += sprintf(buf+len, "%s: %s\r\n", t->key, t->value); - t = t->next; - } - - /* - * Terminate headers - */ - strcat(buf, "\r\n"); - - /* - * Flush it all down the toilet - */ - if (!so_closed(fd)) - i = write(fd, buf, len+2); - else - i = -999; - - free(buf); - - if (i <= 0 || i != len+2) { - if (debug) - printf("headers_send: fd %d warning %d (connection closed)\n", fd, i); - return 0; - } - - return 1; -} - -/* - * Forward "size" of data from "src" to "dst". If size == -1 then keep - * forwarding until src reaches EOF. - * If dst == -1, data is discarded. - */ -int data_send(int dst, int src, length_t len) { - char *buf; - int i, block; - int c = 0; - int j = 1; - - if (!len) - return 1; - - buf = new(BLOCK); - - do { - block = (len == -1 || len-c > BLOCK ? BLOCK : len-c); - i = read(src, buf, block); - - if (i > 0) - c += i; - - if (dst >= 0 && debug) - printf("data_send: read %d of %d / %d of %lld (errno = %s)\n", i, block, c, len, i < 0 ? strerror(errno) : "ok"); - - if (dst >= 0 && so_closed(dst)) { - i = -999; - break; - } - - if (dst >= 0 && i > 0) { - j = write(dst, buf, i); - if (debug) - printf("data_send: wrote %d of %d\n", j, i); - } - - } while (i > 0 && j > 0 && (len == -1 || c < len)); - - free(buf); - - if (i <= 0 || j <= 0) { - if (i == 0 && j > 0 && (len == -1 || c == len)) - return 1; - - if (debug) - printf("data_send: fds %d:%d warning %d (connection closed)\n", dst, src, i); - return 0; - } - - return 1; -} - -/* - * Forward chunked HTTP body from "src" descriptor to "dst". - * If dst == -1, data is discarded. - */ -int chunked_data_send(int dst, int src) { - char *buf; - int bsize; - int i, w, csize; - - char *err = NULL; - - bsize = BUFSIZE; - buf = new(bsize); - - /* Take care of all chunks */ - do { - i = so_recvln(src, &buf, &bsize); - if (i <= 0) { - if (debug) - printf("chunked_data_send: aborting, read error\n"); - free(buf); - return 0; - } - - csize = strtol(buf, &err, 16); - - if (!isspace(*err) && *err != ';') { - if (debug) - printf("chunked_data_send: aborting, chunk size format error\n"); - free(buf); - return 0; - } - - if (dst >= 0) - i = write(dst, buf, strlen(buf)); - - if (csize) - if (!data_send(dst, src, csize+2)) { - if (debug) - printf("chunked_data_send: aborting, data_send failed\n"); - - free(buf); - return 0; - } - } while (csize != 0); - - /* Take care of possible trailer */ - do { - i = so_recvln(src, &buf, &bsize); - if (dst >= 0 && i > 0) - w = write(dst, buf, strlen(buf)); - } while (i > 0 && buf[0] != '\r' && buf[0] != '\n'); - - free(buf); - return 1; -} - -/* - * Full-duplex forwarding between proxy and client descriptors. - * Used for bidirectional HTTP CONNECT connection. - */ -int tunnel(int cd, int sd) { - fd_set set; - int from, to, ret, sel; - char *buf; - - buf = new(BUFSIZE); - - if (debug) - printf("tunnel: select cli: %d, srv: %d\n", cd, sd); - - do { - FD_ZERO(&set); - FD_SET(cd, &set); - FD_SET(sd, &set); - - sel = select(FD_SETSIZE, &set, NULL, NULL, NULL); - if (sel > 0) { - if (FD_ISSET(cd, &set)) { - from = cd; - to = sd; - } else { - from = sd; - to = cd; - } - - ret = read(from, buf, BUFSIZE); - if (ret > 0) { - ret = write(to, buf, ret); - } else { - free(buf); - return (ret == 0); - } - } else if (sel < 0) { - free(buf); - return 0; - } - } while (1); - - free(buf); - return 1; -} - -/* - * Return 0 if no body, -1 if body until EOF, number if size known - * One of request/response can be NULL - */ -length_t http_has_body(rr_data_t request, rr_data_t response) { - rr_data_t current; - length_t length; - int nobody; - char *tmp; - - /* - * Are we checking a complete req+res conversation or just the - * request body? - */ - current = (!response || response->empty ? request : response); - - /* - * HTTP body length decisions. There MUST NOT be any body from - * server if the request was HEAD or reply is 1xx, 204 or 304. - * No body can be in GET request if direction is from client. - */ - if (current == response) { - nobody = (HEAD(request) || - (response->code >= 100 && response->code < 200) || - response->code == 204 || - response->code == 304); - } else { - nobody = GET(request) || HEAD(request); - } - - /* - * Otherwise consult Content-Length. If present, we forward exaclty - * that many bytes. - * - * If not present, but there is Transfer-Encoding or Content-Type - * (or a request to close connection, that is, end of data is signaled - * by remote close), we will forward until EOF. - * - * No C-L, no T-E, no C-T == no body. - */ - tmp = hlist_get(current->headers, "Content-Length"); - if (!nobody && tmp == NULL && (hlist_in(current->headers, "Content-Type") - || hlist_in(current->headers, "Transfer-Encoding") - || hlist_subcmp(current->headers, "Connection", "close"))) { - // || (response->code == 200) - if (hlist_in(current->headers, "Transfer-Encoding") - && hlist_subcmp(current->headers, "Transfer-Encoding", "chunked")) - length = 1; - else - length = -1; - } else - length = (tmp == NULL || nobody ? 0 : atoll(tmp)); - - if (current == request && length == -1) - length = 0; - - return length; -} - -/* - * Send a HTTP body (if any) between descriptors readfd and writefd - */ -int http_body_send(int writefd, int readfd, rr_data_t request, rr_data_t response) { - length_t bodylen; - int rc = 1; - rr_data_t current; - - /* - * Are we checking a complete req+res conversation or just the - * request body? - */ - current = (response->empty ? request : response); - - /* - * Ok, so do we expect any body? - */ - bodylen = http_has_body(request, response); - if (bodylen) { - /* - * Check for supported T-E. - */ - if (hlist_subcmp(current->headers, "Transfer-Encoding", "chunked")) { - if (debug) - printf("Chunked body included.\n"); - - rc = chunked_data_send(writefd, readfd); - if (debug) - printf(rc ? "Chunked body sent.\n" : "Could not chunk send whole body\n"); - } else { - if (debug) - printf("Body included. Length: %lld\n", bodylen); - - rc = data_send(writefd, readfd, bodylen); - if (debug) - printf(rc ? "Body sent.\n" : "Could not send whole body\n"); - } - } else if (debug) - printf("No body.\n"); - - return rc; -} - -/* - * Connection cleanup - C-L or chunked body - * Return 0 if connection closed or EOF, 1 if OK to continue - */ -int http_body_drop(int fd, rr_data_t response) { - length_t bodylen; - int rc = 1; - - bodylen = http_has_body(NULL, response); - if (bodylen) { - if (hlist_subcmp(response->headers, "Transfer-Encoding", "chunked")) { - if (debug) - printf("Discarding chunked body.\n"); - rc = chunked_data_send(-1, fd); - } else { - if (debug) - printf("Discarding %lld bytes.\n", bodylen); - rc = data_send(-1, fd, bodylen); - } - } - - return rc; -} - -/* - * Parse headers for BASIC auth credentials - * - * Return 1 = creds parsed OK, 0 = no creds, -1 = invalid creds - */ -int http_parse_basic(hlist_t headers, const char *header, struct auth_s *tcreds) { - char *tmp = NULL, *pos = NULL, *buf = NULL, *dom = NULL; - int i; - - if (!hlist_subcmp(headers, header, "basic")) - return 0; - - tmp = hlist_get(headers, header); - buf = new(strlen(tmp) + 1); - i = 5; - while (i < strlen(tmp) && tmp[++i] == ' '); - from_base64(buf, tmp+i); - pos = strchr(buf, ':'); - - if (pos == NULL) { - memset(buf, 0, strlen(buf)); /* clean password memory */ - free(buf); - return -1; - } else { - *pos = 0; - dom = strchr(buf, '\\'); - if (dom == NULL) { - auth_strcpy(tcreds, user, buf); - } else { - *dom = 0; - auth_strcpy(tcreds, domain, buf); - auth_strcpy(tcreds, user, dom+1); - } - - if (tcreds->hashntlm2) { - tmp = ntlm2_hash_password(tcreds->user, tcreds->domain, pos+1); - auth_memcpy(tcreds, passntlm2, tmp, 16); - free(tmp); - } - - if (tcreds->hashnt) { - tmp = ntlm_hash_nt_password(pos+1); - auth_memcpy(tcreds, passnt, tmp, 21); - free(tmp); - } - - if (tcreds->hashlm) { - tmp = ntlm_hash_lm_password(pos+1); - auth_memcpy(tcreds, passlm, tmp, 21); - free(tmp); - } - - memset(buf, 0, strlen(buf)); - free(buf); - } - - return 1; -} diff --git a/files/cntlm-0.92.3/http.h b/files/cntlm-0.92.3/http.h deleted file mode 100644 index 3b3f51c..0000000 --- a/files/cntlm-0.92.3/http.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * HTTP handling routines and related socket stuff for CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _HTTP_H -#define _HTTP_H - -#include - -#include "utils.h" -#include "auth.h" - -/* - * A couple of shortcuts for if statements - */ -#define CONNECT(data) ((data) && (data)->req && !strcasecmp("CONNECT", (data)->method)) -#define HEAD(data) ((data) && (data)->req && !strcasecmp("HEAD", (data)->method)) -#define GET(data) ((data) && (data)->req && !strcasecmp("GET", (data)->method)) - -typedef long long int length_t; - -extern int is_http_header(const char *src); -extern char *get_http_header_name(const char *src); -extern char *get_http_header_value(const char *src); -extern int http_parse_basic(hlist_t headers, const char *header, struct auth_s *tcreds); -extern int headers_recv(int fd, rr_data_t data); -extern int headers_send(int fd, rr_data_t data); -extern int tunnel(int cd, int sd); -extern length_t http_has_body(rr_data_t request, rr_data_t response); -extern int http_body_send(int writefd, int readfd, rr_data_t request, rr_data_t response); -extern int http_body_drop(int fd, rr_data_t response); - -#endif /* _HTTP_H */ diff --git a/files/cntlm-0.92.3/main.c b/files/cntlm-0.92.3/main.c deleted file mode 100644 index 3800dc8..0000000 --- a/files/cntlm-0.92.3/main.c +++ /dev/null @@ -1,1618 +0,0 @@ -/* - * This is the main module of the CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Some helping routines like linked list manipulation substr(), memory - * allocation, NTLM authentication routines, etc. - */ -#include "config/config.h" -#include "socket.h" -#include "utils.h" -#include "ntlm.h" -#include "swap.h" -#include "config.h" -#include "acl.h" -#include "auth.h" -#include "http.h" -#include "globals.h" -#include "pages.h" -#include "forward.h" /* code serving via parent proxy */ -#include "direct.h" /* code serving directly without proxy */ - -#define STACK_SIZE sizeof(void *)*8*1024 - -/* - * Global "read-only" data initialized in main(). Comments list funcs. which use - * them. Having these global avoids the need to pass them to each thread and - * from there again a few times to inner calls. - */ -int debug = 0; /* all debug printf's and possibly external modules */ - -struct auth_s *g_creds = NULL; /* throughout the whole module */ - -int quit = 0; /* sighandler() */ -int ntlmbasic = 0; /* forward_request() */ -int serialize = 0; -int scanner_plugin = 0; -long scanner_plugin_maxsize = 0; - -/* - * List of finished threads. Each forward_request() thread adds itself to it when - * finished. Main regularly joins and removes all tid's in there. - */ -plist_t threads_list = NULL; -pthread_mutex_t threads_mtx = PTHREAD_MUTEX_INITIALIZER; - -/* - * List of cached connections. Accessed by each thread forward_request(). - */ -plist_t connection_list = NULL; -pthread_mutex_t connection_mtx = PTHREAD_MUTEX_INITIALIZER; - -/* - * List of available proxies and current proxy id for proxy_connect(). - */ -int parent_count = 0; -plist_t parent_list = NULL; - -/* - * List of custom header substitutions, SOCKS5 proxy users and - * UserAgents for the scanner plugin. - */ -hlist_t header_list = NULL; /* forward_request() */ -hlist_t users_list = NULL; /* socks5_thread() */ -plist_t scanner_agent_list = NULL; /* scanner_hook() */ -plist_t noproxy_list = NULL; /* proxy_thread() */ - -/* - * General signal handler. If in debug mode, quit immediately. - */ -void sighandler(int p) { - if (!quit) - syslog(LOG_INFO, "Signal %d received, issuing clean shutdown\n", p); - else - syslog(LOG_INFO, "Signal %d received, forcing shutdown\n", p); - - if (quit++ || debug) - quit++; -} - -/* - * Parse proxy parameter and add it to the global list. - */ -int parent_add(char *parent, int port) { - int len, i; - char *proxy; - proxy_t *aux; - - /* - * Check format and parse it. - */ - proxy = strdup(parent); - len = strlen(proxy); - i = strcspn(proxy, ": "); - if (i != len) { - proxy[i++] = 0; - while (i < len && (proxy[i] == ' ' || proxy[i] == '\t')) - i++; - - if (i >= len) { - free(proxy); - return 0; - } - - port = atoi(proxy+i); - } - - /* - * No port argument and not parsed from proxy? - */ - if (!port) { - syslog(LOG_ERR, "Invalid proxy specification %s.\n", parent); - free(proxy); - myexit(1); - } - - /* - * Try to resolve proxy address - * - if (debug) - syslog(LOG_INFO, "Resolving proxy %s...\n", proxy); - if (!so_resolv(&host, proxy)) { - syslog(LOG_ERR, "Cannot resolve proxy %s, discarding.\n", parent); - free(proxy); - return 0; - } - */ - - aux = (proxy_t *)new(sizeof(proxy_t)); - strlcpy(aux->hostname, proxy, sizeof(aux->hostname)); - aux->port = port; - aux->resolved = 0; - parent_list = plist_add(parent_list, ++parent_count, (char *)aux); - - free(proxy); - return 1; -} - -/* - * Register and bind new proxy service port. - */ -void listen_add(const char *service, plist_t *list, char *spec, int gateway) { - struct in_addr source; - int i, p, len, port; - char *tmp; - - len = strlen(spec); - p = strcspn(spec, ":"); - if (p < len-1) { - tmp = substr(spec, 0, p); - if (!so_resolv(&source, tmp)) { - syslog(LOG_ERR, "Cannot resolve listen address %s\n", tmp); - myexit(1); - } - free(tmp); - port = atoi(tmp = spec+p+1); - } else { - source.s_addr = htonl(gateway ? INADDR_ANY : INADDR_LOOPBACK); - port = atoi(tmp = spec); - } - - if (!port) { - syslog(LOG_ERR, "Invalid listen port %s.\n", tmp); - myexit(1); - } - - i = so_listen(port, source); - if (i > 0) { - *list = plist_add(*list, i, NULL); - syslog(LOG_INFO, "%s listening on %s:%d\n", service, inet_ntoa(source), port); - } -} - -/* - * Register a new tunnel definition, bind service port. - */ -void tunnel_add(plist_t *list, char *spec, int gateway) { - struct in_addr source; - int i, len, count, pos, port; - char *field[4]; - char *tmp; - - spec = strdup(spec); - len = strlen(spec); - field[0] = spec; - for (count = 1, i = 0; count < 4 && i < len; ++i) - if (spec[i] == ':') { - spec[i] = 0; - field[count++] = spec+i+1; - } - - pos = 0; - if (count == 4) { - if (!so_resolv(&source, field[pos])) { - syslog(LOG_ERR, "Cannot resolve tunel bind address: %s\n", field[pos]); - myexit(1); - } - pos++; - } else - source.s_addr = htonl(gateway ? INADDR_ANY : INADDR_LOOPBACK); - - if (count-pos == 3) { - port = atoi(field[pos]); - if (port == 0) { - syslog(LOG_ERR, "Invalid tunnel local port: %s\n", field[pos]); - myexit(1); - } - - if (!strlen(field[pos+1]) || !strlen(field[pos+2])) { - syslog(LOG_ERR, "Invalid tunnel target: %s:%s\n", field[pos+1], field[pos+2]); - myexit(1); - } - - tmp = new(strlen(field[pos+1]) + strlen(field[pos+2]) + 2 + 1); - strcpy(tmp, field[pos+1]); - strcat(tmp, ":"); - strcat(tmp, field[pos+2]); - - i = so_listen(port, source); - if (i > 0) { - *list = plist_add(*list, i, tmp); - syslog(LOG_INFO, "New tunnel from %s:%d to %s\n", inet_ntoa(source), port, tmp); - } else - free(tmp); - } else { - printf("Tunnel specification incorrect ([laddress:]lport:rserver:rport).\n"); - myexit(1); - } - - free(spec); -} - -/* - * Add no-proxy hostname/IP - */ -plist_t noproxy_add(plist_t list, char *spec) { - char *tok, *save; - - tok = strtok_r(spec, ", ", &save); - while ( tok != NULL ) { - if (debug) - printf("Adding no-proxy for: '%s'\n", tok); - list = plist_add(list, 0, strdup(tok)); - tok = strtok_r(NULL, ", ", &save); - } - - return list; -} - -int noproxy_match(const char *addr) { - plist_t list; - - list = noproxy_list; - while (list) { - if (list->aux && strlen(list->aux) - && fnmatch(list->aux, addr, 0) == 0) { - if (debug) - printf("MATCH: %s (%s)\n", addr, (char *)list->aux); - return 1; - } else if (debug) - printf(" NO: %s (%s)\n", addr, (char *)list->aux); - - list = list->next; - } - - return 0; -} - -/* - * Proxy thread - decide between direct and forward based on NoProxy - */ -void *proxy_thread(void *thread_data) { - rr_data_t request, ret; - int keep_alive; /* Proxy-Connection */ - - int cd = ((struct thread_arg_s *)thread_data)->fd; - - do { - ret = NULL; - keep_alive = 0; - - if (debug) { - printf("\n******* Round 1 C: %d *******\n", cd); - printf("Reading headers (%d)...\n", cd); - } - - request = new_rr_data(); - if (!headers_recv(cd, request)) { - free_rr_data(request); - break; - } - - do { - /* - * Are we being returned a request by forward_request or direct_request? - */ - if (ret) { - free_rr_data(request); - request = ret; - } - - keep_alive = hlist_subcmp(request->headers, "Proxy-Connection", "keep-alive"); - - if (noproxy_match(request->hostname)) - ret = direct_request(thread_data, request); - else - ret = forward_request(thread_data, request); - - if (debug) - printf("proxy_thread: request rc = %p\n", (void *)ret); - } while (ret != NULL && ret != (void *)-1); - - free_rr_data(request); - /* - * If client asked for proxy keep-alive, loop unless the last server response - * requested (Proxy-)Connection: close. - */ - } while (keep_alive && ret != (void *)-1 && !serialize); - - /* - * Add ourselves to the "threads to join" list. - */ - if (!serialize) { - pthread_mutex_lock(&threads_mtx); - threads_list = plist_add(threads_list, (unsigned long)pthread_self(), NULL); - pthread_mutex_unlock(&threads_mtx); - } - - free(thread_data); - close(cd); - - return NULL; -} - -/* - * Tunnel/port forward thread - this method is obviously better solution than using extra - * tools like "corkscrew" which after all require us for authentication and tunneling - * their HTTP CONNECT in the first place. - */ -void *tunnel_thread(void *thread_data) { - char *hostname, *pos; - char *thost = ((struct thread_arg_s *)thread_data)->target; - - hostname = strdup(thost); - if ((pos = strchr(hostname, ':')) != NULL) - *pos = 0; - - if (noproxy_match(hostname)) - direct_tunnel(thread_data); - else - forward_tunnel(thread_data); - - free(hostname); - free(thread_data); - - /* - * Add ourself to the "threads to join" list. - */ - pthread_mutex_lock(&threads_mtx); - threads_list = plist_add(threads_list, (unsigned long)pthread_self(), NULL); - pthread_mutex_unlock(&threads_mtx); - - return NULL; -} - -/* - * SOCKS5 thread - */ -void *socks5_thread(void *thread_data) { - char *tmp, *thost, *tport, *uname, *upass; - unsigned short port; - int ver, r, c, i, w; - - struct auth_s *tcreds = NULL; - unsigned char *bs = NULL, *auths = NULL, *addr = NULL; - int found = -1; - int sd = -1; - int open = !hlist_count(users_list); - - int cd = ((struct thread_arg_s *)thread_data)->fd; - struct sockaddr_in caddr = ((struct thread_arg_s *)thread_data)->addr; - free(thread_data); - - /* - * Check client's version, possibly fuck'em - */ - bs = (unsigned char *)new(10); - thost = new(MINIBUF_SIZE); - tport = new(MINIBUF_SIZE); - r = read(cd, bs, 2); - if (r != 2 || bs[0] != 5) - goto bailout; - - /* - * Read offered auth schemes - */ - c = bs[1]; - auths = (unsigned char *)new(c+1); - r = read(cd, auths, c); - if (r != c) - goto bailout; - - /* - * Are we wide open and client is OK with no auth? - */ - if (open) { - for (i = 0; i < c && (auths[i] || (found = 0)); ++i); - } - - /* - * If not, accept plain auth if offered - */ - if (found < 0) { - for (i = 0; i < c && (auths[i] != 2 || !(found = 2)); ++i); - } - - /* - * If not open and no auth offered or open and auth requested, fuck'em - * and complete the handshake - */ - if (found < 0) { - bs[0] = 5; - bs[1] = 0xFF; - w = write(cd, bs, 2); - goto bailout; - } else { - bs[0] = 5; - bs[1] = found; - w = write(cd, bs, 2); - } - - /* - * Plain auth negotiated? - */ - if (found != 0) { - /* - * Check ver and read username len - */ - r = read(cd, bs, 2); - if (r != 2) { - bs[0] = 1; - bs[1] = 0xFF; /* Unsuccessful (not supported) */ - w = write(cd, bs, 2); - goto bailout; - } - c = bs[1]; - - /* - * Read username and pass len - */ - uname = new(c+1); - r = read(cd, uname, c+1); - if (r != c+1) { - free(uname); - goto bailout; - } - i = uname[c]; - uname[c] = 0; - c = i; - - /* - * Read pass - */ - upass = new(c+1); - r = read(cd, upass, c); - if (r != c) { - free(upass); - free(uname); - goto bailout; - } - upass[c] = 0; - - /* - * Check credentials against the list - */ - tmp = hlist_get(users_list, uname); - if (!hlist_count(users_list) || (tmp && !strcmp(tmp, upass))) { - bs[0] = 1; - bs[1] = 0; /* Success */ - } else { - bs[0] = 1; - bs[1] = 0xFF; /* Failed */ - } - - /* - * Send response - */ - w = write(cd, bs, 2); - free(upass); - free(uname); - - /* - * Fuck'em if auth failed - */ - if (bs[1]) - goto bailout; - } - - /* - * Read request type - */ - r = read(cd, bs, 4); - if (r != 4) - goto bailout; - - /* - * Is it connect for supported address type (IPv4 or DNS)? If not, fuck'em - */ - if (bs[1] != 1 || (bs[3] != 1 && bs[3] != 3)) { - bs[0] = 5; - bs[1] = 2; /* Not allowed */ - bs[2] = 0; - bs[3] = 1; /* Dummy IPv4 */ - memset(bs+4, 0, 6); - w = write(cd, bs, 10); - goto bailout; - } - - /* - * Ok, it's connect to a domain or IP - * Let's read dest address - */ - if (bs[3] == 1) { - ver = 1; /* IPv4, we know the length */ - c = 4; - } else if (bs[3] == 3) { - ver = 2; /* FQDN, get string length */ - r = read(cd, &c, 1); - if (r != 1) - goto bailout; - } else - goto bailout; - - addr = (unsigned char *)new(c+10 + 1); - r = read(cd, addr, c); - if (r != c) - goto bailout; - addr[c] = 0; - - /* - * Convert the address to character string - */ - if (ver == 1) { - sprintf(thost, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); /* It's in network byte order */ - } else { - strlcpy(thost, (char *)addr, MINIBUF_SIZE); - } - - /* - * Read port number and convert to host byte order int - */ - r = read(cd, &port, 2); - if (r != 2) - goto bailout; - - i = 0; - if (noproxy_match(thost)) { - sd = host_connect(thost, ntohs(port)); - i = (sd >= 0); - } else { - sprintf(tport, "%d", ntohs(port)); - strlcat(thost, ":", MINIBUF_SIZE); - strlcat(thost, tport, MINIBUF_SIZE); - - tcreds = new_auth(); - sd = proxy_connect(tcreds); - if (sd >= 0) - i = prepare_http_connect(sd, tcreds, thost); - } - - /* - * Direct or proxy connect? - */ - if (!i) { - /* - * Connect/tunnel failed, report - */ - bs[0] = 5; - bs[1] = 1; /* General failure */ - bs[2] = 0; - bs[3] = 1; /* Dummy IPv4 */ - memset(bs+4, 0, 6); - w = write(cd, bs, 10); - goto bailout; - } else { - /* - * All right - */ - bs[0] = 5; - bs[1] = 0; /* Success */ - bs[2] = 0; - bs[3] = 1; /* Dummy IPv4 */ - memset(bs+4, 0, 6); - w = write(cd, bs, 10); - } - - syslog(LOG_DEBUG, "%s SOCKS %s", inet_ntoa(caddr.sin_addr), thost); - - /* - * Let's give them bi-directional connection they asked for - */ - tunnel(cd, sd); - -bailout: - if (addr) - free(addr); - if (auths) - free(auths); - if (thost) - free(thost); - if (tport) - free(tport); - if (bs) - free(bs); - if (tcreds) - free(tcreds); - if (sd) - close(sd); - close(cd); - - return NULL; -} - -int main(int argc, char **argv) { - char *tmp, *head; - char *cpassword, *cpassntlm2, *cpassnt, *cpasslm; - char *cuser, *cdomain, *cworkstation, *cuid, *cpidfile, *cauth; - struct passwd *pw; - struct termios termold, termnew; - pthread_attr_t pattr; - pthread_t pthr; - hlist_t list; - int i, w; - - int cd = 0; - int help = 0; - int nuid = 0; - int ngid = 0; - int gateway = 0; - int tc = 0; - int tj = 0; - int interactivepwd = 0; - int interactivehash = 0; - int tracefile = 0; - int cflags = 0; - int asdaemon = 1; - plist_t tunneld_list = NULL; - plist_t proxyd_list = NULL; - plist_t socksd_list = NULL; - plist_t rules = NULL; - config_t cf = NULL; - char *magic_detect = NULL; - - g_creds = new_auth(); - cuser = new(MINIBUF_SIZE); - cdomain = new(MINIBUF_SIZE); - cpassword = new(MINIBUF_SIZE); - cpassntlm2 = new(MINIBUF_SIZE); - cpassnt = new(MINIBUF_SIZE); - cpasslm = new(MINIBUF_SIZE); - cworkstation = new(MINIBUF_SIZE); - cpidfile = new(MINIBUF_SIZE); - cuid = new(MINIBUF_SIZE); - cauth = new(MINIBUF_SIZE); - - openlog("cntlm", LOG_CONS, LOG_DAEMON); - -#if config_endian == 0 - syslog(LOG_INFO, "Starting cntlm version " VERSION " for BIG endian\n"); -#else - syslog(LOG_INFO, "Starting cntlm version " VERSION " for LITTLE endian\n"); -#endif - - while ((i = getopt(argc, argv, ":-:a:c:d:fghIl:p:r:su:vw:A:BD:F:G:HL:M:N:O:P:R:S:T:U:")) != -1) { - switch (i) { - case 'A': - case 'D': - if (!acl_add(&rules, optarg, (i == 'A' ? ACL_ALLOW : ACL_DENY))) - myexit(1); - break; - case 'a': - strlcpy(cauth, optarg, MINIBUF_SIZE); - break; - case 'B': - ntlmbasic = 1; - break; - case 'c': - if (!(cf = config_open(optarg))) { - syslog(LOG_ERR, "Cannot access specified config file: %s\n", optarg); - myexit(1); - } - break; - case 'd': - strlcpy(cdomain, optarg, MINIBUF_SIZE); - break; - case 'F': - cflags = swap32(strtoul(optarg, &tmp, 0)); - break; - case 'f': - asdaemon = 0; - break; - case 'G': - if (strlen(optarg)) { - scanner_plugin = 1; - if (!scanner_plugin_maxsize) - scanner_plugin_maxsize = 1; - i = strlen(optarg) + 3; - tmp = new(i); - snprintf(tmp, i, "*%s*", optarg); - scanner_agent_list = plist_add(scanner_agent_list, 0, tmp); - } - break; - case 'g': - gateway = 1; - break; - case 'H': - interactivehash = 1; - break; - case 'I': - interactivepwd = 1; - break; - case 'L': - /* - * Parse and validate the argument. - * Create a listening socket for tunneling. - */ - tunnel_add(&tunneld_list, optarg, gateway); - break; - case 'l': - /* - * Create a listening socket for proxy function. - */ - listen_add("Proxy", &proxyd_list, optarg, gateway); - break; - case 'M': - magic_detect = strdup(optarg); - break; - case 'N': - noproxy_list = noproxy_add(noproxy_list, tmp=strdup(optarg)); - free(tmp); - break; - case 'O': - listen_add("SOCKS5 proxy", &socksd_list, optarg, gateway); - break; - case 'P': - strlcpy(cpidfile, optarg, MINIBUF_SIZE); - break; - case 'p': - /* - * Overwrite the password parameter with '*'s to make it - * invisible in "ps", /proc, etc. - */ - strlcpy(cpassword, optarg, MINIBUF_SIZE); - for (i = strlen(optarg)-1; i >= 0; --i) - optarg[i] = '*'; - break; - case 'R': - tmp = strdup(optarg); - head = strchr(tmp, ':'); - if (!head) { - fprintf(stderr, "Invalid username:password format for -R: %s\n", tmp); - } else { - head[0] = 0; - users_list = hlist_add(users_list, tmp, head+1, - HLIST_ALLOC, HLIST_ALLOC); - } - break; - case 'r': - if (is_http_header(optarg)) - header_list = hlist_add(header_list, - get_http_header_name(optarg), - get_http_header_value(optarg), - HLIST_NOALLOC, HLIST_NOALLOC); - break; - case 'S': - scanner_plugin = 1; - scanner_plugin_maxsize = atol(optarg); - break; - case 's': - /* - * Do not use threads - for debugging purposes only - */ - serialize = 1; - break; - case 'T': - tracefile = open(optarg, O_CREAT | O_TRUNC | O_WRONLY, 0600); - if (tracefile < 0) { - fprintf(stderr, "Cannot create trace file.\n"); - myexit(1); - } else { - printf("Redirecting all output to %s\n", optarg); - dup2(tracefile, 1); - dup2(tracefile, 2); - printf("Cntlm debug trace, version " VERSION); -#ifdef __CYGWIN__ - printf(" windows/cygwin port"); -#endif - printf(".\nCommand line: "); - for (i = 0; i < argc; ++i) - printf("%s ", argv[i]); - printf("\n"); - } - break; - case 'U': - strlcpy(cuid, optarg, MINIBUF_SIZE); - break; - case 'u': - i = strcspn(optarg, "@"); - if (i != strlen(optarg)) { - strlcpy(cuser, optarg, MIN(MINIBUF_SIZE, i+1)); - strlcpy(cdomain, optarg+i+1, MINIBUF_SIZE); - } else { - strlcpy(cuser, optarg, MINIBUF_SIZE); - } - break; - case 'v': - debug = 1; - asdaemon = 0; - openlog("cntlm", LOG_CONS | LOG_PERROR, LOG_DAEMON); - break; - case 'w': - strlcpy(cworkstation, optarg, MINIBUF_SIZE); - break; - case 'h': - default: - help = 1; - } - } - - /* - * Help requested? - */ - if (help) { - printf("CNTLM - Accelerating NTLM Authentication Proxy version " VERSION "\n"); - printf("Copyright (c) 2oo7-2o1o David Kubicek\n\n" - "This program comes with NO WARRANTY, to the extent permitted by law. You\n" - "may redistribute copies of it under the terms of the GNU GPL Version 2 or\n" - "newer. For more information about these matters, see the file LICENSE.\n" - "For copyright holders of included encryption routines see headers.\n\n"); - - fprintf(stderr, "Usage: %s [-AaBcDdFfgHhILlMPpSsTUuvw] [:] ...\n", argv[0]); - fprintf(stderr, "\t-A
[/]\n" - "\t ACL allow rule. IP or hostname, net must be a number (CIDR notation)\n"); - fprintf(stderr, "\t-a ntlm | nt | lm\n" - "\t Authentication type - combined NTLM, just LM, or just NT. Default NTLM.\n" - "\t It is the most versatile setting and likely to work for you.\n"); - fprintf(stderr, "\t-B Enable NTLM-to-basic authentication.\n"); - fprintf(stderr, "\t-c \n" - "\t Configuration file. Other arguments can be used as well, overriding\n" - "\t config file settings.\n"); - fprintf(stderr, "\t-D
[/]\n" - "\t ACL deny rule. Syntax same as -A.\n"); - fprintf(stderr, "\t-d \n" - "\t Domain/workgroup can be set separately.\n"); - fprintf(stderr, "\t-f Run in foreground, do not fork into daemon mode.\n"); - fprintf(stderr, "\t-F \n" - "\t NTLM authentication flags.\n"); - fprintf(stderr, "\t-G \n" - "\t User-Agent matching for the trans-isa-scan plugin.\n"); - fprintf(stderr, "\t-g Gateway mode - listen on all interfaces, not only loopback.\n"); - fprintf(stderr, "\t-H Print password hashes for use in config file (NTLMv2 needs -u and -d).\n"); - fprintf(stderr, "\t-h Print this help info along with version number.\n"); - fprintf(stderr, "\t-I Prompt for the password interactively.\n"); - fprintf(stderr, "\t-L [:]::\n" - "\t Forwarding/tunneling a la OpenSSH. Same syntax - listen on lport\n" - "\t and forward all connections through the proxy to rhost:rport.\n" - "\t Can be used for direct tunneling without corkscrew, etc.\n"); - fprintf(stderr, "\t-l [:]\n" - "\t Main listening port for the NTLM proxy.\n"); - fprintf(stderr, "\t-M \n" - "\t Magic autodetection of proxy's NTLM dialect.\n"); - fprintf(stderr, "\t-N \"[, \"\n" - "\t List of URL's to serve direcly as stand-alone proxy (e.g. '*.local')\n"); - fprintf(stderr, "\t-O [:]\n" - "\t Enable SOCKS5 proxy on port lport (binding to address saddr)\n"); - fprintf(stderr, "\t-P \n" - "\t Create a PID file upon successful start.\n"); - fprintf(stderr, "\t-p \n" - "\t Account password. Will not be visible in \"ps\", /proc, etc.\n"); - fprintf(stderr, "\t-r \"HeaderName: value\"\n" - "\t Add a header substitution. All such headers will be added/replaced\n" - "\t in the client's requests.\n"); - fprintf(stderr, "\t-S \n" - "\t Enable automation of GFI WebMonitor ISA scanner for files < size_in_kb.\n"); - fprintf(stderr, "\t-s Do not use threads, serialize all requests - for debugging only.\n"); - fprintf(stderr, "\t-U \n" - "\t Run as uid. It is an important security measure not to run as root.\n"); - fprintf(stderr, "\t-u [@\n" - "\t Some proxies require correct NetBIOS hostname.\n\n"); - exit(1); - } - - /* - * More arguments on the command-line? Must be proxies. - */ - i = optind; - while (i < argc) { - tmp = strchr(argv[i], ':'); - parent_add(argv[i], !tmp && i+1 < argc ? atoi(argv[i+1]) : 0); - i += (!tmp ? 2 : 1); - } - - /* - * No configuration file yet? Load the default. - */ -#ifdef SYSCONFDIR - if (!cf) { -#ifdef __CYGWIN__ - tmp = getenv("PROGRAMFILES(X86)"); - if (tmp == NULL || strlen(tmp) == 0) - tmp = getenv("PROGRAMFILES"); - if (tmp == NULL) - tmp = "C:\\Program Files"; - - head = new(MINIBUF_SIZE); - strlcpy(head, tmp, MINIBUF_SIZE); - strlcat(head, "\\Cntlm\\cntlm.ini", MINIBUF_SIZE); - cf = config_open(head); -#else - cf = config_open(SYSCONFDIR "/cntlm.conf"); -#endif - if (debug) { - if (cf) - printf("Default config file opened successfully\n"); - else - syslog(LOG_ERR, "Could not open default config file\n"); - } - } -#endif - - /* - * If any configuration file was successfully opened, parse it. - */ - if (cf) { - /* - * Check if gateway mode is requested before actually binding any ports. - */ - tmp = new(MINIBUF_SIZE); - CFG_DEFAULT(cf, "Gateway", tmp, MINIBUF_SIZE); - if (!strcasecmp("yes", tmp)) - gateway = 1; - free(tmp); - - /* - * Check for NTLM-to-basic settings - */ - tmp = new(MINIBUF_SIZE); - CFG_DEFAULT(cf, "NTLMToBasic", tmp, MINIBUF_SIZE); - if (!strcasecmp("yes", tmp)) - ntlmbasic = 1; - free(tmp); - - /* - * Setup the rest of tunnels. - */ - while ((tmp = config_pop(cf, "Tunnel"))) { - tunnel_add(&tunneld_list, tmp, gateway); - free(tmp); - } - - /* - * Bind the rest of proxy service ports. - */ - while ((tmp = config_pop(cf, "Listen"))) { - listen_add("Proxy", &proxyd_list, tmp, gateway); - free(tmp); - } - - /* - * Bind the rest of SOCKS5 service ports. - */ - while ((tmp = config_pop(cf, "SOCKS5Proxy"))) { - listen_add("SOCKS5 proxy", &socksd_list, tmp, gateway); - free(tmp); - } - - /* - * Accept only headers not specified on the command line. - * Command line has higher priority. - */ - while ((tmp = config_pop(cf, "Header"))) { - if (is_http_header(tmp)) { - head = get_http_header_name(tmp); - if (!hlist_in(header_list, head)) - header_list = hlist_add(header_list, head, get_http_header_value(tmp), - HLIST_ALLOC, HLIST_NOALLOC); - free(head); - } else - syslog(LOG_ERR, "Invalid header format: %s\n", tmp); - - free(tmp); - } - - /* - * Add the rest of parent proxies. - */ - while ((tmp = config_pop(cf, "Proxy"))) { - parent_add(tmp, 0); - free(tmp); - } - - /* - * No ACLs on the command line? Use config file. - */ - if (rules == NULL) { - list = cf->options; - while (list) { - if (!(i=strcasecmp("Allow", list->key)) || !strcasecmp("Deny", list->key)) - if (!acl_add(&rules, list->value, i ? ACL_DENY : ACL_ALLOW)) - myexit(1); - list = list->next; - } - - while ((tmp = config_pop(cf, "Allow"))) - free(tmp); - while ((tmp = config_pop(cf, "Deny"))) - free(tmp); - } - - /* - * Single options. - */ - CFG_DEFAULT(cf, "Auth", cauth, MINIBUF_SIZE); - CFG_DEFAULT(cf, "Domain", cdomain, MINIBUF_SIZE); - CFG_DEFAULT(cf, "Password", cpassword, MINIBUF_SIZE); - CFG_DEFAULT(cf, "PassNTLMv2", cpassntlm2, MINIBUF_SIZE); - CFG_DEFAULT(cf, "PassNT", cpassnt, MINIBUF_SIZE); - CFG_DEFAULT(cf, "PassLM", cpasslm, MINIBUF_SIZE); - CFG_DEFAULT(cf, "Username", cuser, MINIBUF_SIZE); - CFG_DEFAULT(cf, "Workstation", cworkstation, MINIBUF_SIZE); - - tmp = new(MINIBUF_SIZE); - CFG_DEFAULT(cf, "Flags", tmp, MINIBUF_SIZE); - if (!cflags) - cflags = swap32(strtoul(tmp, NULL, 0)); - free(tmp); - - tmp = new(MINIBUF_SIZE); - CFG_DEFAULT(cf, "ISAScannerSize", tmp, MINIBUF_SIZE); - if (!scanner_plugin_maxsize && strlen(tmp)) { - scanner_plugin = 1; - scanner_plugin_maxsize = atoi(tmp); - } - free(tmp); - - while ((tmp = config_pop(cf, "NoProxy"))) { - if (strlen(tmp)) { - noproxy_list = noproxy_add(noproxy_list, tmp); - } - free(tmp); - } - - while ((tmp = config_pop(cf, "SOCKS5Users"))) { - head = strchr(tmp, ':'); - if (!head) { - syslog(LOG_ERR, "Invalid username:password format for SOCKS5User: %s\n", tmp); - } else { - head[0] = 0; - users_list = hlist_add(users_list, tmp, head+1, HLIST_ALLOC, HLIST_ALLOC); - } - } - - - /* - * Add User-Agent matching patterns. - */ - while ((tmp = config_pop(cf, "ISAScannerAgent"))) { - scanner_plugin = 1; - if (!scanner_plugin_maxsize) - scanner_plugin_maxsize = 1; - - if ((i = strlen(tmp))) { - head = new(i + 3); - snprintf(head, i+3, "*%s*", tmp); - scanner_agent_list = plist_add(scanner_agent_list, 0, head); - } - free(tmp); - } - - /* - * Print out unused/unknown options. - */ - list = cf->options; - while (list) { - syslog(LOG_INFO, "Ignoring config file option: %s\n", list->key); - list = list->next; - } - } - - config_close(cf); - - if (!interactivehash && !parent_list) - croak("Parent proxy address missing.\n", interactivepwd || magic_detect); - - if (!interactivehash && !magic_detect && !proxyd_list) - croak("No proxy service ports were successfully opened.\n", interactivepwd); - - /* - * Set default value for the workstation. Hostname if possible. - */ - if (!strlen(cworkstation)) { -#if config_gethostname == 1 - gethostname(cworkstation, MINIBUF_SIZE); -#endif - if (!strlen(cworkstation)) - strlcpy(cworkstation, "cntlm", MINIBUF_SIZE); - - syslog(LOG_INFO, "Workstation name used: %s\n", cworkstation); - } - - /* - * Parse selected NTLM hash combination. - */ - if (strlen(cauth)) { - if (!strcasecmp("ntlm", cauth)) { - g_creds->hashnt = 1; - g_creds->hashlm = 1; - g_creds->hashntlm2 = 0; - } else if (!strcasecmp("nt", cauth)) { - g_creds->hashnt = 1; - g_creds->hashlm = 0; - g_creds->hashntlm2 = 0; - } else if (!strcasecmp("lm", cauth)) { - g_creds->hashnt = 0; - g_creds->hashlm = 1; - g_creds->hashntlm2 = 0; - } else if (!strcasecmp("ntlmv2", cauth)) { - g_creds->hashnt = 0; - g_creds->hashlm = 0; - g_creds->hashntlm2 = 1; - } else if (!strcasecmp("ntlm2sr", cauth)) { - g_creds->hashnt = 2; - g_creds->hashlm = 0; - g_creds->hashntlm2 = 0; - } else { - syslog(LOG_ERR, "Unknown NTLM auth combination.\n"); - myexit(1); - } - } - - if (socksd_list && !users_list) - syslog(LOG_WARNING, "SOCKS5 proxy will NOT require any authentication\n"); - - if (!magic_detect) - syslog(LOG_INFO, "Using following NTLM hashes: NTLMv2(%d) NT(%d) LM(%d)\n", - g_creds->hashntlm2, g_creds->hashnt, g_creds->hashlm); - - if (cflags) { - syslog(LOG_INFO, "Using manual NTLM flags: 0x%X\n", swap32(cflags)); - g_creds->flags = cflags; - } - - /* - * Last chance to get password from the user - */ - if (interactivehash || magic_detect || (interactivepwd && !ntlmbasic)) { - printf("Password: "); - tcgetattr(0, &termold); - termnew = termold; - termnew.c_lflag &= ~(ISIG | ECHO); - tcsetattr(0, TCSADRAIN, &termnew); - tmp = fgets(cpassword, MINIBUF_SIZE, stdin); - tcsetattr(0, TCSADRAIN, &termold); - i = strlen(cpassword) - 1; - if (cpassword[i] == '\n') { - cpassword[i] = 0; - if (cpassword[i - 1] == '\r') - cpassword[i - 1] = 0; - } - printf("\n"); - } - - /* - * Convert optional PassNT, PassLM and PassNTLMv2 strings to hashes - * unless plaintext pass was used, which has higher priority. - * - * If plain password is present, calculate its NT and LM hashes - * and remove it from the memory. - */ - if (!strlen(cpassword)) { - if (strlen(cpassntlm2)) { - tmp = scanmem(cpassntlm2, 8); - if (!tmp) { - syslog(LOG_ERR, "Invalid PassNTLMv2 hash, terminating\n"); - exit(1); - } - auth_memcpy(g_creds, passntlm2, tmp, 16); - free(tmp); - } - if (strlen(cpassnt)) { - tmp = scanmem(cpassnt, 8); - if (!tmp) { - syslog(LOG_ERR, "Invalid PassNT hash, terminating\n"); - exit(1); - } - auth_memcpy(g_creds, passnt, tmp, 16); - free(tmp); - } - if (strlen(cpasslm)) { - tmp = scanmem(cpasslm, 8); - if (!tmp) { - syslog(LOG_ERR, "Invalid PassLM hash, terminating\n"); - exit(1); - } - auth_memcpy(g_creds, passlm, tmp, 16); - free(tmp); - } - } else { - if (g_creds->hashnt || magic_detect || interactivehash) { - tmp = ntlm_hash_nt_password(cpassword); - auth_memcpy(g_creds, passnt, tmp, 21); - free(tmp); - } if (g_creds->hashlm || magic_detect || interactivehash) { - tmp = ntlm_hash_lm_password(cpassword); - auth_memcpy(g_creds, passlm, tmp, 21); - free(tmp); - } if (g_creds->hashntlm2 || magic_detect || interactivehash) { - tmp = ntlm2_hash_password(cuser, cdomain, cpassword); - auth_memcpy(g_creds, passntlm2, tmp, 16); - free(tmp); - } - memset(cpassword, 0, strlen(cpassword)); - } - - auth_strcpy(g_creds, user, cuser); - auth_strcpy(g_creds, domain, cdomain); - auth_strcpy(g_creds, workstation, cworkstation); - - free(cuser); - free(cdomain); - free(cworkstation); - free(cpassword); - free(cpassntlm2); - free(cpassnt); - free(cpasslm); - free(cauth); - - /* - * Try known NTLM auth combinations and print which ones work. - * User can pick the best (most secure) one as his config. - */ - if (magic_detect) { - magic_auth_detect(magic_detect); - goto bailout; - } - - if (interactivehash) { - if (g_creds->passlm) { - tmp = printmem(g_creds->passlm, 16, 8); - printf("PassLM %s\n", tmp); - free(tmp); - } - - if (g_creds->passnt) { - tmp = printmem(g_creds->passnt, 16, 8); - printf("PassNT %s\n", tmp); - free(tmp); - } - - if (g_creds->passntlm2) { - tmp = printmem(g_creds->passntlm2, 16, 8); - printf("PassNTLMv2 %s # Only for user '%s', domain '%s'\n", - tmp, g_creds->user, g_creds->domain); - free(tmp); - } - goto bailout; - } - - /* - * If we're going to need a password, check we really have it. - */ - if (!ntlmbasic && ( - (g_creds->hashnt && !g_creds->passnt) - || (g_creds->hashlm && !g_creds->passlm) - || (g_creds->hashntlm2 && !g_creds->passntlm2))) { - syslog(LOG_ERR, "Parent proxy account password (or required hashes) missing.\n"); - myexit(1); - } - - /* - * Ok, we are ready to rock. If daemon mode was requested, - * fork and die. The child will not be group leader anymore - * and can thus create a new session for itself and detach - * from the controlling terminal. - */ - if (asdaemon) { - if (debug) - printf("Forking into background as requested.\n"); - - i = fork(); - if (i == -1) { - perror("Fork into background failed"); /* fork failed */ - myexit(1); - } else if (i) - myexit(0); /* parent */ - - setsid(); - umask(0); - w = chdir("/"); - i = open("/dev/null", O_RDWR); - if (i >= 0) { - dup2(i, 0); - dup2(i, 1); - dup2(i, 2); - if (i > 2) - close(i); - } - } - - /* - * Reinit syslog logging to include our PID, after forking - * it is going to be OK - */ - if (asdaemon) { - openlog("cntlm", LOG_CONS | LOG_PID, LOG_DAEMON); - syslog(LOG_INFO, "Daemon ready"); - } else { - openlog("cntlm", LOG_CONS | LOG_PID | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "Cntlm ready, staying in the foreground"); - } - - /* - * Check and change UID. - */ - if (strlen(cuid)) { - if (getuid() && geteuid()) { - syslog(LOG_WARNING, "No root privileges; keeping identity %d:%d\n", getuid(), getgid()); - } else { - if (isdigit(cuid[0])) { - nuid = atoi(cuid); - ngid = nuid; - if (nuid <= 0) { - syslog(LOG_ERR, "Numerical uid parameter invalid\n"); - myexit(1); - } - } else { - pw = getpwnam(cuid); - if (!pw || !pw->pw_uid) { - syslog(LOG_ERR, "Username %s in -U is invalid\n", cuid); - myexit(1); - } - nuid = pw->pw_uid; - ngid = pw->pw_gid; - } - setgid(ngid); - i = setuid(nuid); - syslog(LOG_INFO, "Changing uid:gid to %d:%d - %s\n", nuid, ngid, strerror(errno)); - if (i) { - syslog(LOG_ERR, "Terminating\n"); - myexit(1); - } - } - } - - /* - * PID file requested? Try to create one (it must not exist). - * If we fail, exit with error. - */ - if (strlen(cpidfile)) { - umask(0); - cd = open(cpidfile, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (cd < 0) { - syslog(LOG_ERR, "Error creating a new PID file\n"); - myexit(1); - } - - tmp = new(50); - snprintf(tmp, 50, "%d\n", getpid()); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - close(cd); - } - - /* - * Change the handler for signals recognized as clean shutdown. - * When the handler is called (termination request), it signals - * this news by adding 1 to the global quit variable. - */ - signal(SIGPIPE, SIG_IGN); - signal(SIGINT, &sighandler); - signal(SIGTERM, &sighandler); - signal(SIGHUP, &sighandler); - - /* - * Initialize the random number generator - */ - srandom(time(NULL)); - - /* - * This loop iterates over every connection request on any of - * the listening ports. We keep the number of created threads. - * - * We also check the "finished threads" list, threads_list, here and - * free the memory of all inactive threads. Then, we update the - * number of finished threads. - * - * The loop ends, when we were "killed" and all threads created - * are finished, OR if we were killed more than once. This way, - * we have a "clean" shutdown (wait for all connections to finish - * after the first kill) and a "forced" one (user insists and - * killed us twice). - */ - while (quit == 0 || (tc != tj && quit < 2)) { - struct thread_arg_s *data; - struct sockaddr_in caddr; - struct timeval tv; - socklen_t clen; - fd_set set; - plist_t t; - int tid = 0; - - FD_ZERO(&set); - - /* - * Watch for proxy ports. - */ - t = proxyd_list; - while (t) { - FD_SET(t->key, &set); - t = t->next; - } - - /* - * Watch for SOCKS5 ports. - */ - t = socksd_list; - while (t) { - FD_SET(t->key, &set); - t = t->next; - } - - /* - * Watch for tunneled ports. - */ - t = tunneld_list; - while (t) { - FD_SET(t->key, &set); - t = t->next; - } - - tv.tv_sec = 1; - tv.tv_usec = 0; - - /* - * Wait here for data (connection request) on any of the listening - * sockets. When ready, establish the connection. For the main - * port, a new proxy_thread() thread is spawned to service the HTTP - * request. For tunneled ports, tunnel_thread() thread is created - * and for SOCKS port, socks5_thread() is created. - * - * All threads are defined in forward.c, except for local proxy_thread() - * which routes the request as forwarded or direct, depending on the - * URL host name and NoProxy settings. - */ - cd = select(FD_SETSIZE, &set, NULL, NULL, &tv); - if (cd > 0) { - for (i = 0; i < FD_SETSIZE; ++i) { - if (!FD_ISSET(i, &set)) - continue; - - clen = sizeof(caddr); - cd = accept(i, (struct sockaddr *)&caddr, (socklen_t *)&clen); - - if (cd < 0) { - syslog(LOG_ERR, "Serious error during accept: %s\n", strerror(errno)); - continue; - } - - /* - * Check main access control list. - */ - if (acl_check(rules, caddr.sin_addr) != ACL_ALLOW) { - syslog(LOG_WARNING, "Connection denied for %s:%d\n", - inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port)); - tmp = gen_denied_page(inet_ntoa(caddr.sin_addr)); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - close(cd); - continue; - } - - /* - * Log peer IP if it's not localhost - * - * if (debug || (gateway && caddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK))) - * syslog(LOG_INFO, "Connection accepted from %s:%d\n", - * inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port)); - */ - - pthread_attr_init(&pattr); - pthread_attr_setstacksize(&pattr, STACK_SIZE); -#ifndef __CYGWIN__ - pthread_attr_setguardsize(&pattr, 256); -#endif - - if (plist_in(proxyd_list, i)) { - data = (struct thread_arg_s *)new(sizeof(struct thread_arg_s)); - data->fd = cd; - data->addr = caddr; - if (!serialize) - tid = pthread_create(&pthr, &pattr, proxy_thread, (void *)data); - else - proxy_thread((void *)data); - } else if (plist_in(socksd_list, i)) { - data = (struct thread_arg_s *)new(sizeof(struct thread_arg_s)); - data->fd = cd; - data->addr = caddr; - tid = pthread_create(&pthr, &pattr, socks5_thread, (void *)data); - } else { - data = (struct thread_arg_s *)new(sizeof(struct thread_arg_s)); - data->fd = cd; - data->addr = caddr; - data->target = plist_get(tunneld_list, i); - tid = pthread_create(&pthr, &pattr, tunnel_thread, (void *)data); - } - - pthread_attr_destroy(&pattr); - - if (tid) - syslog(LOG_ERR, "Serious error during pthread_create: %d\n", tid); - else - tc++; - } - } else if (cd < 0 && !quit) - syslog(LOG_ERR, "Serious error during select: %s\n", strerror(errno)); - - if (threads_list) { - pthread_mutex_lock(&threads_mtx); - t = threads_list; - while (t) { - plist_t tmp = t->next; - tid = pthread_join((pthread_t)t->key, (void *)&i); - - if (!tid) { - tj++; - if (debug) - printf("Joining thread %lu; rc: %d\n", t->key, i); - } else - syslog(LOG_ERR, "Serious error during pthread_join: %d\n", tid); - - free(t); - t = tmp; - } - threads_list = NULL; - pthread_mutex_unlock(&threads_mtx); - } - } - -bailout: - if (strlen(cpidfile)) - unlink(cpidfile); - - syslog(LOG_INFO, "Terminating with %d active threads\n", tc - tj); - pthread_mutex_lock(&connection_mtx); - plist_free(connection_list); - pthread_mutex_unlock(&connection_mtx); - - hlist_free(header_list); - plist_free(scanner_agent_list); - plist_free(noproxy_list); - plist_free(tunneld_list); - plist_free(proxyd_list); - plist_free(socksd_list); - plist_free(rules); - - free(cuid); - free(cpidfile); - free(magic_detect); - free(g_creds); - - plist_free(parent_list); - - exit(0); -} - diff --git a/files/cntlm-0.92.3/ntlm.c b/files/cntlm-0.92.3/ntlm.c deleted file mode 100644 index dd04864..0000000 --- a/files/cntlm-0.92.3/ntlm.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * These are NTLM authentication routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include - -#include "ntlm.h" -#include "swap.h" -#include "xcrypt.h" -#include "utils.h" -#include "auth.h" - -extern int debug; - -static void ntlm_set_key(unsigned char *src, gl_des_ctx *context) { - char key[8]; - - key[0] = src[0]; - key[1] = ((src[0] << 7) & 0xff) | (src[1] >> 1); - key[2] = ((src[1] << 6) & 0xff) | (src[2] >> 2); - key[3] = ((src[2] << 5) & 0xff) | (src[3] >> 3); - key[4] = ((src[3] << 4) & 0xff) | (src[4] >> 4); - key[5] = ((src[4] << 3) & 0xff) | (src[5] >> 5); - key[6] = ((src[5] << 2) & 0xff) | (src[6] >> 6); - key[7] = (src[6] << 1) & 0xff; - - gl_des_setkey(context, key); -} - -static int ntlm_calc_resp(char **dst, char *keys, char *challenge) { - gl_des_ctx context; - - *dst = new(24 + 1); - - ntlm_set_key(MEM(keys, unsigned char, 0), &context); - gl_des_ecb_encrypt(&context, challenge, *dst); - - ntlm_set_key(MEM(keys, unsigned char, 7), &context); - gl_des_ecb_encrypt(&context, challenge, *dst+8); - - ntlm_set_key(MEM(keys, unsigned char, 14), &context); - gl_des_ecb_encrypt(&context, challenge, *dst+16); - - return 24; -} - -static void ntlm2_calc_resp(char **nthash, int *ntlen, char **lmhash, int *lmlen, - char *passnt2, char *challenge, int tbofs, int tblen) { - char *tmp, *blob, *nonce, *buf; - int64_t tw; - int blen; - - nonce = new(8 + 1); - VAL(nonce, uint64_t, 0) = ((uint64_t)random() << 32) | random(); - tw = ((uint64_t)time(NULL) + 11644473600LLU) * 10000000LLU; - - if (debug) { - tmp = printmem(nonce, 8, 7); -#ifdef PRId64 - printf("NTLMv2:\n\t Nonce: %s\n\tTimestamp: %"PRId64"\n", tmp, tw); -#else - printf("NTLMv2:\n\t Nonce: %s\n\tTimestamp: %ld\n", tmp, tw); -#endif - free(tmp); - } - - blob = new(4+4+8+8+4+tblen+4 + 1); - VAL(blob, uint32_t, 0) = U32LE(0x00000101); - VAL(blob, uint32_t, 4) = U32LE(0); - VAL(blob, uint64_t, 8) = U64LE(tw); - VAL(blob, uint64_t, 16) = U64LE(VAL(nonce, uint64_t, 0)); - VAL(blob, uint32_t, 24) = U32LE(0); - memcpy(blob+28, MEM(challenge, char, tbofs), tblen); - VAL(blob, uint32_t, 28+tblen) = U32LE(0); - blen = 28+tblen+4; - - if (0 && debug) { - tmp = printmem(blob, blen, 7); - printf("\t Blob: %s (%d)\n", tmp, blen); - free(tmp); - } - - *ntlen = 16+blen; - *nthash = new(*ntlen + 1); - buf = new(8+blen + 1); - memcpy(buf, MEM(challenge, char, 24), 8); - memcpy(buf+8, blob, blen); - hmac_md5(passnt2, 16, buf, 8+blen, *nthash); - memcpy(*nthash+16, blob, blen); - free(buf); - - *lmlen = 24; - *lmhash = new(*lmlen + 1); - buf = new(16 + 1); - memcpy(buf, MEM(challenge, char, 24), 8); - memcpy(buf+8, nonce, 8); - hmac_md5(passnt2, 16, buf, 16, *lmhash); - memcpy(*lmhash+16, nonce, 8); - free(buf); - - free(blob); - free(nonce); - return; -} - -static void ntlm2sr_calc_rest(char **nthash, int *ntlen, char **lmhash, int *lmlen, char *passnt, char *challenge) { - char *sess, *nonce, *buf; - - nonce = new(8 + 1); - VAL(nonce, uint64_t, 0) = ((uint64_t)random() << 32) | random(); - - *lmlen = 24; - *lmhash = new(*lmlen + 1); - memcpy(*lmhash, nonce, 8); - memset(*lmhash+8, 0, 16); - - buf = new(16 + 1); - sess = new(16 + 1); - memcpy(buf, MEM(challenge, char, 24), 8); - memcpy(buf+8, nonce, 8); - md5_buffer(buf, 16, sess); - free(buf); - - *ntlen = 24; - ntlm_calc_resp(nthash, passnt, sess); - - free(sess); - free(nonce); - return; -} - -char *ntlm_hash_lm_password(char *password) { - char magic[8] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - gl_des_ctx context; - char *keys, *pass; - - keys = new(21 + 1); - pass = new(14 + 1); - uppercase(strncpy(pass, password, MIN(14, strlen(password)))); - - ntlm_set_key(MEM(pass, unsigned char, 0), &context); - gl_des_ecb_encrypt(&context, magic, keys); - - ntlm_set_key(MEM(pass, unsigned char, 7), &context); - gl_des_ecb_encrypt(&context, magic, keys+8); - - memset(keys+16, 0, 5); - memset(pass, 0, 14); - free(pass); - - return keys; -} - -char *ntlm_hash_nt_password(char *password) { - char *u16, *keys; - int len; - - keys = new(21 + 1); - len = unicode(&u16, password); - md4_buffer(u16, len, keys); - - memset(keys+16, 0, 5); - memset(u16, 0, len); - free(u16); - - return keys; -} - -char *ntlm2_hash_password(char *username, char *domain, char *password) { - char *tmp, *buf, *passnt, *passnt2; - int len; - - passnt = ntlm_hash_nt_password(password); - - buf = new(strlen(username)+strlen(domain) + 1); - strcat(buf, username); - strcat(buf, domain); - uppercase(buf); - len = unicode(&tmp, buf); - - passnt2 = new(16 + 1); - hmac_md5(passnt, 16, tmp, len, passnt2); - - free(passnt); - free(tmp); - free(buf); - - return passnt2; -} - -int ntlm_request(char **dst, struct auth_s *creds) { - char *buf, *tmp; - int dlen, hlen; - uint32_t flags = 0xb206; - - *dst = NULL; - dlen = strlen(creds->domain); - hlen = strlen(creds->workstation); - - if (!creds->flags) { - if (creds->hashntlm2) - flags = 0xa208b205; - else if (creds->hashnt == 2) - flags = 0xa208b207; - else if (creds->hashnt && creds->hashlm) - flags = 0xb207; - else if (creds->hashnt) - flags = 0xb205; - else if (creds->hashlm) - flags = 0xb206; - else { - if (debug) { - printf("You're requesting with empty auth_s?!\n"); - dump_auth(creds); - } - return 0; - } - } else - flags = creds->flags; - - if (debug) { - printf("NTLM Request:\n"); - printf("\t Domain: %s\n", creds->domain); - printf("\t Hostname: %s\n", creds->workstation); - printf("\t Flags: 0x%X\n", (int)flags); - } - - buf = new(NTLM_BUFSIZE); - memcpy(buf, "NTLMSSP\0", 8); - VAL(buf, uint32_t, 8) = U32LE(1); - VAL(buf, uint32_t, 12) = U32LE(flags); - VAL(buf, uint16_t, 16) = U16LE(dlen); - VAL(buf, uint16_t, 18) = U16LE(dlen); - VAL(buf, uint32_t, 20) = U32LE(32 + hlen); - VAL(buf, uint16_t, 24) = U16LE(hlen); - VAL(buf, uint16_t, 26) = U16LE(hlen); - VAL(buf, uint32_t, 28) = U32LE(32); - - tmp = uppercase(strdup(creds->workstation)); - memcpy(buf+32, tmp, hlen); - free(tmp); - - tmp = uppercase(strdup(creds->domain)); - memcpy(buf+32+hlen, tmp, dlen); - free(tmp); - - *dst = buf; - return 32+dlen+hlen; -} - -static char *printuc(char *src, int len) { - char *tmp; - int i; - - tmp = new((len+1)/2 + 1); - for (i = 0; i < len/2; ++i) { - tmp[i] = src[i*2]; - } - - return tmp; -} - -/* -void dump(char *src, int len) { - int i, j; - char *tmp; - - tmp = new(len*3+4); - for (i = 0; i < len; ++i) { - snprintf(tmp+i*3, 4, "%0hhX ", src[i]); - printf("%c ", src[i]); - } - printf("\n%s\n", tmp); - free(tmp); -} -*/ - -int ntlm_response(char **dst, char *challenge, int challen, struct auth_s *creds) { - char *buf, *udomain, *uuser, *uhost, *tmp; - int dlen, ulen, hlen; - uint16_t tpos, tlen, ttype = -1, tbofs = 0, tblen = 0; - char *lmhash = NULL, *nthash = NULL; - int lmlen = 0, ntlen = 0; - - if (debug) { - printf("NTLM Challenge:\n"); - tmp = printmem(MEM(challenge, char, 24), 8, 7); - printf("\tChallenge: %s (len: %d)\n", tmp, challen); - free(tmp); - printf("\t Flags: 0x%X\n", U32LE(VAL(challenge, uint32_t, 20))); - } - - if (challen > 48) { - tbofs = tpos = U16LE(VAL(challenge, uint16_t, 44)); - while (tpos+4 <= challen && (ttype = U16LE(VAL(challenge, uint16_t, tpos)))) { - tlen = U16LE(VAL(challenge, uint16_t, tpos+2)); - if (tpos+4+tlen > challen) - break; - - if (debug) { - switch (ttype) { - case 0x1: - printf("\t Server: "); - break; - case 0x2: - printf("\tNT domain: "); - break; - case 0x3: - printf("\t FQDN: "); - break; - case 0x4: - printf("\t Domain: "); - break; - case 0x5: - printf("\t TLD: "); - break; - default: - printf("\t %3d: ", ttype); - break; - } - tmp = printuc(MEM(challenge, char, tpos+4), tlen); - printf("%s\n", tmp); - free(tmp); - } - - tpos += 4+tlen; - tblen += 4+tlen; - } - - if (tblen && ttype == 0) - tblen += 4; - - if (debug) { - printf("\t TBofs: %d\n\t TBlen: %d\n\t ttype: %d\n", tbofs, tblen, ttype); - } - } - - if (creds->hashntlm2 && !tblen) { - return 0; - } - - if (creds->hashntlm2) { - ntlm2_calc_resp(&nthash, &ntlen, &lmhash, &lmlen, creds->passntlm2, challenge, tbofs, tblen); - } - - if (creds->hashnt == 2) { - ntlm2sr_calc_rest(&nthash, &ntlen, &lmhash, &lmlen, creds->passnt, challenge); - } - - if (creds->hashnt == 1) { - ntlen = ntlm_calc_resp(&nthash, creds->passnt, MEM(challenge, char, 24)); - } - - if (creds->hashlm) { - lmlen = ntlm_calc_resp(&lmhash, creds->passlm, MEM(challenge, char, 24)); - } - - if (creds->hashnt || creds->hashntlm2) { - tmp = uppercase(strdup(creds->domain)); - dlen = unicode(&udomain, tmp); - free(tmp); - ulen = unicode(&uuser, creds->user); - tmp = uppercase(strdup(creds->workstation)); - hlen = unicode(&uhost, tmp); - free(tmp); - } else { - udomain = uppercase(strdup(creds->domain)); - uuser = uppercase(strdup(creds->user)); - uhost = uppercase(strdup(creds->workstation)); - - dlen = strlen(creds->domain); - ulen = strlen(creds->user); - hlen = strlen(creds->workstation); - } - - if (debug) { - printf("NTLM Response:\n"); - printf("\t Hostname: '%s'\n", creds->workstation); - printf("\t Domain: '%s'\n", creds->domain); - printf("\t Username: '%s'\n", creds->user); - if (ntlen) { - tmp = printmem(nthash, ntlen, 7); - printf("\t Response: '%s' (%d)\n", tmp, ntlen); - free(tmp); - } - if (lmlen) { - tmp = printmem(lmhash, lmlen, 7); - printf("\t Response: '%s' (%d)\n", tmp, lmlen); - free(tmp); - } - } - - buf = new(NTLM_BUFSIZE); - memcpy(buf, "NTLMSSP\0", 8); - VAL(buf, uint32_t, 8) = U32LE(3); - - /* LM */ - VAL(buf, uint16_t, 12) = U16LE(lmlen); - VAL(buf, uint16_t, 14) = U16LE(lmlen); - VAL(buf, uint32_t, 16) = U32LE(64+dlen+ulen+hlen); - - /* NT */ - VAL(buf, uint16_t, 20) = U16LE(ntlen); - VAL(buf, uint16_t, 22) = U16LE(ntlen); - VAL(buf, uint32_t, 24) = U32LE(64+dlen+ulen+hlen+lmlen); - - /* Domain */ - VAL(buf, uint16_t, 28) = U16LE(dlen); - VAL(buf, uint16_t, 30) = U16LE(dlen); - VAL(buf, uint32_t, 32) = U32LE(64); - - /* Username */ - VAL(buf, uint16_t, 36) = U16LE(ulen); - VAL(buf, uint16_t, 38) = U16LE(ulen); - VAL(buf, uint32_t, 40) = U32LE(64+dlen); - - /* Hostname */ - VAL(buf, uint16_t, 44) = U16LE(hlen); - VAL(buf, uint16_t, 46) = U16LE(hlen); - VAL(buf, uint32_t, 48) = U32LE(64+dlen+ulen); - - /* Session */ - VAL(buf, uint16_t, 52) = U16LE(0); - VAL(buf, uint16_t, 54) = U16LE(0); - VAL(buf, uint16_t, 56) = U16LE(64+dlen+ulen+hlen+lmlen+ntlen); - - /* Flags */ - VAL(buf, uint32_t, 60) = VAL(challenge, uint32_t, 20); - - memcpy(MEM(buf, char, 64), udomain, dlen); - memcpy(MEM(buf, char, 64+dlen), uuser, ulen); - memcpy(MEM(buf, char, 64+dlen+ulen), uhost, hlen); - memcpy(MEM(buf, char, 64+dlen+ulen+hlen), lmhash, lmlen); - memcpy(MEM(buf, char, 64+dlen+ulen+hlen+24), nthash, ntlen); - - if (nthash) - free(nthash); - if (lmhash) - free(lmhash); - - free(uhost); - free(uuser); - free(udomain); - - *dst = buf; - return 64+dlen+ulen+hlen+lmlen+ntlen; -} diff --git a/files/cntlm-0.92.3/ntlm.h b/files/cntlm-0.92.3/ntlm.h deleted file mode 100644 index b0afdba..0000000 --- a/files/cntlm-0.92.3/ntlm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * These are NTLM authentication routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _NTLM_H -#define _NTLM_H - -#include "xcrypt.h" -#include "auth.h" - -#define NTLM_BUFSIZE 1024 -#define NTLM_CHALLENGE_MIN 24 - -extern char *ntlm_hash_lm_password(char *password); -extern char *ntlm_hash_nt_password(char *password); -extern char *ntlm2_hash_password(char *username, char *domain, char *password); -extern int ntlm_request(char **dst, struct auth_s *creds); -extern int ntlm_response(char **dst, char *challenge, int challen, struct auth_s *creds); - -#endif /* _NTLM_H */ diff --git a/files/cntlm-0.92.3/pages.c b/files/cntlm-0.92.3/pages.c deleted file mode 100644 index 2242f53..0000000 --- a/files/cntlm-0.92.3/pages.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Static HTML page generators for CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _PAGES_H -#define _PAGES_H - -#include "utils.h" -#include "string.h" -#include "stdio.h" - -char *gen_407_page(const char *http) { - char *tmp; - if (http == NULL) - http = "HTTP/1.0"; - tmp = new(BUFSIZE); - snprintf(tmp, BUFSIZE-1, - "%s 407 Access denied\r\n" - "Proxy-Authenticate: Basic realm=\"Cntlm Proxy\"\r\n" - "Content-Type: text/html\r\n\r\n" - "

407 Access denied

Cntlm requests your credentials for proxy access.

", - http); - return tmp; -} - -char *gen_401_page(const char *http, const char *host, int port) { - char *tmp; - if (http == NULL) - http = "HTTP/1.0"; - tmp = new(BUFSIZE); - snprintf(tmp, BUFSIZE-1, - "%s 401 Access denied\r\n" - "WWW-Authenticate: Basic realm=\"%s:%d\"\r\n" - "Content-Type: text/html\r\n\r\n" - "

401 Access denied

Cntlm proxy requests your credentials for this URL.

", - http, host, port); - return tmp; -} - -char *gen_denied_page(const char *ip) { - char *tmp; - if (ip == NULL) - ip = "client"; - tmp = new(BUFSIZE); - snprintf(tmp, BUFSIZE-1, - "HTTP/1.0 407 Access denied\r\n" - "Content-Type: text/html\r\n\r\n" - "

Access denied

Your request has been declined, %s is not allowed to connect.

", - ip); - return tmp; -} - -char *gen_502_page(const char *http, const char *msg) { - char *tmp; - if (http == NULL) - http = "HTTP/1.0"; - if (msg == NULL) - msg = "Proxy error"; - tmp = new(BUFSIZE); - snprintf(tmp, BUFSIZE-1, - "%s 502 %s\r\n" - "Content-Type: text/html\r\n\r\n" - "

502 %s

Cntlm proxy failed to complete the request.

", - http, msg, msg); - return tmp; -} - -#endif /* _PAGES_H */ diff --git a/files/cntlm-0.92.3/pages.h b/files/cntlm-0.92.3/pages.h deleted file mode 100644 index 6de9a5b..0000000 --- a/files/cntlm-0.92.3/pages.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include "utils.h" -#include "string.h" -#include "stdio.h" - -extern char *gen_407_page(const char *http); -extern char *gen_401_page(const char *http, const char *host, int port); -extern char *gen_denied_page(const char *ip); -extern char *gen_502_page(const char *http, const char *msg); diff --git a/files/cntlm-0.92.3/rpm/cntlm.init b/files/cntlm-0.92.3/rpm/cntlm.init deleted file mode 100644 index 746c4b2..0000000 --- a/files/cntlm-0.92.3/rpm/cntlm.init +++ /dev/null @@ -1,272 +0,0 @@ -#!/bin/sh -# -# cntlmd: Start/stop the cntlm proxy. -# -# chkconfig: 2345 26 89 -# Description: Cntlm is meant to be given your proxy address and becomming -# the primary proxy then, listening on a selected local port. -# You point all your proxy-aware programs to it and don't ever -# have to deal with proxy authentication again. -# -# Authors: Radislav Vrnata -# Michal Strnad -# Christian Wittmer -# -### BEGIN INIT INFO -# Provides: cntlm -# Required-Start: $syslog $network $time -# Should-Start: $remote_fs -# Required-Stop: $syslog $network $time -# Should-Stop: $remote_fs -# Default-Start: 2 3 5 -# Default-Stop: 0 1 6 -# Short-Description: start/stop the cntlm proxy -# Description: ntlm is meant to be given your proxy address and becomming -# the primary proxy then, listening on a selected local port. -# You point all your proxy-aware programs to it and don't ever -# have to deal with proxy authentication again. -### END INIT INFO -# -# Note on runlevels: -# 0 - halt/poweroff 6 - reboot -# 1 - single user -# 2 - multiuser without network exported -# 3 - multiuser with network (text mode) -# 4 - Not used/User-definable -# 5 - multiuser with network and X11 (xdm) -# 6 - reboot -# - -# Determining Linux RedHat/SuSE -# -# /etc/redhat-release -# /etc/SuSE-release - -SuSE=false -RedHat=false - -if [ -f /etc/SuSE-release ]; then - SuSE=true -elif [ -f /etc/redhat-release ]; then - RedHat=true -else - echo "Error: your platform is not supported by $0" > /dev/stderr - exit 1 -fi - - -# Source function library SuSE/RedHat. -if $SuSE; then - # Source LSB init functions - # providing start_daemon, killproc, pidofproc, - # log_success_msg, log_failure_msg and log_warning_msg. - # This is currently not used by UnitedLinux based distributions and - # not needed for init scripts for UnitedLinux only. If it is used, - # the functions from rc.status should not be sourced or used. - #. /lib/lsb/init-functions - - # Shell functions sourced from /etc/rc.status: - # rc_check check and set local and overall rc status - # rc_status check and set local and overall rc status - # rc_status -v be verbose in local rc status and clear it afterwards - # rc_status -v -r ditto and clear both the local and overall rc status - # rc_status -s display "skipped" and exit with status 3 - # rc_status -u display "unused" and exit with status 3 - # rc_failed set local and overall rc status to failed - # rc_failed set local and overall rc status to - # rc_reset clear both the local and overall rc status - # rc_exit exit appropriate to overall rc status - # rc_active checks whether a service is activated by symlinks - - # Return values acc. to LSB for all commands but status: - # 0 - success - # 1 - generic or unspecified error - # 2 - invalid or excess argument(s) - # 3 - unimplemented feature (e.g. "reload") - # 4 - user had insufficient privileges - # 5 - program is not installed - # 6 - program is not configured - # 7 - program is not running - # 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl) - # - # Note that starting an already running service, stopping - # or restarting a not-running service as well as the restart - # with force-reload (in case signaling is not supported) are - # considered a success. - test -f /etc/rc.status && . /etc/rc.status || { - echo "Error: your platform is not supported by $0" > /dev/stderr; - exit 1 - } - rc_reset -else - test -f /etc/init.d/functions && . /etc/init.d/functions || { - echo "Error: your platform is not supported by $0" > /dev/stderr; - exit 1 - } - RETVAL=0 -fi - -# Check for existence of needed config file and read it -CNTLM_CONFIG="/etc/cntlm.conf" -test -r $CNTLM_CONFIG || { echo "$CNTLM_CONFIG not existing"; - if [ "$1" = "stop" ]; then exit 0; - else exit 6; fi; } - -# Check for existence of needed sysconfig file and read it -if $SuSE ; then - CNTLM_SYSCONFIG="/etc/sysconfig/cntlm" -else - CNTLM_SYSCONFIG="/etc/sysconfig/cntlmd" -fi -test -r $CNTLM_SYSCONFIG && . $CNTLM_SYSCONFIG || { - echo "$CNTLM_SYSCONFIG not existing"; - if [ "$1" = "stop" ]; then exit 0; - else exit 6; fi; } - -# some defaults -[ -z "${DAEMON}" ] && DAEMON=/usr/sbin/cntlm -[ -z "${DESC}" ] && DESC="CNTLM Authentication Proxy" -[ -z "${PIDFILE}" ] && PIDFILE="/var/run/cntlm/cntlmd.pid" -if $SuSE ; then - [ -z "${LOCKFILE}" ] && LOCKFILE="/var/lock/subsys/cntlm" -else - [ -z "${LOCKFILE}" ] && LOCKFILE="/var/lock/subsys/cntlmd" -fi -[ -z "${RUNAS}" ] && RUNAS="cntlm" - -# if no "Proxy" is set in cntlm.conf try '127.0.0.1:3128' as a default -if [ `/bin/cat $CNTLM_CONFIG | grep -e "^Listen" >/dev/null; echo $?` -eq 0 ]; then - CNTLM_LISTEN= -else - CNTLM_LISTEN="-l 127.0.0.1:3128" -fi - -# Check for missing binaries (stale symlinks should not happen) -# Note: Special treatment of stop for LSB conformance -test -x $DAEMON || { echo "$DAEMON not installed"; - if [ "$1" = "stop" ]; then exit 0; - else exit 5; fi; } - -case "$1" in - start) - echo -n "Starting ${DESC}: " - if $SuSE; then - ## Start daemon with startproc(8). If this fails - ## the return value is set appropriately by startproc. - /sbin/startproc -p $PIDFILE $DAEMON -P $PIDFILE $CNTLM_LISTEN -U $RUNAS $OPTARGS &>/dev/null - - # Remember status and be verbose - rc_status -v - else - daemon cntlm -P $PIDFILE $CNTLM_LISTEN -U $RUNAS $OPTARGS 2>/dev/null - RETVAL=$? - echo - [ $RETVAL -eq 0 ] && touch $LOCKFILE - exit $RETVAL - fi - ;; - stop) - echo -n "Shutting down ${DESC}: " - if $SuSE; then - ## Stop daemon with killproc(8) and if this fails - ## killproc sets the return value according to LSB. - /sbin/killproc -p $PIDFILE -TERM $DAEMON &>/dev/null - - # Remember status and be verbose - rc_status -v - else - killproc cntlm - RETVAL=$? - echo - [ $RETVAL -eq 0 ] && rm -f $LOCKFILE - exit $RETVAL - fi - ;; - try-restart|condrestart) - ## Do a restart only if the service was active before. - ## Note: try-restart is now part of LSB (as of 1.9). - ## RH has a similar command named condrestart. - if test "$1" = "condrestart"; then - echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}" - fi - $0 status - if test $? = 0; then - $0 restart - else - if $SuSE; then - rc_reset # Not running is not a failure. - # Remember status and be quiet - rc_status - else - exit 0 - fi - fi - ;; - restart) - ## Stop the service and regardless of whether it was - ## running or not, start it again. - $0 stop - $0 start - - if $SuSE; then - # Remember status and be quiet - rc_status - fi - ;; - force-reload|reload) - ## Signal the daemon to reload its config. Most daemons - ## do this on signal 1 (SIGHUP). - ## If it does not support it, restart the service if it - ## is running. - - # cntlm does not support SIGHUP, so restart - echo -n "Reload ${DESC}: " - ## if it supports it: - #/sbin/killproc -p $PIDFILE -HUP $DAEMON - - # Remember status and be verbose - #rc_status -v - - ## Otherwise: - $0 try-restart - - if $SuSE; then - # Remember status and be quiet - rc_status - fi - ;; - status) - echo -n "Checking for ${DESC}: " - if $SuSE; then - ## Check status with checkproc(8), if process is running - ## checkproc will return with exit status 0. - - # Return value is slightly different for the status command: - # 0 - service up and running - # 1 - service dead, but /var/run/ pid file exists - # 2 - service dead, but /var/lock/ lock file exists - # 3 - service not running (unused) - # 4 - service status unknown :-( - # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.) - - # NOTE: checkproc returns LSB compliant status values. - /sbin/checkproc -p $PIDFILE $DAEMON - # NOTE: rc_status knows that we called this init script with - # "status" option and adapts its messages accordingly. - - # Remember status and be verbose - rc_status -v - else - status cntlm - fi - ;; - *) - echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}" - exit 1 - ;; -esac -if $SuSE; then - rc_exit -else - exit $RETVAL -fi diff --git a/files/cntlm-0.92.3/rpm/cntlm.spec b/files/cntlm-0.92.3/rpm/cntlm.spec deleted file mode 100644 index 9211fb3..0000000 --- a/files/cntlm-0.92.3/rpm/cntlm.spec +++ /dev/null @@ -1,161 +0,0 @@ -Summary: Fast NTLM authentication proxy with tunneling -Name: cntlm -Version: 0.92.3 -Release: 1%{?dist} -License: GNU GPL V2 -%if 0%{?suse_version} -Group: Productivity/Networking/Web/Proxy -%else -Group: System/Daemons -%endif -URL: http://cntlm.sourceforge.net/ -Source0: %{name}-%{version}.tar.bz2 -Source1: %{name}.init -Source2: %{name}.sysconfig - - -%if 0%{?suse_version} -Prereq: util-linux %{?insserv_prereq} %{?fillup_prereq} -%else -Prereq: which /sbin/chkconfig -%endif -Prereq: /usr/sbin/useradd /usr/bin/getent - -Provides: cntlm = %{version} - -BuildRoot: %{_tmppath}/%{name}-%{version}-root - -%description -Cntlm is a fast and efficient NTLM proxy, with support for TCP/IP tunneling, -authenticated connection caching, ACLs, proper daemon logging and behaviour -and much more. It has up to ten times faster responses than similar NTLM -proxies, while using by orders or magnitude less RAM and CPU. Manual page -contains detailed information. - -%prep -%setup -q -n %{name}-%{version} - -%build -./configure -make SYSCONFDIR=%{_sysconfdir} \ - BINDIR=%{_sbindir} \ - MANDIR=%{_mandir} - -%install -# Clean up in case there is trash left from a previous build -rm -rf $RPM_BUILD_ROOT -mkdir $RPM_BUILD_ROOT - -# Create the target build directory hierarchy -%if 0%{?suse_version} - mkdir -p ${RPM_BUILD_ROOT}/var/adm/fillup-templates -%else - mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig -%endif - -mkdir -p $RPM_BUILD_ROOT/sbin - -%makeinstall SYSCONFDIR=$RPM_BUILD_ROOT/%{_sysconfdir} \ - BINDIR=$RPM_BUILD_ROOT/%{_sbindir} \ - MANDIR=$RPM_BUILD_ROOT/%{_mandir} -%if 0%{?suse_version} - install -D -m 755 %{SOURCE1} $RPM_BUILD_ROOT/%{_initrddir}/cntlm - install -D -m 644 %{SOURCE2} $RPM_BUILD_ROOT/var/adm/fillup-templates/sysconfig.cntlm - ln -sf %{_initrddir}/cntlm $RPM_BUILD_ROOT/sbin/rccntlm -%else - install -D -m 755 %{SOURCE1} $RPM_BUILD_ROOT/%{_initrddir}/cntlmd - install -D -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/cntlmd - ln -sf %{_initrddir}/cntlmd $RPM_BUILD_ROOT/sbin/rccntlmd -%endif - -%clean -rm -rf $RPM_BUILD_ROOT - -%pre -if [ "$1" -eq 1 ]; then - [ -z "`%{_bindir}/getent passwd "cntlm"`" ] && { - useradd -s /sbin/nologin -m -r -d /var/run/cntlm cntlm 2>/dev/null - } -fi -: - -%post -%if 0%{?suse_version} -%{fillup_and_insserv cntlm} -%else - if [ "$1" -eq 1 ]; then - if [ -x /usr/lib/lsb/install_initd ]; then - /usr/lib/lsb/install_initd /etc/init.d/cntlmd - elif [ -x /sbin/chkconfig ]; then - /sbin/chkconfig --add cntlmd - else - for i in 2 3 4 5; do - ln -sf /etc/init.d/cntlmd /etc/rc.d/rc${i}.d/S26cntlmd - done - for i in 1 6; do - ln -sf /etc/init.d/cntlmd /etc/rc.d/rc${i}.d/K89cntlmd - done - fi - fi - : -%endif - -%preun -%if 0%{?suse_version} -%{stop_on_removal cntlm} -%else - if [ "$1" -eq 0 ]; then - /etc/init.d/cntlmd stop > /dev/null 2>&1 - if [ -x /usr/lib/lsb/remove_initd ]; then - /usr/lib/lsb/install_initd /etc/init.d/cntlmd - elif [ -x /sbin/chkconfig ]; then - /sbin/chkconfig --del cntlmd - else - rm -f /etc/rc.d/rc?.d/???cntlmd - fi - fi - : -%endif - -%postun -if [ "$1" -eq 0 ]; then - /usr/sbin/userdel -r cntlm 2>/dev/null -fi -: -%if 0%{?suse_version} -%{insserv_cleanup} -%else - if [ -x /usr/lib/lsb/remove_initd ]; then - /usr/lib/lsb/install_initd /etc/init.d/cntlmd - elif [ -x /sbin/chkconfig ]; then - /sbin/chkconfig --del cntlmd - else - rm -f /etc/rc.d/rc?.d/???cntlmd - fi - : -%endif - -%files -%defattr(-,root,root,-) -%doc LICENSE README COPYRIGHT -%{_sbindir}/cntlm -%{_mandir}/man1/cntlm.1* -%config(noreplace) %{_sysconfdir}/cntlm.conf -%if 0%{?suse_version} - %config(noreplace) /var/adm/fillup-templates/sysconfig.cntlm - %{_initrddir}/cntlm - /sbin/rccntlm -%else - %config(noreplace) %{_sysconfdir}/sysconfig/cntlmd - %{_initrddir}/cntlmd - /sbin/rccntlmd -%endif - -%changelog -* Thu Mar 18 2010 : Version 0.90 -- Major rewrite of proxy code -- NoProxy option added to bypass proxy for certain addresses -- Ability to work as a standalone proxy added -- few changes in spec file to package successfully for SuSE - and RedHat distros using openSuSE BuildService by - Michal Strnad diff --git a/files/cntlm-0.92.3/rpm/cntlm.sysconfig b/files/cntlm-0.92.3/rpm/cntlm.sysconfig deleted file mode 100644 index 11dcc51..0000000 --- a/files/cntlm-0.92.3/rpm/cntlm.sysconfig +++ /dev/null @@ -1,36 +0,0 @@ -## Path: Network/Proxy/Cntlm - -## Type: string -## Default: /usr/sbin/cntlm -# CNTLM binary location -DAEMON="/usr/sbin/cntlm" - -## Type: string -## Default: /usr/sbin/cntlm -# Location of CNTLM's PID file. -# Make sure that you or, if used, -U uid can create/write it -PIDFILE="/var/run/cntlm/cntlmd.pid" - -## Description: Timeout before forced shutdown -## Type: integer -## Default: 1 -# How long to wait before forcing cntlm to stop with a second -# signal when active connections are still not finished -TIMEOUT=1 - -## Type: string -## Default: cntlm -# Name or number of the non-privileged account to run as -RUNAS=cntlm - -## Type: string -## Default: "CNTLM Authentication Proxy" -# CNTLM custom service description -DESC="CNTLM Authentication Proxy" - -## Type: string -## Default: "" -# List o optional arguments one would specify on the command line. -# See the cntlm man page for list of available arguments -# with their description. -OPTARGS="-U $RUNAS -P $PIDFILE" diff --git a/files/cntlm-0.92.3/rpm/rules b/files/cntlm-0.92.3/rpm/rules deleted file mode 100755 index d60953a..0000000 --- a/files/cntlm-0.92.3/rpm/rules +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -# -# Usage: rules [binary|clean] -# - -if [ ! -f VERSION -o ! -f Makefile ]; then - echo "This command must be run from the main source directory!" >&2 - exit 1 -fi - -RPMS="BUILD RPMS SOURCES SPECS SRPMS tmp" -DIR=`pwd`/tmp -NAME=cntlm-`cat VERSION` - -if [ "$1" = "binary" ]; then - rm -f cntlm*.rpm 2>/dev/null - for i in $RPMS; do mkdir -p $DIR/$i; done # Create new rpm build structure - - make tbz2 - mv $NAME.tar.bz2 $DIR/SOURCES - cp rpm/cntlm.* $DIR/SOURCES # Prepare build environment - - rpmbuild \ - --define "_topdir $DIR" \ - --define "_sourcedir %_topdir/SOURCES" \ - --define "_builddir %_topdir/BUILD" \ - --define "_buildrootdir %_topdir/BUILD" \ - --define "_rpmdir %_topdir/RPMS" \ - --define "_specdir %_topdir/SPECS" \ - --define "_srcrpmdir %_topdir/SRPMS" \ - -ba $DIR/SOURCES/cntlm.spec - - cp $DIR/SRPMS/*rpm . 2>/dev/null - cp $DIR/RPMS/*/cntlm*rpm . 2>/dev/null -elif [ "$1" = "clean" ]; then - for i in $RPMS; do rm -rf $DIR/$i; done # Clean the whole mess, keep packages - rmdir $DIR 2>/dev/null || true -fi diff --git a/files/cntlm-0.92.3/scanner.c b/files/cntlm-0.92.3/scanner.c deleted file mode 100644 index 56287fc..0000000 --- a/files/cntlm-0.92.3/scanner.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "socket.h" -#include "http.h" -#include "globals.h" -#include "forward.h" -#include "scanner.h" - -/* - * This code is a piece of shit, but it works. Cannot rewrite it now, because - * I don't have ISA AV filter anymore - wouldn't be able to test it. - */ -int scanner_hook(rr_data_t request, rr_data_t response, struct auth_s *credentials, int cd, int *sd, long maxKBs) { - char *buf, *line, *pos, *tmp, *pat, *post, *isaid, *uurl; - int bsize, lsize, size, len, i, w, nc; - rr_data_t newreq, newres; - plist_t list; - - int ok = 1; - int done = 0; - int headers_initiated = 0; - long c, progress = 0, filesize = 0; - - /* - * Let's limit the responses we examine to an absolute minimum - */ - if (!request->req || response->code != 200 - || http_has_body(request, response) != -1 - || hlist_subcmp(response->headers, "Transfer-Encoding", "chunked") - || !hlist_subcmp(response->headers, "Proxy-Connection", "close")) - return PLUG_SENDHEAD | PLUG_SENDDATA; - - tmp = hlist_get(request->headers, "User-Agent"); - if (tmp) { - tmp = lowercase(strdup(tmp)); - list = scanner_agent_list; - while (list) { - pat = lowercase(strdup(list->aux)); - if (debug) - printf("scanner_hook: matching U-A header (%s) to %s\n", tmp, pat); - if (!fnmatch(pat, tmp, 0)) { - if (debug) - printf("scanner_hook: positive match!\n"); - maxKBs = 0; - free(pat); - break; - } - free(pat); - list = list->next; - } - free(tmp); - } - - bsize = SAMPLE; - buf = new(bsize); - - len = 0; - do { - size = read(*sd, buf + len, SAMPLE - len - 1); - if (debug) - printf("scanner_hook: read %d of %d\n", size, SAMPLE - len); - if (size > 0) - len += size; - } while (size > 0 && len < SAMPLE - 1); - - if (strstr(buf, "Downloading status") && (pos=strstr(buf, "ISAServerUniqueID=")) && (pos = strchr(pos, '"'))) { - pos++; - c = strlen(pos); - for (i = 0; i < c && pos[i] != '"'; ++i); - - if (pos[i] == '"') { - isaid = substr(pos, 0, i); - if (debug) - printf("scanner_hook: ISA id = %s\n", isaid); - - lsize = BUFSIZE; - line = new(lsize); - do { - i = so_recvln(*sd, &line, &lsize); - - c = strlen(line); - if (len + c >= bsize) { - bsize *= 2; - tmp = realloc(buf, bsize); - if (tmp == NULL) - break; - else - buf = tmp; - } - - strcat(buf, line); - len += c; - - if (i >= 0 && ( - ((pos = strstr(line, "UpdatePage(")) - && isdigit(pos[11])) - || - ((pos = strstr(line, "DownloadFinished(")) - && isdigit(pos[17]) - && (done = 1)) )) { - if (debug) - printf("scanner_hook: %s", line); - - if ((pos = strstr(line, "To be downloaded"))) { - filesize = atol(pos+16); - if (debug) { - if (filesize > 0) { - printf("scanner_hook: file size detected: %ld KiBs (max: %ld)\n", filesize/1024, maxKBs); - } else { - printf("scanner_hook: file size unknown -- quitting\n"); - break; - } - } - - if (maxKBs && (maxKBs == 1 || filesize/1024 > maxKBs)) - break; - - /* - * We have to send HTTP protocol ID so we can send the notification - * headers during downloading. Once we've done that, it cannot appear - * again, which it would if we returned PLUG_SENDHEAD, so we must - * remember to not include it. - */ - headers_initiated = 1; - tmp = new(MINIBUF_SIZE); - snprintf(tmp, MINIBUF_SIZE, "%s 200 OK\r\n", request->http); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - } - - if (!headers_initiated) { - if (debug) - printf("scanner_hook: Giving up, \"To be downloaded\" line not found!\n"); - break; - } - - /* - * Send a notification header to the client, just so it doesn't timeout - */ - if (!done) { - tmp = new(MINIBUF_SIZE); - progress = atol(line+12); - snprintf(tmp, MINIBUF_SIZE, "ISA-Scanner: %ld of %ld\r\n", progress, filesize); - w = write(cd, tmp, strlen(tmp)); - free(tmp); - } - - /* - * If download size is unknown beforehand, stop when downloaded amount is over ISAScannerSize - */ - if (!filesize && maxKBs && maxKBs != 1 && progress/1024 > maxKBs) - break; - } - } while (i > 0 && !done); - - if (i >= 0 && done && (pos = strstr(line, "\",\"")+3) && (c = strchr(pos, '"') - pos) > 0) { - tmp = substr(pos, 0, c); - pos = urlencode(tmp); - free(tmp); - - uurl = urlencode(request->url); - - post = new(BUFSIZE); - snprintf(post, BUFSIZE-1, "%surl=%s&%sSaveToDisk=YES&%sOrig=%s", isaid, pos, isaid, isaid, uurl); - - if (debug) - printf("scanner_hook: Getting file with URL data = %s\n", request->url); - - tmp = new(MINIBUF_SIZE); - snprintf(tmp, MINIBUF_SIZE, "%d", (int)strlen(post)); - - newres = new_rr_data(); - newreq = dup_rr_data(request); - - free(newreq->method); - newreq->method = strdup("POST"); - hlist_mod(newreq->headers, "Referer", request->url, 1); - hlist_mod(newreq->headers, "Content-Type", "application/x-www-form-urlencoded", 1); - hlist_mod(newreq->headers, "Content-Length", tmp, 1); - free(tmp); - - nc = proxy_connect(credentials); - c = proxy_authenticate(&nc, newreq, newres, credentials); - if (c && newres->code == 407) { - if (debug) - printf("scanner_hook: Authentication OK, getting the file...\n"); - } else { - if (debug) - printf("scanner_hook: Authentication failed or refused!\n"); - close(nc); - nc = 0; - } - - /* - * The POST request for the real file - */ - reset_rr_data(newres); - if (nc && headers_send(nc, newreq) && write(nc, post, strlen(post)) && headers_recv(nc, newres)) { - if (debug) - hlist_dump(newres->headers); - - /* - * We always know the filesize here. Send it to the client, because ISA doesn't!!! - * The clients progress bar doesn't work without it and it stinks! - */ - if (filesize || progress) { - tmp = new(20); - snprintf(tmp, 20, "%ld", filesize ? filesize : progress); - newres->headers = hlist_mod(newres->headers, "Content-Length", tmp, 1); - } - - /* - * Here we remember if previous code already sent some headers - * to the client. In such case, do not include the HTTP/1.x ID. - */ - newres->skip_http = headers_initiated; - copy_rr_data(response, newres); - close(*sd); - *sd = nc; - - len = 0; - ok = PLUG_SENDHEAD | PLUG_SENDDATA; - } else if (debug) - printf("scanner_hook: New request failed\n"); - - free(newreq); - free(newres); - free(post); - free(uurl); - } - - free(line); - free(isaid); - } else if (debug) - printf("scanner_hook: ISA id not found\n"); - } - - if (len) { - if (debug) { - printf("scanner_hook: flushing %d original bytes\n", len); - hlist_dump(response->headers); - } - - if (!headers_send(cd, response)) { - if (debug) - printf("scanner_hook: failed to send headers\n"); - free(buf); - return PLUG_ERROR; - } - - size = write(cd, buf, len); - if (size > 0) - ok = PLUG_SENDDATA; - else - ok = PLUG_ERROR; - } - - if (debug) - printf("scanner_hook: ending with %d\n", ok); - - free(buf); - return ok; -} - diff --git a/files/cntlm-0.92.3/scanner.h b/files/cntlm-0.92.3/scanner.h deleted file mode 100644 index baa3d8c..0000000 --- a/files/cntlm-0.92.3/scanner.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _SCANNER_H -#define _SCANNER_H - -#include "utils.h" - -/* - * ISA plugin flags - */ -#define PLUG_NONE 0x0000 -#define PLUG_SENDHEAD 0x0001 -#define PLUG_SENDDATA 0x0002 -#define PLUG_ERROR 0x8000 -#define PLUG_ALL 0x7FFF - -/* - * Plugin download sample size - */ -#define SAMPLE 4096 - -extern int scanner_hook(rr_data_t request, rr_data_t response, struct auth_s *credentials, int cd, int *sd, long maxKBs); - -#endif /* _SCANNER_H */ diff --git a/files/cntlm-0.92.3/socket.c b/files/cntlm-0.92.3/socket.c deleted file mode 100644 index b241b0f..0000000 --- a/files/cntlm-0.92.3/socket.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * These are socket routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" - -extern int debug; - -/* - * gethostbyname() wrapper. Return 1 if OK, otherwise 0. - */ -int so_resolv(struct in_addr *host, const char *name) { -/* - struct hostent *resolv; - - resolv = gethostbyname(name); - if (!resolv) - return 0; - - memcpy(host, resolv->h_addr_list[0], resolv->h_length); - return 1; -*/ - struct addrinfo hints, *res, *p; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - int rc = getaddrinfo(name, NULL, &hints, &res); - if (rc != 0) { - if (debug) - printf("so_resolv: %s failed: %s (%d)\n", name, gai_strerror(rc), rc); - return 0; - } - - if (debug) - printf("Resolve %s:\n", name); - int addr_set = 0; - for (p = res; p != NULL; p = p->ai_next) { - struct sockaddr_in *ad = (struct sockaddr_in*)(p->ai_addr); - if (ad == NULL) { - freeaddrinfo(res); - return 0; - } - if (!addr_set) { - memcpy(host, &ad->sin_addr, sizeof(ad->sin_addr)); - addr_set = 1; - if (debug) - printf(" -> %s\n", inet_ntoa(ad->sin_addr)); - } else - if (debug) - printf(" %s\n", inet_ntoa(ad->sin_addr)); - } - - freeaddrinfo(res); - - return 1; -} - -/* - * Connect to a host. Host is required to be resolved - * in the struct in_addr already. - * Returns: socket descriptor - */ -int so_connect(struct in_addr host, int port) { - int flags, fd, rc; - struct sockaddr_in saddr; - // struct timeval tv; - // fd_set fds; - - if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - if (debug) - printf("so_connect: create: %s\n", strerror(errno)); - return -1; - } - - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); - saddr.sin_addr = host; - - if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { - if (debug) - printf("so_connect: get flags: %s\n", strerror(errno)); - close(fd); - return -1; - } - - /* NON-BLOCKING connect with timeout - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { - if (debug) - printf("so_connect: set non-blocking: %s\n", strerror(errno)); - close(fd); - return -1; - } - */ - - rc = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); - - /* - printf("connect = %d\n", rc); - if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS)) { - FD_ZERO(&fds); - FD_SET(fd, &fds); - tv.tv_sec = 10; - tv.tv_usec = 0; - printf("select!\n"); - rc = select(fd+1, NULL, &fds, NULL, &tv) - 1; - printf("select = %d\n", rc); - } - */ - - if (rc < 0) { - if (debug) - printf("so_connect: %s\n", strerror(errno)); - close(fd); - return -1; - } - - if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) < 0) { - if (debug) - printf("so_connect: set blocking: %s\n", strerror(errno)); - close(fd); - return -1; - } - - return fd; -} - -/* - * Bind the specified port and listen on it. - * Return socket descriptor if OK, otherwise 0. - */ -int so_listen(int port, struct in_addr source) { - struct sockaddr_in saddr; - int fd; - socklen_t clen; - - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) { - if (debug) - printf("so_listen: new socket: %s\n", strerror(errno)); - close(fd); - return -1; - } - - clen = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &clen, sizeof(clen)); - memset((void *)&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(port); - saddr.sin_addr.s_addr = source.s_addr; - - if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr))) { - syslog(LOG_ERR, "Cannot bind port %d: %s!\n", port, strerror(errno)); - close(fd); - return -1; - } - - if (listen(fd, 5)) { - close(fd); - return -1; - } - - return fd; -} - -/* - * Return 1 if data is available on the socket, - * 0 if connection was closed - * -1 if error (errno is set) - */ -int so_recvtest(int fd) { - char buf; - int i; -#ifndef MSG_DONTWAIT - unsigned int flags; - - flags = fcntl(fd, F_GETFL); - fcntl(fd, F_SETFL, flags | O_NONBLOCK); - i = recv(fd, &buf, 1, MSG_PEEK); - fcntl(fd, F_SETFL, flags); -#else - i = recv(fd, &buf, 1, MSG_DONTWAIT | MSG_PEEK); -#endif - - return i; -} - -/* - * Return true if there are some data on the socket - */ -int so_dataready(int fd) { - return so_recvtest(fd) > 0; -} - -/* - * Reliable way of finding out whether a connection was closed - * on the remote end, without actually reading from it. - */ -int so_closed(int fd) { - int i; - - if (fd == -1) - return 1; - - i = so_recvtest(fd); - return (i == 0 || (i == -1 && errno != EAGAIN && errno != ENOENT)); /* ENOENT, you ask? Perhap AIX devels could explain! :-( */ -} - -/* - * Receive a single line from the socket. This is no super-efficient - * implementation, but more than we need to read in a few headers. - * What's more, the data is actually recv'd from a socket buffer. - * - * I had to time this in comparison to recv with block read :) and - * the performance was very similar. Given the fact that it keeps us - * from creating a whole buffering scheme around the socket (HTTP - * connection is both line and block oriented, switching back and forth), - * it is actually OK. - */ -int so_recvln(int fd, char **buf, int *size) { - int len = 0; - int r = 1; - char c = 0; - char *tmp; - - while (len < *size-1 && c != '\n') { - r = read(fd, &c, 1); - if (r <= 0) - break; - - (*buf)[len++] = c; - - /* - * End of buffer, still no EOL? Resize the buffer - */ - if (len == *size-1 && c != '\n') { - if (debug) - printf("so_recvln(%d): realloc %d\n", fd, *size*2); - *size *= 2; - tmp = realloc(*buf, *size); - if (tmp == NULL) - return -1; - else - *buf = tmp; - } - } - (*buf)[len] = 0; - - return r; -} - diff --git a/files/cntlm-0.92.3/socket.h b/files/cntlm-0.92.3/socket.h deleted file mode 100644 index 081d10f..0000000 --- a/files/cntlm-0.92.3/socket.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * These are socket routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _SOCKET_H -#define _SOCKET_H - -#include -#include - -#include "config/config.h" - -#if config_socklen_t != 1 -#define socklen_t uint32_t -#endif - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif - -extern int so_resolv(struct in_addr *host, const char *name); -extern int so_connect(struct in_addr host, int port); -extern int so_listen(int port, struct in_addr source); -extern int so_dataready(int fd); -extern int so_closed(int fd); -extern int so_recvln(int fd, char **buf, int *size); - -#endif /* _SOCKET_H */ diff --git a/files/cntlm-0.92.3/swap.h b/files/cntlm-0.92.3/swap.h deleted file mode 100644 index fc748d0..0000000 --- a/files/cntlm-0.92.3/swap.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * These are little/big endian routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _SWAP_H -#define _SWAP_H - -#include - -#include "config/config.h" - -#define swap16(x) \ - ((uint16_t)( \ - (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) - -#define swap32(x) \ - ((uint32_t)( \ - (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) - -#define swap64(x) \ - ((uint64_t)( \ - (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) | \ - (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) )) - -#if config_endian == 0 -# define U16LE(x) swap16(x) -# define U32LE(x) swap32(x) -# define U64LE(x) swap64(x) -# define U16BE(x) (x) -# define U32BE(x) (x) -# define U64BE(x) (x) -#else -# define U16LE(x) (x) -# define U32LE(x) (x) -# define U64LE(x) (x) -# define U16BE(x) swap16(x) -# define U32BE(x) swap32(x) -# define U64BE(x) swap64(x) -#endif - -#endif /* _SWAP_H */ diff --git a/files/cntlm-0.92.3/utils.c b/files/cntlm-0.92.3/utils.c deleted file mode 100644 index 2fc195e..0000000 --- a/files/cntlm-0.92.3/utils.c +++ /dev/null @@ -1,931 +0,0 @@ -/* - * These are helping routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config/config.h" -#include "swap.h" -#include "utils.h" -#include "socket.h" - -char hextab[17] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 0}; -int hexindex[128] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1, - -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; - -void myexit(int rc) { - if (rc) - fprintf(stderr, "Exitting with error. Check daemon logs or run with -v.\n"); - - exit(rc); -} - -void croak(const char *msg, int console) { - if (console) - printf("%s", msg); - else - syslog(LOG_ERR, "%s", msg); - - myexit(1); -} - -/* - * Add a new item to a list. Every plist_t variable must be - * initialized to NULL (or pass NULL for "list" when adding - * the first item). This is for simplicity's sake (we don't - * need any plist_new). - * - * This list type allows to store an arbitrary pointer - * associating it with the key. - */ -plist_t plist_add(plist_t list, unsigned long key, void *aux) { - plist_t tmp, t = list; - - tmp = malloc(sizeof(struct plist_s)); - tmp->key = key; - tmp->aux = aux; - tmp->next = NULL; - - if (list == NULL) - return tmp; - - while (t->next) - t = t->next; - - t->next = tmp; - - return list; -} - -/* - * Delete an item from the list, possibly returning NULL when - * the list is empty or nothing was found. - */ -plist_t plist_del(plist_t list, unsigned long key) { - plist_t ot = NULL, t = list; - - while (t) { - if (t->key == key) - break; - ot = t; - t = t->next; - } - - if (t) { - plist_t tmp = t->next; - - if (t->aux) - free(t->aux); - free(t); - if (ot == NULL) - return tmp; - - ot->next = tmp; - } - - return list; -} - -/* - * Return true if an item is present in the list. - */ -int plist_in(plist_t list, unsigned long key) { - plist_t t = list; - - while (t) { - if (t->key == key) - break; - t = t->next; - } - - return (t != NULL); -} - -/* - * For debugging purposes - dump the entire contents - * of a list. - */ -void plist_dump(plist_t list) { - plist_t t; - - t = list; - while (t) { - printf("List data: %lu => 0x%8p\n", (unsigned long int)t->key, t->aux); - t = t->next; - } -} - -/* - * Return the pointer associated with the key. - */ -char *plist_get(plist_t list, int key) { - plist_t t = list; - - while (t) { - if (t->key == key) - break; - t = t->next; - } - - return (t == NULL ? NULL : t->aux); -} - -/* - * Scan the list for an open descriptor (socket), possibly - * discarding all closed ones on the way. Return the first - * match. - * - * Use this method only for lists of descriptors! - * - * In conjunction with plist_add, the list behaves as a FIFO. - * This feature is used for rotating cached connections in the - * list, so that none is left too long unused (proxy timeout). - * - * Returns key value (descriptor) and if aux != NULL, *aux gets - * aux pointer value (which caller must free if != NULL). - */ - -int plist_pop(plist_t *list, void **aux) { - plist_t tmp, t; - int id = 0; - int ok = 0; - void *a = NULL; - - if (list == NULL || *list == NULL) - return 0; - - t = *list; - while (!ok && t) { - id = t->key; - a = t->aux; - tmp = t->next; - - if (so_closed(id)) { - close(id); - if (t->aux) - free(t->aux); - } else - ok = 1; - - free(t); - t = tmp; - } - - *list = t; - - if (ok) { - if (aux != NULL) - *aux = a; - return id; - } - - return 0; -} - -/* - * Return the number of items in a list. - */ -int plist_count(plist_t list) { - plist_t t = list; - int rc = 0; - - while (t) { - rc++; - t = t->next; - } - - return rc; -} - -/* - * Free the list. - */ -plist_t plist_free(plist_t list) { - plist_t t = list; - - while (list) { - t = list->next; - if (list->aux) - free(list->aux); - free(list); - list = t; - } - - return NULL; -} - -/* - * The same as plist_add. Here we have two other arguments. - * They are boolean flags - HLIST_ALLOC means to duplicate a - * key/value, HLIST_NOALLOC means to store the pointer directly. - * - * Caller decides this on a by-call basis. Part of the manipulation - * routines is a "free". That method always deallocates both the - * key and the value. So for static or temporary keys/values, - * the caller can instruct us to duplicate the necessary amount - * of heap. This mechanism is used to minimize memory-related - * bugs throughout the code and tons of free's. - */ -hlist_t hlist_add(hlist_t list, char *key, char *value, hlist_add_t allockey, hlist_add_t allocvalue) { - hlist_t tmp, t = list; - - if (key == NULL || value == NULL) - return list; - - tmp = malloc(sizeof(struct hlist_s)); - tmp->key = (allockey == HLIST_ALLOC ? strdup(key) : key); - tmp->value = (allocvalue == HLIST_ALLOC ? strdup(value) : value); - tmp->next = NULL; - tmp->islist = 0; - - if (list == NULL) - return tmp; - - while (t->next) - t = t->next; - - t->next = tmp; - - return list; -} - -/* - * Return a duplicate of the list (copy). - */ -hlist_t hlist_dup(hlist_t list) { - hlist_t tmp = NULL, t = list; - - while (t) { - tmp = hlist_add(tmp, t->key, t->value, HLIST_ALLOC, HLIST_ALLOC); - t = t->next; - } - - return tmp; -} - -/* - * Remove an item from the list. - */ -hlist_t hlist_del(hlist_t list, const char *key) { - hlist_t ot = NULL, t = list; - - while (t) { - if (!strcasecmp(t->key, key)) - break; - ot = t; - t = t->next; - } - - if (t) { - hlist_t tmp = t->next; - - free(t->key); - free(t->value); - free(t); - - if (ot == NULL) - return tmp; - - ot->next = tmp; - } - - return list; -} - -/* - * Change the value of a key. If add is true, we store it in the - * list if the key is not found. Unlike hlist_add, which offers - * pointer storage or memory duplication for both the key and the - * value separately, hlist_mod always duplicates. - * - * Used to add a header, which might already be present. - */ -hlist_t hlist_mod(hlist_t list, char *key, char *value, int add) { - hlist_t t = list; - - while (t) { - if (!strcasecmp(t->key, key)) - break; - t = t->next; - } - - if (t) { - free(t->value); - t->value = strdup(value); - } else if (add) { - list = hlist_add(list, key, value, HLIST_ALLOC, HLIST_ALLOC); - } - - return list; -} - -/* - * Return true is the key is in the list. - */ -int hlist_in(hlist_t list, const char *key) { - hlist_t t = list; - - while (t) { - if (!strcasecmp(t->key, key)) - break; - t = t->next; - } - - return (t != NULL); -} - -/* - * Return the number of items in a list. - */ -int hlist_count(hlist_t list) { - hlist_t t = list; - int rc = 0; - - while (t) { - rc++; - t = t->next; - } - - return rc; -} - -/* - * Return the value for the key. - */ -char *hlist_get(hlist_t list, const char *key) { - hlist_t t = list; - - while (t) { - if (!strcasecmp(t->key, key)) - break; - t = t->next; - } - - return (t == NULL ? NULL : t->value); -} - -/* - * Test if substr is part of the header's value. - * Both case-insensitive. - */ -int hlist_subcmp(hlist_t list, const char *key, const char *substr) { - int found = 0; - char *tmp, *low; - - lowercase(low = strdup(substr)); - tmp = hlist_get(list, key); - if (tmp) { - lowercase(tmp = strdup(tmp)); - if (strstr(tmp, low)) - found = 1; - - free(tmp); - } - - free(low); - return found; -} - -/* - * Test if substr is part of the header's value. - * Both case-insensitive, checks all headers, not just first one. - */ -int hlist_subcmp_all(hlist_t list, const char *key, const char *substr) { - hlist_t t = list; - int found = 0; - char *tmp, *low; - - lowercase(low = strdup(substr)); - while (t) { - if (!strcasecmp(t->key, key)) { - lowercase(tmp = strdup(t->value)); - if (strstr(tmp, low)) - found = 1; - - free(tmp); - } - t = t->next; - } - - free(low); - return found; -} - -/* - * Free the list. For more about list memory management, - * se hlist_add. - */ -hlist_t hlist_free(hlist_t list) { - hlist_t t = list; - - while (list) { - t = list->next; - - free(list->key); - free(list->value); - free(list); - - list = t; - } - - return NULL; -} - -/* - * This is for debugging purposes. - */ -void hlist_dump(hlist_t list) { - hlist_t t; - - t = list; - while (t) { - printf("%-30s => %s\n", t->key, t->value); - t = t->next; - } -} - -/* - * Standard substr. To prevent modification of the source - * (terminating \x0), return the result in a new memory. - */ -char *substr(const char *src, int pos, int len) { - int l; - char *tmp; - - if (len == 0) - len = strlen(src); - - l = MIN(len, strlen(src)-pos); - if (l <= 0) - return new(1); - - tmp = new(l+1); - strlcpy(tmp, src+pos, l+1); - - return tmp; -} - -/* - * Allocate memory and initialize a new rr_data_t structure. - */ -rr_data_t new_rr_data(void) { - rr_data_t data; - - data = malloc(sizeof(struct rr_data_s)); - data->req = 0; - data->code = 0; - data->skip_http = 0; - data->body_len = 0; - data->empty = 1; - data->port = 0; - data->headers = NULL; - data->method = NULL; - data->url = NULL; - data->rel_url = NULL; - data->hostname = NULL; - data->http = NULL; - data->msg = NULL; - data->body = NULL; - data->errmsg = NULL; /* for static strings - we don't free, dup, nor copy */ - - return data; -} - -/* - * Copy the req/res data. - */ -rr_data_t copy_rr_data(rr_data_t dst, rr_data_t src) { - if (src == NULL || dst == NULL) - return NULL; - - reset_rr_data(dst); - dst->req = src->req; - dst->code = src->code; - dst->skip_http = src->skip_http; - dst->body_len = src->body_len; - dst->empty = src->empty; - dst->port = src->port; - - if (src->headers) - dst->headers = hlist_dup(src->headers); - if (src->method) - dst->method = strdup(src->method); - if (src->url) - dst->url = strdup(src->url); - if (src->rel_url) - dst->rel_url = strdup(src->rel_url); - if (src->hostname) - dst->hostname = strdup(src->hostname); - if (src->http) - dst->http = strdup(src->http); - if (src->msg) - dst->msg = strdup(src->msg); - if (src->body && src->body_len > 0) { - dst->body = new(src->body_len); - memcpy(dst->body, src->body, src->body_len); - } - - return dst; -} - -/* - * Duplicate the req/res data. - */ -rr_data_t dup_rr_data(rr_data_t data) { - rr_data_t tmp; - - if (data == NULL) - return NULL; - - tmp = new_rr_data(); - return copy_rr_data(tmp, data); -} - -/* - * Reset, freeing if neccessary - */ -rr_data_t reset_rr_data(rr_data_t data) { - if (data == NULL) - return NULL; - - data->req = 0; - data->code = 0; - data->skip_http = 0; - data->body_len = 0; - data->empty = 1; - data->port = 0; - - if (data->headers) hlist_free(data->headers); - if (data->method) free(data->method); - if (data->url) free(data->url); - if (data->rel_url) free(data->rel_url); - if (data->hostname) free(data->hostname); - if (data->http) free(data->http); - if (data->msg) free(data->msg); - if (data->body) free(data->body); - - data->headers = NULL; - data->method = NULL; - data->url = NULL; - data->rel_url = NULL; - data->hostname = NULL; - data->http = NULL; - data->msg = NULL; - data->body = NULL; - data->errmsg = NULL; - - return data; -} - -/* - * Free rr_data_t structure. We also take care of freeing - * the memory of its members. - */ -void free_rr_data(rr_data_t data) { - if (data == NULL) - return; - - if (data->headers) hlist_free(data->headers); - if (data->method) free(data->method); - if (data->url) free(data->url); - if (data->rel_url) free(data->rel_url); - if (data->hostname) free(data->hostname); - if (data->http) free(data->http); - if (data->msg) free(data->msg); - if (data->body) free(data->body); - free(data); -} - -/* - * Cut the whitespace at the end of a string. - */ -char *trimr(char *buf) { - int i; - - for (i = strlen(buf)-1; i >= 0 && isspace(buf[i]); --i); - buf[i+1] = 0; - - return buf; -} - -#if config_strdup == 0 -/* - * Our implementation of non-POSIX strdup() - */ -char *strdup(const char *src) { - size_t len; - char *tmp; - - if (!src) - return NULL; - - len = strlen(src)+1; - tmp = calloc(1, len); - memcpy(tmp, src, len-1); - - return tmp; -} -#endif - -/* - * More intuitive version of strncpy with string termination - * from OpenBSD - */ -size_t strlcpy(char *dst, const char *src, size_t siz) { - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) { - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++); - } - - return (s - src - 1); /* count does not include NUL */ -} - -/* - * More intuitive version os strncat with string termination - * from OpenBSD - */ -size_t strlcat(char *dst, const char *src, size_t siz) { - char *d = dst; - const char *s = src; - size_t n = siz; - size_t dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (n-- != 0 && *d != '\0') - d++; - - dlen = d - dst; - n = siz - dlen; - - if (n == 0) - return(dlen + strlen(s)); - - while (*s != '\0') { - if (n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = '\0'; - - return (dlen + (s - src)); /* count does not include NUL */ -} - -/* - * Shortcut for malloc/memset zero. - */ -char *new(size_t size) { - char *tmp; - - tmp = malloc(size); - memset(tmp, 0, size); - - return tmp; -} - -/* - * Self-explanatory. - */ -char *lowercase(char *str) { - int i; - - for (i = 0; i < strlen(str); ++i) - str[i] = tolower(str[i]); - - return str; -} - -/* - * Self-explanatory. - */ -char *uppercase(char *str) { - int i; - - for (i = 0; i < strlen(str); ++i) - str[i] = toupper(str[i]); - - return str; -} - -int unicode(char **dst, char *src) { - char *tmp; - int l, i; - - if (!src) { - *dst = NULL; - return 0; - } - - l = MIN(64, strlen(src)); - tmp = new(2*l); - for (i = 0; i < l; ++i) - tmp[2*i] = src[i]; - - *dst = tmp; - return 2*l; -} - -char *urlencode(const char *str) { - char *tmp; - int i, pos; - - tmp = new(strlen(str)*3 + 1); - for (pos = 0, i = 0; i < strlen(str); ++i) { - if (isdigit(str[i]) || (tolower(str[i]) >= 'a' && tolower(str[i]) <= 'z') || str[i] == '.' || str[i] == '-' || str[i] == '_' || str[i] == '~') { - tmp[pos++] = str[i]; - } else { - sprintf(tmp+pos, "%%%X", (unsigned char)str[i]); - pos += 3; - } - } - - return tmp; -} - -char *printmem(char *src, size_t len, int bitwidth) { - char *tmp; - int i; - - tmp = new(2*len+1); - for (i = 0; i < len; ++i) { - tmp[i*2] = hextab[((uint8_t)src[i] ^ (uint8_t)(7-bitwidth)) >> 4]; - tmp[i*2+1] = hextab[(src[i] ^ (uint8_t)(7-bitwidth)) & 0x0F]; - } - - return tmp; -} - -char *scanmem(char *src, int bitwidth) { - int h, l, i, bytes; - char *tmp; - - if (strlen(src) % 2) - return NULL; - - bytes = strlen(src)/2; - tmp = new(bytes+1); - for (i = 0; i < bytes; ++i) { - h = hexindex[(int)src[i*2]]; - l = hexindex[(int)src[i*2+1]]; - if (h < 0 || l < 0) { - free(tmp); - return NULL; - } - tmp[i] = ((h << 4) + l) ^ (uint8_t)(7-bitwidth); - } - tmp[i] = 0; - - return tmp; -} - - - -/* - * BASE64 CODE FROM MUTT BEGIN - ORIGINAL COPYRIGHT APPLIES: - * - * Copyright (C) 1996-2001 Michael R. Elkins - * Copyright (C) 1996-2001 Brandon Long - * Copyright (C) 1997-2001 Thomas Roessler - * Copyright (C) 1998-2001 Werner Koch - * Copyright (C) 1999-2001 Brendan Cully - * Copyright (C) 1999-2001 Tommi Komulainen - * Copyright (C) 2000-2001 Edmund Grimley Evans - * - */ - -#define BAD -1 -#define base64val(c) index64[(unsigned int)(c)] - -char base64[64] = { - 'A','B','C','D','E','F','G','H','I','J','K','L','M','N', - 'O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b', - 'c','d','e','f','g','h','i','j','k','l','m','n','o','p', - 'q','r','s','t','u','v','w','x','y','z','0','1','2','3', - '4','5','6','7','8','9','+','/' -}; - -int index64[128] = { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60, - 61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13, - 14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26, - 27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45, - 46,47,48,49,50,51,-1,-1,-1,-1,-1 -}; - -void to_base64(unsigned char *out, const unsigned char *in, size_t len, size_t olen) { - while (len >= 3 && olen > 10) { - *out++ = base64[in[0] >> 2]; - *out++ = base64[((in[0] << 4) & 0x30) | (in[1] >> 4)]; - *out++ = base64[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; - *out++ = base64[in[2] & 0x3f]; - olen -= 4; - len -= 3; - in += 3; - } - - /* clean up remainder */ - if (len > 0 && olen > 4) { - unsigned char fragment; - - *out++ = base64[in[0] >> 2]; - fragment = (in[0] << 4) & 0x30; - if (len > 1) - fragment |= in[1] >> 4; - *out++ = base64[fragment]; - *out++ = (len < 2) ? '=' : base64[(in[1] << 2) & 0x3c]; - *out++ = '='; - } - *out = '\0'; -} - -/* Convert '\0'-terminated base 64 string to raw bytes. - * Returns length of returned buffer, or -1 on error */ -int from_base64(char *out, const char *in) -{ - int len = 0; - register unsigned char digit1, digit2, digit3, digit4; - - do { - digit1 = in[0]; - if (digit1 > 127 || base64val (digit1) == BAD) - return -1; - - digit2 = in[1]; - if (digit2 > 127 || base64val (digit2) == BAD) - return -1; - - digit3 = in[2]; - if (digit3 > 127 || ((digit3 != '=') && (base64val (digit3) == BAD))) - return -1; - - digit4 = in[3]; - if (digit4 > 127 || ((digit4 != '=') && (base64val (digit4) == BAD))) - return -1; - - in += 4; - - /* digits are already sanity-checked */ - *out++ = (base64val(digit1) << 2) | (base64val(digit2) >> 4); - len++; - if (digit3 != '=') { - *out++ = ((base64val(digit2) << 4) & 0xf0) | (base64val(digit3) >> 2); - len++; - if (digit4 != '=') { - *out++ = ((base64val(digit3) << 6) & 0xc0) | base64val(digit4); - len++; - } - } - } while (*in && digit4 != '='); - - return len; -} -/* - * CODE FROM MUTT END - */ diff --git a/files/cntlm-0.92.3/utils.h b/files/cntlm-0.92.3/utils.h deleted file mode 100644 index 06e2d2b..0000000 --- a/files/cntlm-0.92.3/utils.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * These are helping routines for the main module of CNTLM - * - * CNTLM is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. - * - * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin - * St, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 David Kubicek - * - */ - -#ifndef _UTILS_H -#define _UTILS_H - -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -# include -#endif -#include -#include - -#include "config/config.h" - -#define BUFSIZE 4096 -#define MINIBUF_SIZE 50 -#define VAL(var, type, offset) *((type *)(var+offset)) -#define MEM(var, type, offset) (type *)(var+offset) - -#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -/* -#define isalnum(c) (isalpha(c) || isdigit(c)) -#define isspace(c) ((c) == ' ' || (c) == '\f' || (c) == '\t' || (c) == '\r' || (c) == '\n') -*/ - -/* - * Solaris doesn't have LOG_PERROR - */ -#ifndef LOG_PERROR -# define LOG_PERROR LOG_CONS -#endif - -/* - * Two single-linked list types. First is for storing headers, - * second keeps a list of finished threads or cached connections. - * Each has a different set of manipulation routines. - */ -typedef struct hlist_s *hlist_t; -struct hlist_s { - char *key; - char *value; - int islist; - struct hlist_s *next; -}; - -typedef struct plist_s *plist_t; -struct plist_s { - unsigned long key; - void *aux; - struct plist_s *next; -}; - -typedef enum { - HLIST_NOALLOC = 0, - HLIST_ALLOC -} hlist_add_t; - -/* - * Request/response data structure. Complete and parsed req/res is - * kept in this. See below for (de)allocation routines. - */ -typedef struct rr_data_s *rr_data_t; -struct rr_data_s { - int req; - hlist_t headers; - int code; - int skip_http; - int body_len; - int empty; - int port; - char *method; - char *url; - char *rel_url; - char *hostname; - char *http; - char *msg; - char *body; - char *errmsg; -}; - -/* - * This is used in main() for passing arguments to the thread. - */ -struct thread_arg_s { - int fd; - char *target; - struct sockaddr_in addr; -}; - -extern void myexit(int rc); -extern void croak(const char *msg, int console); - -extern plist_t plist_add(plist_t list, unsigned long key, void *aux); -extern plist_t plist_del(plist_t list, unsigned long key); -extern int plist_in(plist_t list, unsigned long key); -extern void plist_dump(plist_t list); -extern char *plist_get(plist_t list, int key); -extern int plist_pop(plist_t *list, void **aux); -extern int plist_count(plist_t list); -extern plist_t plist_free(plist_t list); - -extern hlist_t hlist_add(hlist_t list, char *key, char *value, hlist_add_t allockey, hlist_add_t allocvalue); -extern hlist_t hlist_dup(hlist_t list); -extern hlist_t hlist_del(hlist_t list, const char *key); -extern hlist_t hlist_mod(hlist_t list, char *key, char *value, int add); -extern int hlist_in(hlist_t list, const char *key); -extern int hlist_count(hlist_t list); -extern char *hlist_get(hlist_t list, const char *key); -extern int hlist_subcmp(hlist_t list, const char *key, const char *substr); -extern int hlist_subcmp_all(hlist_t list, const char *key, const char *substr); -extern hlist_t hlist_free(hlist_t list); -extern void hlist_dump(hlist_t list); - -extern char *substr(const char *src, int pos, int len); -extern size_t strlcpy(char *dst, const char *src, size_t siz); -extern size_t strlcat(char *dst, const char *src, size_t siz); -extern char *trimr(char *buf); -extern char *lowercase(char *str); -extern char *uppercase(char *str); -extern int unicode(char **dst, char *src); -extern char *new(size_t size); -extern char *urlencode(const char *str); - -extern rr_data_t new_rr_data(void); -extern rr_data_t copy_rr_data(rr_data_t dst, rr_data_t src); -extern rr_data_t dup_rr_data(rr_data_t data); -extern rr_data_t reset_rr_data(rr_data_t data); -extern void free_rr_data(rr_data_t data); - -extern char *printmem(char *src, size_t len, int bitwidth); -extern char *scanmem(char *src, int bitwidth); - -extern void to_base64(unsigned char *out, const unsigned char *in, size_t len, size_t olen); -extern int from_base64(char *out, const char *in); - -extern long int random(void); -#if config_gethostname == 1 -extern int gethostname(char *name, size_t len); -#endif -#ifndef strdup -extern char *strdup(const char *src); -#endif - -#endif /* _UTILS_H */ diff --git a/files/cntlm-0.92.3/win/Cntlm Homepage.url b/files/cntlm-0.92.3/win/Cntlm Homepage.url deleted file mode 100644 index f70e2e2..0000000 --- a/files/cntlm-0.92.3/win/Cntlm Homepage.url +++ /dev/null @@ -1,2 +0,0 @@ -[InternetShortcut] -URL=http://cntlm.sf.net/ diff --git a/files/cntlm-0.92.3/win/README.txt b/files/cntlm-0.92.3/win/README.txt deleted file mode 100644 index 2d430a4..0000000 --- a/files/cntlm-0.92.3/win/README.txt +++ /dev/null @@ -1,27 +0,0 @@ -Cntlm Installation Manual for Windows -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Run setup.exe installer -- Edit cntlm.ini -- Start Cntlm - -Visit http://cntlm.sf.net for HOWTO's and configuration tips. - -Starting and stopping -~~~~~~~~~~~~~~~~~~~~~ - -You can use Cntlm Start Menu shortcuts to start, stop and configure -the application. Cntlm is installed as an auto-start service. - -OR: -Start -> Settings -> Control Panel -> Administrative Tools -> Services - -OR (command line): -net start cntlm -net stop cntlm - - -Uninstalling -~~~~~~~~~~~~ -Stop Cntlm service, run uninstaller from your Start Menu, or use -native Windows "Add/Remove Programs" Control Panel. diff --git a/files/cntlm-0.92.3/win/Software Updates.url b/files/cntlm-0.92.3/win/Software Updates.url deleted file mode 100644 index 949150e..0000000 --- a/files/cntlm-0.92.3/win/Software Updates.url +++ /dev/null @@ -1,2 +0,0 @@ -[InternetShortcut] -URL=http://sourceforge.net/projects/cntlm/files/ diff --git a/files/cntlm-0.92.3/win/Support Website.url b/files/cntlm-0.92.3/win/Support Website.url deleted file mode 100644 index 82b7b54..0000000 --- a/files/cntlm-0.92.3/win/Support Website.url +++ /dev/null @@ -1,2 +0,0 @@ -[InternetShortcut] -URL=http://sourceforge.net/tracker/?group_id=197861 diff --git a/files/cntlm-0.92.3/win/cntlm.ico b/files/cntlm-0.92.3/win/cntlm.ico deleted file mode 100644 index f66c62e..0000000 Binary files a/files/cntlm-0.92.3/win/cntlm.ico and /dev/null differ diff --git a/files/cntlm-0.92.3/win/resources.rc b/files/cntlm-0.92.3/win/resources.rc deleted file mode 100644 index 4b67196..0000000 --- a/files/cntlm-0.92.3/win/resources.rc +++ /dev/null @@ -1 +0,0 @@ -1 ICON "win/cntlm.ico" diff --git a/files/cntlm-0.92.3/win/setup.iss.in b/files/cntlm-0.92.3/win/setup.iss.in deleted file mode 100644 index a30a3c2..0000000 --- a/files/cntlm-0.92.3/win/setup.iss.in +++ /dev/null @@ -1,48 +0,0 @@ -[Setup] -AppId={{4D753458-961F-45DA-B5E3-7B44D4E368B4} -AppName=Cntlm -AppVerName=Cntlm v$VERSION -AppCopyright=Copyright (C) 2007-2010 David Kubicek -AppPublisher=David Kubicek -AppPublisherURL=http://cntlm.sf.net/ -LicenseFile=license.txt - -DefaultDirName={pf}\Cntlm -DefaultGroupName=Cntlm -SetupIconFile=cntlm.ico -UninstallDisplayIcon={app}\cntlm.ico -Uninstallable=yes -OutputBaseFileName=cntlm-$VERSION-setup -OutputDir=. - -[Files] -Source: "cntlm.exe"; DestDir: "{app}" -Source: "cygrunsrv.exe"; DestDir: "{app}" -Source: "cygwin1.dll"; DestDir: "{app}" -Source: "cyggcc_s-1.dll"; DestDir: "{app}" -Source: "cygstdc++-6.dll"; DestDir: "{app}" -Source: "cntlm.ini"; DestDir: "{app}"; Flags: uninsneveruninstall confirmoverwrite -Source: "cntlm_manual.pdf"; DestDir: "{app}" -Source: "README.txt"; DestDir: "{app}"; Flags: isreadme -Source: "Cntlm Homepage.url"; DestDir: "{app}" -Source: "Software Updates.url"; DestDir: "{app}" -Source: "Support Website.url"; DestDir: "{app}" - -[Run] -Filename: "{app}\cygrunsrv.exe"; StatusMsg: "Stopping Cntlm service..."; Parameters: " --stop cntlm" -Filename: "{app}\cygrunsrv.exe"; StatusMsg: "Removing Cntlm service..."; Parameters: " --remove cntlm" -Filename: "{app}\cygrunsrv.exe"; StatusMsg: "Installing Cntlm service..."; Parameters: "--install cntlm -s KILL -t auto -p ""{app}\cntlm.exe"" -d ""Cntlm Authentication Proxy"" -f ""HTTP Accelerator"" -a -f" - -[Icons] -Name: "{group}\cntlm.ini"; Filename: "{app}\cntlm.ini" -Name: "{group}\Start Cntlm Authentication Proxy"; Filename: "{sys}\net.exe"; Parameters: "start cntlm"; WorkingDir: {app} -Name: "{group}\Stop Cntlm Authentication Proxy"; Filename: "{sys}\net.exe"; Parameters: "stop cntlm"; WorkingDir: {app} -Name: "{group}\Tools\Uninstall Cntlm"; Filename: "{uninstallexe}" -Name: "{group}\Tools\Cntlm Homepage"; Filename: "{app}\Cntlm Homepage.url" -Name: "{group}\Tools\Software Updates"; Filename: "{app}\Software Updates.url" -Name: "{group}\Tools\Support Website"; Filename: "{app}\Support Website.url" -Name: "{group}\Tools\PDF configuration manual"; Filename: "{app}\cntlm_manual.pdf" - -[UninstallRun] -Filename: "{app}\cygrunsrv.exe"; StatusMsg: "Stopping Cntlm service..."; Parameters: " --stop cntlm" -Filename: "{app}\cygrunsrv.exe"; StatusMsg: "Removing Cntlm service..."; Parameters: " --remove cntlm" diff --git a/files/cntlm-0.92.3/xcrypt.c b/files/cntlm-0.92.3/xcrypt.c deleted file mode 100644 index 609e010..0000000 --- a/files/cntlm-0.92.3/xcrypt.c +++ /dev/null @@ -1,1274 +0,0 @@ -/* des.c --- DES and Triple-DES encryption/decryption Algorithm - * Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 - * Free Software Foundation, Inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * ---------------------------------------------------------------------- - * Functions to compute MD4 message digest of files or memory blocks. - * according to the definition of MD4 in RFC 1320 from April 1992. Copyright - * (C) 1995,1996,1997,1999,2000,2001,2002,2003,2005,2006 Free Software - * Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "xcrypt.h" -#include "swap.h" - -#define SWAP(n) U32LE(n) - -#define BLOCKSIZE 4096 -#if BLOCKSIZE % 64 != 0 -# error "invalid BLOCKSIZE" -#endif - -/* - * To check alignment gcc has an appropriate operator. Other compilers don't. - */ -# if __GNUC__ >= 2 -# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0) -# else -# define alignof(type) offsetof (struct { char c; type x; }, x) -# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0) -# endif - -# define MD4_DIGEST_SIZE 16 - -/* MD4 round constants */ -#define K1 0x5a827999 -#define K2 0x6ed9eba1 - -/* Round functions. */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) -#define R1(a,b,c,d,k,s) a=rol(a+F(b,c,d)+x[k],s); -#define R2(a,b,c,d,k,s) a=rol(a+G(b,c,d)+x[k]+K1,s); -#define R3(a,b,c,d,k,s) a=rol(a+H(b,c,d)+x[k]+K2,s); - -/* This array contains the bytes used to pad the buffer to the next - 64-byte boundary. (RFC 1320, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; - -/* - * The s-box values are permuted according to the 'primitive function P' - * and are rotated one bit to the left. - */ -static const uint32_t sbox1[64] = { - 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, - 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400, - 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, - 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, - 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, - 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static const uint32_t sbox2[64] = { - 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, - 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020, - 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, - 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, - 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, - 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static const uint32_t sbox3[64] = { - 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, - 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008, - 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, - 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, - 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, - 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static const uint32_t sbox4[64] = { - 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, - 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000, - 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, - 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, - 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, - 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static const uint32_t sbox5[64] = { - 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, - 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000, - 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, - 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, - 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, - 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static const uint32_t sbox6[64] = { - 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, - 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010, - 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, - 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, - 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, - 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static const uint32_t sbox7[64] = { - 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, - 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802, - 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, - 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, - 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, - 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static const uint32_t sbox8[64] = { - 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, - 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040, - 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, - 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, - 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, - 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -/* - * These two tables are part of the 'permuted choice 1' function. - * In this implementation several speed improvements are done. - */ -static const uint32_t leftkey_swap[16] = { - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 -}; - -static const uint32_t rightkey_swap[16] = { - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101, -}; - -/* - * Numbers of left shifts per round for encryption subkeys. To - * calculate the decryption subkeys we just reverse the ordering of - * the calculated encryption subkeys, so there is no need for a - * decryption rotate tab. - */ -static const unsigned char encrypt_rotate_tab[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -/* - * Table with weak DES keys sorted in ascending order. In DES there - * are 64 known keys which are weak. They are weak because they - * produce only one, two or four different subkeys in the subkey - * scheduling process. The keys in this table have all their parity - * bits cleared. - */ -static const unsigned char weak_keys[64][8] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*w */ - {0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e}, - {0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0}, - {0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe}, - {0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e}, /*sw */ - {0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00}, - {0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe}, - {0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0}, - {0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0}, /*sw */ - {0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe}, - {0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00}, - {0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e}, - {0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe}, /*sw */ - {0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0}, - {0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e}, - {0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00}, - {0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e}, - {0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00}, /*sw */ - {0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe}, - {0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0}, - {0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00}, - {0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e}, /*w */ - {0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0}, - {0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe}, - {0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe}, - {0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0}, /*sw */ - {0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e}, - {0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00}, - {0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0}, - {0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe}, /*sw */ - {0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00}, - {0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e}, - {0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0}, - {0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe}, - {0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00}, /*sw */ - {0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e}, - {0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe}, - {0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0}, - {0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e}, /*sw */ - {0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00}, - {0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00}, - {0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e}, - {0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0}, /*w */ - {0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe}, - {0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e}, - {0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00}, - {0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe}, /*sw */ - {0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0}, - {0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe}, - {0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0}, - {0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e}, - {0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00}, /*sw */ - {0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0}, - {0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe}, - {0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00}, - {0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e}, /*sw */ - {0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e}, - {0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00}, - {0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe}, - {0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0}, /*sw */ - {0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00}, - {0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e}, - {0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0}, - {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe} /*w */ -}; - - -bool gl_des_is_weak_key (const char * key) { - char work[8]; - int i, left, right, middle, cmp_result; - - /* clear parity bits */ - for (i = 0; i < 8; ++i) - work[i] = ((unsigned char)key[i]) & 0xfe; - - /* binary search in the weak key table */ - left = 0; - right = 63; - while (left <= right) - { - middle = (left + right) / 2; - - if (!(cmp_result = memcmp (work, weak_keys[middle], 8))) - return -1; - - if (cmp_result > 0) - left = middle + 1; - else - right = middle - 1; - } - - return 0; -} - -/* - * Macro to swap bits across two words. - */ -#define DO_PERMUTATION(a, temp, b, offset, mask) \ - temp = ((a>>offset) ^ b) & mask; \ - b ^= temp; \ - a ^= temp<> 31); \ - temp = (left ^ right) & 0xaaaaaaaa; \ - right ^= temp; \ - left ^= temp; \ - left = (left << 1) | (left >> 31); - -/* - * The 'inverse initial permutation'. - */ -#define FINAL_PERMUTATION(left, temp, right) \ - left = (left << 31) | (left >> 1); \ - temp = (left ^ right) & 0xaaaaaaaa; \ - left ^= temp; \ - right ^= temp; \ - right = (right << 31) | (right >> 1); \ - DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \ - DO_PERMUTATION(right, temp, left, 2, 0x33333333) \ - DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \ - DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) - - -/* - * A full DES round including 'expansion function', 'sbox substitution' - * and 'primitive function P' but without swapping the left and right word. - * Please note: The data in 'from' and 'to' is already rotated one bit to - * the left, done in the initial permutation. - */ -#define DES_ROUND(from, to, work, subkey) \ - work = from ^ *subkey++; \ - to ^= sbox8[ work & 0x3f ]; \ - to ^= sbox6[ (work>>8) & 0x3f ]; \ - to ^= sbox4[ (work>>16) & 0x3f ]; \ - to ^= sbox2[ (work>>24) & 0x3f ]; \ - work = ((from << 28) | (from >> 4)) ^ *subkey++; \ - to ^= sbox7[ work & 0x3f ]; \ - to ^= sbox5[ (work>>8) & 0x3f ]; \ - to ^= sbox3[ (work>>16) & 0x3f ]; \ - to ^= sbox1[ (work>>24) & 0x3f ]; - -/* - * Macros to convert 8 bytes from/to 32bit words. - */ -#define READ_64BIT_DATA(data, left, right) \ - left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \ - right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; - -#define WRITE_64BIT_DATA(data, left, right) \ - data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \ - data[2] = (left >> 8) &0xff; data[3] = left &0xff; \ - data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \ - data[6] = (right >> 8) &0xff; data[7] = right &0xff; - -/* - * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for - * 16 encryption rounds. - * To calculate subkeys for decryption the caller - * have to reorder the generated subkeys. - * - * rawkey: 8 Bytes of key data - * subkey: Array of at least 32 uint32_ts. Will be filled - * with calculated subkeys. - * - */ -static void des_key_schedule (const char * _rawkey, uint32_t * subkey) { - const unsigned char *rawkey = (const unsigned char *) _rawkey; - uint32_t left, right, work; - int round; - - READ_64BIT_DATA (rawkey, left, right) - DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f) - DO_PERMUTATION (right, work, left, 0, 0x10101010) - left = ((leftkey_swap[(left >> 0) & 0xf] << 3) - | (leftkey_swap[(left >> 8) & 0xf] << 2) - | (leftkey_swap[(left >> 16) & 0xf] << 1) - | (leftkey_swap[(left >> 24) & 0xf]) - | (leftkey_swap[(left >> 5) & 0xf] << 7) - | (leftkey_swap[(left >> 13) & 0xf] << 6) - | (leftkey_swap[(left >> 21) & 0xf] << 5) - | (leftkey_swap[(left >> 29) & 0xf] << 4)); - - left &= 0x0fffffff; - - right = ((rightkey_swap[(right >> 1) & 0xf] << 3) - | (rightkey_swap[(right >> 9) & 0xf] << 2) - | (rightkey_swap[(right >> 17) & 0xf] << 1) - | (rightkey_swap[(right >> 25) & 0xf]) - | (rightkey_swap[(right >> 4) & 0xf] << 7) - | (rightkey_swap[(right >> 12) & 0xf] << 6) - | (rightkey_swap[(right >> 20) & 0xf] << 5) - | (rightkey_swap[(right >> 28) & 0xf] << 4)); - - right &= 0x0fffffff; - - for (round = 0; round < 16; ++round) - { - left = ((left << encrypt_rotate_tab[round]) - | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; - right = ((right << encrypt_rotate_tab[round]) - | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff; - - *subkey++ = (((left << 4) & 0x24000000) - | ((left << 28) & 0x10000000) - | ((left << 14) & 0x08000000) - | ((left << 18) & 0x02080000) - | ((left << 6) & 0x01000000) - | ((left << 9) & 0x00200000) - | ((left >> 1) & 0x00100000) - | ((left << 10) & 0x00040000) - | ((left << 2) & 0x00020000) - | ((left >> 10) & 0x00010000) - | ((right >> 13) & 0x00002000) - | ((right >> 4) & 0x00001000) - | ((right << 6) & 0x00000800) - | ((right >> 1) & 0x00000400) - | ((right >> 14) & 0x00000200) - | (right & 0x00000100) - | ((right >> 5) & 0x00000020) - | ((right >> 10) & 0x00000010) - | ((right >> 3) & 0x00000008) - | ((right >> 18) & 0x00000004) - | ((right >> 26) & 0x00000002) - | ((right >> 24) & 0x00000001)); - - *subkey++ = (((left << 15) & 0x20000000) - | ((left << 17) & 0x10000000) - | ((left << 10) & 0x08000000) - | ((left << 22) & 0x04000000) - | ((left >> 2) & 0x02000000) - | ((left << 1) & 0x01000000) - | ((left << 16) & 0x00200000) - | ((left << 11) & 0x00100000) - | ((left << 3) & 0x00080000) - | ((left >> 6) & 0x00040000) - | ((left << 15) & 0x00020000) - | ((left >> 4) & 0x00010000) - | ((right >> 2) & 0x00002000) - | ((right << 8) & 0x00001000) - | ((right >> 14) & 0x00000808) - | ((right >> 9) & 0x00000400) - | ((right) & 0x00000200) - | ((right << 7) & 0x00000100) - | ((right >> 7) & 0x00000020) - | ((right >> 3) & 0x00000011) - | ((right << 2) & 0x00000004) - | ((right >> 21) & 0x00000002)); - } -} - -void gl_des_setkey (gl_des_ctx *ctx, const char * key) { - int i; - - des_key_schedule (key, ctx->encrypt_subkeys); - - for (i = 0; i < 32; i += 2) - { - ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30 - i]; - ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[31 - i]; - } -} - -bool gl_des_makekey (gl_des_ctx *ctx, const char * key, size_t keylen) { - if (keylen != 8) - return false; - - gl_des_setkey (ctx, key); - - return !gl_des_is_weak_key (key); -} - -void gl_des_ecb_crypt (gl_des_ctx *ctx, const char * _from, char * _to, int mode) { - const unsigned char *from = (const unsigned char *) _from; - unsigned char *to = (unsigned char *) _to; - uint32_t left, right, work; - uint32_t *keys; - - keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys; - - READ_64BIT_DATA (from, left, right) - INITIAL_PERMUTATION (left, work, right) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys) - FINAL_PERMUTATION (right, work, left) - WRITE_64BIT_DATA (to, right, left) -} - -/* Process LEN bytes of BUFFER, accumulating context into CTX. - It is assumed that LEN % 64 == 0. */ -void md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx) { - const uint32_t *words = buffer; - size_t nwords = len / sizeof (uint32_t); - const uint32_t *endp = words + nwords; - uint32_t x[16]; - uint32_t A = ctx->A; - uint32_t B = ctx->B; - uint32_t C = ctx->C; - uint32_t D = ctx->D; - - /* First increment the byte count. RFC 1320 specifies the possible - length of the file up to 2^64 bits. Here we only compute the - number of bytes. Do a double word increment. */ - ctx->total[0] += len; - if (ctx->total[0] < len) - ++ctx->total[1]; - - /* Process all bytes in the buffer with 64 bytes in each round of - the loop. */ - while (words < endp) - { - int t; - for (t = 0; t < 16; t++) - { - x[t] = SWAP (*words); - words++; - } - - /* Round 1. */ - R1 (A, B, C, D, 0, 3); - R1 (D, A, B, C, 1, 7); - R1 (C, D, A, B, 2, 11); - R1 (B, C, D, A, 3, 19); - R1 (A, B, C, D, 4, 3); - R1 (D, A, B, C, 5, 7); - R1 (C, D, A, B, 6, 11); - R1 (B, C, D, A, 7, 19); - R1 (A, B, C, D, 8, 3); - R1 (D, A, B, C, 9, 7); - R1 (C, D, A, B, 10, 11); - R1 (B, C, D, A, 11, 19); - R1 (A, B, C, D, 12, 3); - R1 (D, A, B, C, 13, 7); - R1 (C, D, A, B, 14, 11); - R1 (B, C, D, A, 15, 19); - - /* Round 2. */ - R2 (A, B, C, D, 0, 3); - R2 (D, A, B, C, 4, 5); - R2 (C, D, A, B, 8, 9); - R2 (B, C, D, A, 12, 13); - R2 (A, B, C, D, 1, 3); - R2 (D, A, B, C, 5, 5); - R2 (C, D, A, B, 9, 9); - R2 (B, C, D, A, 13, 13); - R2 (A, B, C, D, 2, 3); - R2 (D, A, B, C, 6, 5); - R2 (C, D, A, B, 10, 9); - R2 (B, C, D, A, 14, 13); - R2 (A, B, C, D, 3, 3); - R2 (D, A, B, C, 7, 5); - R2 (C, D, A, B, 11, 9); - R2 (B, C, D, A, 15, 13); - - /* Round 3. */ - R3 (A, B, C, D, 0, 3); - R3 (D, A, B, C, 8, 9); - R3 (C, D, A, B, 4, 11); - R3 (B, C, D, A, 12, 15); - R3 (A, B, C, D, 2, 3); - R3 (D, A, B, C, 10, 9); - R3 (C, D, A, B, 6, 11); - R3 (B, C, D, A, 14, 15); - R3 (A, B, C, D, 1, 3); - R3 (D, A, B, C, 9, 9); - R3 (C, D, A, B, 5, 11); - R3 (B, C, D, A, 13, 15); - R3 (A, B, C, D, 3, 3); - R3 (D, A, B, C, 11, 9); - R3 (C, D, A, B, 7, 11); - R3 (B, C, D, A, 15, 15); - - A = ctx->A += A; - B = ctx->B += B; - C = ctx->C += C; - D = ctx->D += D; - } -} - -/* Initialize structure containing state of computation. - (RFC 1320, 3.3: Step 3) */ -void md4_init_ctx (struct md4_ctx *ctx) { - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; - - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; -} - -/* Put result from CTX in first 16 bytes following RESBUF. The result - must be in little endian byte order. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * md4_read_ctx (const struct md4_ctx *ctx, void *resbuf) { - ((uint32_t *) resbuf)[0] = SWAP (ctx->A); - ((uint32_t *) resbuf)[1] = SWAP (ctx->B); - ((uint32_t *) resbuf)[2] = SWAP (ctx->C); - ((uint32_t *) resbuf)[3] = SWAP (ctx->D); - - return resbuf; -} - -/* Process the remaining bytes in the internal buffer and the usual - prolog according to the standard and write the result to RESBUF. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32 bits value. */ -void * md4_finish_ctx (struct md4_ctx *ctx, void *resbuf) { - /* Take yet unprocessed bytes into account. */ - uint32_t bytes = ctx->buflen; - size_t pad; - - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; - - pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; - memcpy (&((char*)ctx->buffer)[bytes], fillbuf, pad); - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - ctx->buffer[(bytes + pad) / 4] = SWAP (ctx->total[0] << 3); - ctx->buffer[(bytes + pad) / 4 + 1] = SWAP ((ctx->total[1] << 3) | - (ctx->total[0] >> 29)); - - /* Process last bytes. */ - md4_process_block (ctx->buffer, bytes + pad + 8, ctx); - - return md4_read_ctx (ctx, resbuf); -} - -void md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx) { - /* When we already have some bits in our internal buffer concatenate - both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 128 - left_over > len ? len : 128 - left_over; - - memcpy (&((char*)ctx->buffer)[left_over], buffer, add); - ctx->buflen += add; - - if (ctx->buflen > 64) - { - md4_process_block (ctx->buffer, ctx->buflen & ~63, ctx); - - ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap. */ - memcpy (ctx->buffer, &((char*)ctx->buffer)[(left_over + add) & ~63], - ctx->buflen); - } - - buffer = (const char *) buffer + add; - len -= add; - } - - /* Process available complete blocks. */ - if (len >= 64) - { -#if !_STRING_ARCH_unaligned - if (UNALIGNED_P (buffer)) - while (len > 64) - { - md4_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); - buffer = (const char *) buffer + 64; - len -= 64; - } - else -#endif - { - md4_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; - } - } - - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; - - memcpy (&((char*)ctx->buffer)[left_over], buffer, len); - left_over += len; - if (left_over >= 64) - { - md4_process_block (ctx->buffer, 64, ctx); - left_over -= 64; - memcpy (ctx->buffer, &ctx->buffer[16], left_over); - } - ctx->buflen = left_over; - } -} - -/* Compute MD4 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. */ -int md4_stream (FILE * stream, void *resblock) { - struct md4_ctx ctx; - char buffer[BLOCKSIZE + 72]; - size_t sum; - - /* Initialize the computation context. */ - md4_init_ctx (&ctx); - - /* Iterate over full file contents. */ - while (1) - { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the - computation function processes the whole buffer so that with the - next round of the loop another block can be read. */ - size_t n; - sum = 0; - - /* Read block. Take care for partial reads. */ - while (1) - { - n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); - - sum += n; - - if (sum == BLOCKSIZE) - break; - - if (n == 0) - { - /* Check for the error flag IFF N == 0, so that we don't - exit the loop after a partial read due to e.g., EAGAIN - or EWOULDBLOCK. */ - if (ferror (stream)) - return 1; - goto process_partial_block; - } - - /* We've read at least one byte, so ignore errors. But always - check for EOF, since feof may be true even though N > 0. - Otherwise, we could end up calling fread after EOF. */ - if (feof (stream)) - goto process_partial_block; - } - - /* Process buffer with BLOCKSIZE bytes. Note that - BLOCKSIZE % 64 == 0 - */ - md4_process_block (buffer, BLOCKSIZE, &ctx); - } - -process_partial_block:; - - /* Process any remaining bytes. */ - if (sum > 0) - md4_process_bytes (buffer, sum, &ctx); - - /* Construct result in desired memory. */ - md4_finish_ctx (&ctx, resblock); - return 0; -} - -/* Compute MD4 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void * md4_buffer (const char *buffer, size_t len, void *resblock) { - struct md4_ctx ctx; - - /* Initialize the computation context. */ - md4_init_ctx (&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - md4_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return md4_finish_ctx (&ctx, resblock); -} - -void * memxor (void *dest, const void *src, size_t n) { - char const *s = src; - char *d = dest; - - for (; n > 0; n--) - *d++ ^= *s++; - - return dest; -} - -int hmac_md5 (const void *key, size_t keylen, const void *in, size_t inlen, void *resbuf) -{ - struct md5_ctx inner; - struct md5_ctx outer; - char optkeybuf[16]; - char block[64]; - char innerhash[16]; - - /* Reduce the key's size, so that it becomes <= 64 bytes large. */ - - if (keylen > 64) - { - struct md5_ctx keyhash; - - md5_init_ctx (&keyhash); - md5_process_bytes (key, keylen, &keyhash); - md5_finish_ctx (&keyhash, optkeybuf); - - key = optkeybuf; - keylen = 16; - } - - /* Compute INNERHASH from KEY and IN. */ - - md5_init_ctx (&inner); - - memset (block, IPAD, sizeof (block)); - memxor (block, key, keylen); - - md5_process_block (block, 64, &inner); - md5_process_bytes (in, inlen, &inner); - - md5_finish_ctx (&inner, innerhash); - - /* Compute result from KEY and INNERHASH. */ - - md5_init_ctx (&outer); - - memset (block, OPAD, sizeof (block)); - memxor (block, key, keylen); - - md5_process_block (block, 64, &outer); - md5_process_bytes (innerhash, 16, &outer); - - md5_finish_ctx (&outer, resbuf); - - return 0; -} - - - -/* Initialize structure containing state of computation. - (RFC 1321, 3.3: Step 3) */ -void -md5_init_ctx (struct md5_ctx *ctx) -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; - - ctx->total[0] = ctx->total[1] = 0; - ctx->buflen = 0; -} - -/* Put result from CTX in first 16 bytes following RESBUF. The result - must be in little endian byte order. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32-bit value. */ -void * -md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) -{ - ((uint32_t *) resbuf)[0] = SWAP (ctx->A); - ((uint32_t *) resbuf)[1] = SWAP (ctx->B); - ((uint32_t *) resbuf)[2] = SWAP (ctx->C); - ((uint32_t *) resbuf)[3] = SWAP (ctx->D); - - return resbuf; -} - -/* Process the remaining bytes in the internal buffer and the usual - prolog according to the standard and write the result to RESBUF. - - IMPORTANT: On some systems it is required that RESBUF is correctly - aligned for a 32-bit value. */ -void * -md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) -{ - /* Take yet unprocessed bytes into account. */ - uint32_t bytes = ctx->buflen; - size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; - - /* Now count remaining bytes. */ - ctx->total[0] += bytes; - if (ctx->total[0] < bytes) - ++ctx->total[1]; - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3); - ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); - - memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); - - /* Process last bytes. */ - md5_process_block (ctx->buffer, size * 4, ctx); - - return md5_read_ctx (ctx, resbuf); -} - -/* Compute MD5 message digest for bytes read from STREAM. The - resulting message digest number will be written into the 16 bytes - beginning at RESBLOCK. */ -int -md5_stream (FILE *stream, void *resblock) -{ - struct md5_ctx ctx; - char buffer[BLOCKSIZE + 72]; - size_t sum; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - /* Iterate over full file contents. */ - while (1) - { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the - computation function processes the whole buffer so that with the - next round of the loop another block can be read. */ - size_t n; - sum = 0; - - /* Read block. Take care for partial reads. */ - while (1) - { - n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); - - sum += n; - - if (sum == BLOCKSIZE) - break; - - if (n == 0) - { - /* Check for the error flag IFF N == 0, so that we don't - exit the loop after a partial read due to e.g., EAGAIN - or EWOULDBLOCK. */ - if (ferror (stream)) - return 1; - goto process_partial_block; - } - - /* We've read at least one byte, so ignore errors. But always - check for EOF, since feof may be true even though N > 0. - Otherwise, we could end up calling fread after EOF. */ - if (feof (stream)) - goto process_partial_block; - } - - /* Process buffer with BLOCKSIZE bytes. Note that - BLOCKSIZE % 64 == 0 - */ - md5_process_block (buffer, BLOCKSIZE, &ctx); - } - -process_partial_block: - - /* Process any remaining bytes. */ - if (sum > 0) - md5_process_bytes (buffer, sum, &ctx); - - /* Construct result in desired memory. */ - md5_finish_ctx (&ctx, resblock); - return 0; -} - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - result is always in little endian byte order, so that a byte-wise - output yields to the wanted ASCII representation of the message - digest. */ -void * -md5_buffer (const char *buffer, size_t len, void *resblock) -{ - struct md5_ctx ctx; - - /* Initialize the computation context. */ - md5_init_ctx (&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - md5_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return md5_finish_ctx (&ctx, resblock); -} - - -void -md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx) -{ - /* When we already have some bits in our internal buffer concatenate - both inputs first. */ - if (ctx->buflen != 0) - { - size_t left_over = ctx->buflen; - size_t add = 128 - left_over > len ? len : 128 - left_over; - - memcpy (&((char *) ctx->buffer)[left_over], buffer, add); - ctx->buflen += add; - - if (ctx->buflen > 64) - { - md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); - - ctx->buflen &= 63; - /* The regions in the following copy operation cannot overlap. */ - memcpy (ctx->buffer, - &((char *) ctx->buffer)[(left_over + add) & ~63], - ctx->buflen); - } - - buffer = (const char *) buffer + add; - len -= add; - } - - /* Process available complete blocks. */ - if (len >= 64) - { -#if !_STRING_ARCH_unaligned - if (UNALIGNED_P (buffer)) - while (len > 64) - { - md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); - buffer = (const char *) buffer + 64; - len -= 64; - } - else -#endif - { - md5_process_block (buffer, len & ~63, ctx); - buffer = (const char *) buffer + (len & ~63); - len &= 63; - } - } - - /* Move remaining bytes in internal buffer. */ - if (len > 0) - { - size_t left_over = ctx->buflen; - - memcpy (&((char *) ctx->buffer)[left_over], buffer, len); - left_over += len; - if (left_over >= 64) - { - md5_process_block (ctx->buffer, 64, ctx); - left_over -= 64; - memcpy (ctx->buffer, &ctx->buffer[16], left_over); - } - ctx->buflen = left_over; - } -} - - -/* These are the four functions used in the four steps of the MD5 algorithm - and defined in the RFC 1321. The first function is a little bit optimized - (as found in Colin Plumbs public domain implementation). */ -/* #define FF(b, c, d) ((b & c) | (~b & d)) */ -#define FF(b, c, d) (d ^ (b & (c ^ d))) -#define FG(b, c, d) FF (d, b, c) -#define FH(b, c, d) (b ^ c ^ d) -#define FI(b, c, d) (c ^ (b | ~d)) - -/* Process LEN bytes of BUFFER, accumulating context into CTX. - It is assumed that LEN % 64 == 0. */ - -void -md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) -{ - uint32_t correct_words[16]; - const uint32_t *words = buffer; - size_t nwords = len / sizeof (uint32_t); - const uint32_t *endp = words + nwords; - uint32_t A = ctx->A; - uint32_t B = ctx->B; - uint32_t C = ctx->C; - uint32_t D = ctx->D; - - /* First increment the byte count. RFC 1321 specifies the possible - length of the file up to 2^64 bits. Here we only compute the - number of bytes. Do a double word increment. */ - ctx->total[0] += len; - if (ctx->total[0] < len) - ++ctx->total[1]; - - /* Process all bytes in the buffer with 64 bytes in each round of - the loop. */ - while (words < endp) - { - uint32_t *cwp = correct_words; - uint32_t A_save = A; - uint32_t B_save = B; - uint32_t C_save = C; - uint32_t D_save = D; - - /* First round: using the given function, the context and a constant - the next context is computed. Because the algorithms processing - unit is a 32-bit word and it is determined to work on words in - little endian byte order we perhaps have to change the byte order - before the computation. To reduce the work for the next steps - we store the swapped words in the array CORRECT_WORDS. */ - -#define OP(a, b, c, d, s, T) \ - do \ - { \ - a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ - ++words; \ - CYCLIC (a, s); \ - a += b; \ - } \ - while (0) - - /* It is unfortunate that C does not provide an operator for - cyclic rotation. Hope the C compiler is smart enough. */ -#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) - - /* Before we start, one word to the strange constants. - They are defined in RFC 1321 as - - T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 - - Here is an equivalent invocation using Perl: - - perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' - */ - - /* Round 1. */ - OP (A, B, C, D, 7, 0xd76aa478); - OP (D, A, B, C, 12, 0xe8c7b756); - OP (C, D, A, B, 17, 0x242070db); - OP (B, C, D, A, 22, 0xc1bdceee); - OP (A, B, C, D, 7, 0xf57c0faf); - OP (D, A, B, C, 12, 0x4787c62a); - OP (C, D, A, B, 17, 0xa8304613); - OP (B, C, D, A, 22, 0xfd469501); - OP (A, B, C, D, 7, 0x698098d8); - OP (D, A, B, C, 12, 0x8b44f7af); - OP (C, D, A, B, 17, 0xffff5bb1); - OP (B, C, D, A, 22, 0x895cd7be); - OP (A, B, C, D, 7, 0x6b901122); - OP (D, A, B, C, 12, 0xfd987193); - OP (C, D, A, B, 17, 0xa679438e); - OP (B, C, D, A, 22, 0x49b40821); - - /* For the second to fourth round we have the possibly swapped words - in CORRECT_WORDS. Redefine the macro to take an additional first - argument specifying the function to use. */ -#undef OP -#define OP(f, a, b, c, d, k, s, T) \ - do \ - { \ - a += f (b, c, d) + correct_words[k] + T; \ - CYCLIC (a, s); \ - a += b; \ - } \ - while (0) - - /* Round 2. */ - OP (FG, A, B, C, D, 1, 5, 0xf61e2562); - OP (FG, D, A, B, C, 6, 9, 0xc040b340); - OP (FG, C, D, A, B, 11, 14, 0x265e5a51); - OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); - OP (FG, A, B, C, D, 5, 5, 0xd62f105d); - OP (FG, D, A, B, C, 10, 9, 0x02441453); - OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); - OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); - OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); - OP (FG, D, A, B, C, 14, 9, 0xc33707d6); - OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); - OP (FG, B, C, D, A, 8, 20, 0x455a14ed); - OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); - OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); - OP (FG, C, D, A, B, 7, 14, 0x676f02d9); - OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); - - /* Round 3. */ - OP (FH, A, B, C, D, 5, 4, 0xfffa3942); - OP (FH, D, A, B, C, 8, 11, 0x8771f681); - OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); - OP (FH, B, C, D, A, 14, 23, 0xfde5380c); - OP (FH, A, B, C, D, 1, 4, 0xa4beea44); - OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); - OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); - OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); - OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); - OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); - OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); - OP (FH, B, C, D, A, 6, 23, 0x04881d05); - OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); - OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); - OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); - OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); - - /* Round 4. */ - OP (FI, A, B, C, D, 0, 6, 0xf4292244); - OP (FI, D, A, B, C, 7, 10, 0x432aff97); - OP (FI, C, D, A, B, 14, 15, 0xab9423a7); - OP (FI, B, C, D, A, 5, 21, 0xfc93a039); - OP (FI, A, B, C, D, 12, 6, 0x655b59c3); - OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); - OP (FI, C, D, A, B, 10, 15, 0xffeff47d); - OP (FI, B, C, D, A, 1, 21, 0x85845dd1); - OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); - OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); - OP (FI, C, D, A, B, 6, 15, 0xa3014314); - OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); - OP (FI, A, B, C, D, 4, 6, 0xf7537e82); - OP (FI, D, A, B, C, 11, 10, 0xbd3af235); - OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); - OP (FI, B, C, D, A, 9, 21, 0xeb86d391); - - /* Add the starting values of the context. */ - A += A_save; - B += B_save; - C += C_save; - D += D_save; - } - - /* Put checksum in context given as argument. */ - ctx->A = A; - ctx->B = B; - ctx->C = C; - ctx->D = D; -} - diff --git a/files/cntlm-0.92.3/xcrypt.h b/files/cntlm-0.92.3/xcrypt.h deleted file mode 100644 index 3822c76..0000000 --- a/files/cntlm-0.92.3/xcrypt.h +++ /dev/null @@ -1,111 +0,0 @@ -/* des.c --- DES and Triple-DES encryption/decryption Algorithm - * Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 - * Free Software Foundation, Inc. - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * ---------------------------------------------------------------------- - * Functions to compute MD4 message digest of files or memory blocks. - * according to the definition of MD4 in RFC 1320 from April 1992. Copyright - * (C) 1995,1996,1997,1999,2000,2001,2002,2003,2005,2006 Free Software - * Foundation, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _XCRYPT_H -#define _XCRYPT_H - -#include -#include -#include -#include - -#define MD5_DIGEST_SIZE 16 -#define MD5_BLOCK_SIZE 64 -#define IPAD 0x36 -#define OPAD 0x5c - -#define gl_des_ecb_encrypt(ctx, from, to) gl_des_ecb_crypt(ctx, from, to, 0) -#define gl_des_ecb_decrypt(ctx, from, to) gl_des_ecb_crypt(ctx, from, to, 1) - -/* - * Encryption/Decryption context of DES - */ -typedef struct { - uint32_t encrypt_subkeys[32]; - uint32_t decrypt_subkeys[32]; -} gl_des_ctx; - -/* Structures to save state of computation between the single steps. */ -struct md4_ctx { - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - - uint32_t total[2]; - uint32_t buflen; - uint32_t buffer[32]; -}; - -struct md5_ctx { - uint32_t A; - uint32_t B; - uint32_t C; - uint32_t D; - - uint32_t total[2]; - uint32_t buflen; - uint32_t buffer[32]; -}; - -extern bool gl_des_is_weak_key(const char * key); -extern void gl_des_setkey(gl_des_ctx *ctx, const char * key); -extern bool gl_des_makekey(gl_des_ctx *ctx, const char * key, size_t keylen); -extern void gl_des_ecb_crypt(gl_des_ctx *ctx, const char * _from, char * _to, int mode); - -extern void md4_process_block (const void *buffer, size_t len, struct md4_ctx *ctx); -extern void md4_init_ctx (struct md4_ctx *ctx); -extern void *md4_read_ctx (const struct md4_ctx *ctx, void *resbuf); -extern void *md4_finish_ctx (struct md4_ctx *ctx, void *resbuf); -extern void md4_process_bytes (const void *buffer, size_t len, struct md4_ctx *ctx); -extern int md4_stream(FILE * stream, void *resblock); -extern void *md4_buffer (const char *buffer, size_t len, void *resblock); - -extern int hmac_md5 (const void *key, size_t keylen, const void *in, size_t inlen, void *resbuf); - -extern void md5_init_ctx (struct md5_ctx *ctx); -extern void md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx); -extern void md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx); -extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf); -extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf); -extern int md5_stream (FILE *stream, void *resblock); -extern void *md5_buffer (const char *buffer, size_t len, void *resblock); - -#endif /* _XCRYPT_H */ diff --git a/scripts/init_container.sh b/scripts/init_container.sh index eda1b3e..d033401 100755 --- a/scripts/init_container.sh +++ b/scripts/init_container.sh @@ -40,22 +40,5 @@ then sed -i 's//'${CNTLM_USERNAME}/g /etc/cntlm.conf fi -# Build and install cntlm -FLAG_GCC_INSTALLED=$(which gcc) -FLAG_MAKE_INSTALLED=$(which make) -if [[ -z FLAG_GCC_INSTALLED || -z FLAG_MAKE_INSTALLED ]] -then - echo "Cannot find both make and gcc installed." - exit 1 -fi - -if [ -d /usr/local/src/cntlm-0.92.3/ ] -then - cd /usr/local/src/cntlm-0.92.3/ - ./configure - make - make install -fi - # Start cNTLM in foreground cntlm -f -g -c /etc/cntlm.conf