aboutsummaryrefslogtreecommitdiffstats
path: root/libntlm-0.21
diff options
context:
space:
mode:
authorRob Funk <rfunk@funknet.net>2004-06-08 03:59:01 +0000
committerRob Funk <rfunk@funknet.net>2004-06-08 03:59:01 +0000
commitd78b61e3efaea197a6e5b2b72bf2981a9ed69461 (patch)
tree1704e13ce5d767d59868a2d5e834cb2e988ed90f /libntlm-0.21
parentd9e84e176fe538e110d9612f9832d69846e8d3e7 (diff)
downloadfetchmail-d78b61e3efaea197a6e5b2b72bf2981a9ed69461.tar.gz
fetchmail-d78b61e3efaea197a6e5b2b72bf2981a9ed69461.tar.bz2
fetchmail-d78b61e3efaea197a6e5b2b72bf2981a9ed69461.zip
Add files from ESR's dev directory that weren't under version control
svn path=/trunk/; revision=3881
Diffstat (limited to 'libntlm-0.21')
-rw-r--r--libntlm-0.21/COPYING339
-rw-r--r--libntlm-0.21/HISTORY21
-rw-r--r--libntlm-0.21/Makefile42
-rw-r--r--libntlm-0.21/README98
-rw-r--r--libntlm-0.21/ntlm.h68
-rw-r--r--libntlm-0.21/smb.h52
-rw-r--r--libntlm-0.21/smbbyteorder.h265
-rw-r--r--libntlm-0.21/smbdes.c399
-rw-r--r--libntlm-0.21/smbdes.h9
-rw-r--r--libntlm-0.21/smbencrypt.c323
-rw-r--r--libntlm-0.21/smbencrypt.h2
-rw-r--r--libntlm-0.21/smbmd4.c172
-rw-r--r--libntlm-0.21/smbmd4.h1
-rw-r--r--libntlm-0.21/smbutil.c218
-rwxr-xr-xlibntlm-0.21/test/COPYING339
-rw-r--r--libntlm-0.21/test/Makefile6
-rw-r--r--libntlm-0.21/test/README19
-rw-r--r--libntlm-0.21/test/dumper.c237
-rw-r--r--libntlm-0.21/test/getargs.c240
-rw-r--r--libntlm-0.21/test/getargs.h19
20 files changed, 2869 insertions, 0 deletions
diff --git a/libntlm-0.21/COPYING b/libntlm-0.21/COPYING
new file mode 100644
index 00000000..a43ea212
--- /dev/null
+++ b/libntlm-0.21/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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
+
+ Appendix: 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.
+
+ <signature of Ty Coon>, 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/libntlm-0.21/HISTORY b/libntlm-0.21/HISTORY
new file mode 100644
index 00000000..58c31c57
--- /dev/null
+++ b/libntlm-0.21/HISTORY
@@ -0,0 +1,21 @@
+
+7 October 1999 Revsion 0.21
+
+Added support for usernames with embedded domain strings of the
+format username@domain. If present, the domain will override the
+domain that is returned by the host in the challenge.
+
+6 October 1999 Revision 0.2
+-----------------------------
+
+Fixed another byte-order problem in unicode routine in smbutil.c.
+Added a copy of GPL to the distribution. Added test driver
+program directory.
+
+5 October 1999 Revision 0.1
+-----------------------------
+
+Fixed usage of byte-order macros in smbutil.c. Hopefully this
+will make it work on SPARC machines...
+
+
diff --git a/libntlm-0.21/Makefile b/libntlm-0.21/Makefile
new file mode 100644
index 00000000..3195f4b0
--- /dev/null
+++ b/libntlm-0.21/Makefile
@@ -0,0 +1,42 @@
+CFLAGS=-Wall -g
+
+DEST=/usr/local
+LIBDEST=$(DEST)/lib
+INCDEST=$(DEST)/include
+
+SRCS=smbdes.c smbencrypt.c smbmd4.c smbutil.c
+OBJS=smbdes.o smbencrypt.o smbmd4.o smbutil.o
+
+libntlm.a: $(OBJS)
+ ar cru libntlm.a $(OBJS)
+ ranlib libntlm.a
+
+install: libntlm.a ntlm.h
+ install libntlm.a $(LIBDEST)
+ install ntlm.h $(INCDEST)
+
+clean:
+ rm -f *.a *.o *~ *.bak \#*\#
+
+depend:
+ makedepend $(SRCS)
+# DO NOT DELETE
+
+smbdes.o: smbdes.h
+smbencrypt.o: /usr/include/unistd.h /usr/include/sys/feature_tests.h
+smbencrypt.o: /usr/include/sys/types.h /usr/include/sys/isa_defs.h
+smbencrypt.o: /usr/include/sys/machtypes.h /usr/include/sys/int_types.h
+smbencrypt.o: /usr/include/sys/select.h /usr/include/sys/time.h
+smbencrypt.o: /usr/include/sys/time.h /usr/include/sys/unistd.h
+smbencrypt.o: /usr/include/stdlib.h /usr/include/string.h
+smbencrypt.o: /usr/include/ctype.h smbbyteorder.h smbdes.h smbmd4.h
+smbmd4.o: smbmd4.h
+smbutil.o: /usr/include/unistd.h /usr/include/sys/feature_tests.h
+smbutil.o: /usr/include/sys/types.h /usr/include/sys/isa_defs.h
+smbutil.o: /usr/include/sys/machtypes.h /usr/include/sys/int_types.h
+smbutil.o: /usr/include/sys/select.h /usr/include/sys/time.h
+smbutil.o: /usr/include/sys/time.h /usr/include/sys/unistd.h
+smbutil.o: /usr/include/stdlib.h /usr/include/stdio.h
+smbutil.o: /usr/include/sys/va_list.h /usr/include/ctype.h
+smbutil.o: /usr/include/assert.h /usr/include/string.h ntlm.h smbencrypt.h
+smbutil.o: smbbyteorder.h
diff --git a/libntlm-0.21/README b/libntlm-0.21/README
new file mode 100644
index 00000000..2ce20c39
--- /dev/null
+++ b/libntlm-0.21/README
@@ -0,0 +1,98 @@
+
+This directory contains sources for a library which provides
+routines to manipulate the structures used for the client end
+of Microsoft NTLM authentication.
+
+This code was taken mostly from the Samba project and was
+initially intended for use with Microsoft Exchange Server when
+it is configured to require NTLM authentication for clients of
+it's IMAP server.
+
+BUILDING
+
+If you want the library installed in /usr/local/lib and
+the header in /usr/local/include, then
+
+ $ make
+ $ make install
+
+will probably work. Not much effort has been put into making
+this portable, and I only know for sure that it works on i386
+Linux glibc systems -- though there shouldn't be anything all
+that system-specific anywhere. System byte order differences
+should already be taken care of.
+
+TEST PROGRAM
+
+The test directory contains sources for a program named
+"dumper" that will dump out base64 NTLM auth messages in a
+readable format. It will also take a challenge and generate a
+response if provided with a username and password.
+
+USAGE
+
+The application program must convert these structures to/from
+base64 which is used to transfer data for IMAP authentication.
+For example usage see the sources for the mutt MUA or the
+fetchmail package.
+
+In general the usage is something like shown below (no, I don't
+know if this code even compiles, but you get the idea
+hopefully):
+
+
+#include <ntlm.h>
+
+extern char *seqTag; /* IMAP sequence number */
+
+int imap_auth_ntlm(char *user, char *domain, char *pass)
+{
+ tSmbNtlmAuthRequest request;
+ tSmbNtlmAuthChallenge challenge;
+ tSmbNtlmAuthResponse response;
+ char buffer[512];
+ char tmpstr[32];
+
+ writeToServer("%s AUTHENTICATE NTLM\r\n",seqTag);
+ readFromServer(buffer)
+
+ /* buffer should be "+", but we won't show code to check */
+
+ /*
+ * prepare the request, convert to base64, and send it to
+ * the the server. My server didn't care about domain, and NULL
+ * worked fine.
+ */
+
+ buildSmbNtlmAuthRequest(&request,user,domain);
+ convertToBase64(buffer, &request, SmbLength(&request));
+ writeToServer("%s\r\n",buffer);
+
+ /* read challange data from server, convert from base64 */
+
+ readFromServer(buffer);
+
+ /* buffer should contain the string "+ [base 64 data]" */
+
+ convertFromBase64(&challenge, buffer+2);
+
+ /* prepare response, convert to base64, send to server */
+
+ buildSmbNtlmAuthResponse(&challenge, &response, user, pass);
+ convertToBase64(buffer,&response,SmbLength(&response));
+ writeToServer("%s\r\n",buffer);
+
+ /* read line from server, it should be "[seq] OK blah blah blah" */
+
+ readFromServer(buffer);
+
+ sprintf(tmpstr,"%s OK",seqTag);
+
+ if (strncmp(buffer,tmpstr,strlen(tmpstr)))
+ {
+ /* login failed */
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libntlm-0.21/ntlm.h b/libntlm-0.21/ntlm.h
new file mode 100644
index 00000000..3f6d206f
--- /dev/null
+++ b/libntlm-0.21/ntlm.h
@@ -0,0 +1,68 @@
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned char uint8;
+
+
+/*
+ * These structures are byte-order dependant, and should not
+ * be manipulated except by the use of the routines provided
+ */
+
+typedef struct
+{
+uint16 len;
+uint16 maxlen;
+uint32 offset;
+}tSmbStrHeader;
+
+typedef struct
+{
+char ident[8];
+uint32 msgType;
+uint32 flags;
+tSmbStrHeader user;
+tSmbStrHeader domain;
+uint8 buffer[1024];
+uint32 bufIndex;
+}tSmbNtlmAuthRequest;
+
+typedef struct
+{
+char ident[8];
+uint32 msgType;
+tSmbStrHeader uDomain;
+uint32 flags;
+uint8 challengeData[8];
+uint8 reserved[8];
+tSmbStrHeader emptyString;
+uint8 buffer[1024];
+uint32 bufIndex;
+}tSmbNtlmAuthChallenge;
+
+
+typedef struct
+{
+char ident[8];
+uint32 msgType;
+tSmbStrHeader lmResponse;
+tSmbStrHeader ntResponse;
+tSmbStrHeader uDomain;
+tSmbStrHeader uUser;
+tSmbStrHeader uWks;
+tSmbStrHeader sessionKey;
+uint32 flags;
+uint8 buffer[1024];
+uint32 bufIndex;
+}tSmbNtlmAuthResponse;
+
+/* public: */
+
+#define SmbLength(ptr) (((ptr)->buffer - (uint8*)(ptr)) + (ptr)->bufIndex)
+
+extern void dumpSmbNtlmAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request);
+extern void dumpSmbNtlmAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge);
+extern void dumpSmbNtlmAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response);
+
+extern void buildSmbNtlmAuthRequest(tSmbNtlmAuthRequest *request, char *user, char *domain);
+extern void buildSmbNtlmAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, char *user, char *password);
+
diff --git a/libntlm-0.21/smb.h b/libntlm-0.21/smb.h
new file mode 100644
index 00000000..eb5e382e
--- /dev/null
+++ b/libntlm-0.21/smb.h
@@ -0,0 +1,52 @@
+typedef unsigned short uint16;
+typedef unsigned uint32;
+typedef unsigned char uint8;
+
+typedef struct
+{
+uint16 len;
+uint16 maxlen;
+uint32 offset;
+}tSmbStrHeader;
+
+typedef struct
+{
+char ident[8];
+uint32 msgType;
+uint32 flags;
+tSmbStrHeader user;
+tSmbStrHeader domain;
+uint8 buffer[1024];
+uint32 bufIndex;
+}tSmbNtlmAuthRequest;
+
+typedef struct
+{
+char ident[8];
+uint32 msgType;
+tSmbStrHeader uDomain;
+uint32 flags;
+uint8 challengeData[8];
+uint8 reserved[8];
+tSmbStrHeader emptyString;
+uint8 buffer[1024];
+uint32 bufIndex;
+}tSmbNtlmAuthChallenge;
+
+
+typedef struct
+{
+char ident[8];
+uint32 msgType;
+tSmbStrHeader lmResponse;
+tSmbStrHeader ntResponse;
+tSmbStrHeader uDomain;
+tSmbStrHeader uUser;
+tSmbStrHeader uWks;
+tSmbStrHeader sessionKey;
+uint32 flags;
+uint8 buffer[1024];
+uint32 bufIndex;
+}tSmbNtlmAuthResponse;
+
+#define SmbLength(ptr) (((ptr)->buffer - (uint8*)(ptr)) + (ptr)->bufIndex)
diff --git a/libntlm-0.21/smbbyteorder.h b/libntlm-0.21/smbbyteorder.h
new file mode 100644
index 00000000..59ae4979
--- /dev/null
+++ b/libntlm-0.21/smbbyteorder.h
@@ -0,0 +1,265 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB Byte handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _BYTEORDER_H
+#define _BYTEORDER_H
+
+/*
+ This file implements macros for machine independent short and
+ int manipulation
+
+Here is a description of this file that I emailed to the samba list once:
+
+> I am confused about the way that byteorder.h works in Samba. I have
+> looked at it, and I would have thought that you might make a distinction
+> between LE and BE machines, but you only seem to distinguish between 386
+> and all other architectures.
+>
+> Can you give me a clue?
+
+sure.
+
+The distinction between 386 and other architectures is only there as
+an optimisation. You can take it out completely and it will make no
+difference. The routines (macros) in byteorder.h are totally byteorder
+independent. The 386 optimsation just takes advantage of the fact that
+the x86 processors don't care about alignment, so we don't have to
+align ints on int boundaries etc. If there are other processors out
+there that aren't alignment sensitive then you could also define
+CAREFUL_ALIGNMENT=0 on those processors as well.
+
+Ok, now to the macros themselves. I'll take a simple example, say we
+want to extract a 2 byte integer from a SMB packet and put it into a
+type called uint16 that is in the local machines byte order, and you
+want to do it with only the assumption that uint16 is _at_least_ 16
+bits long (this last condition is very important for architectures
+that don't have any int types that are 2 bytes long)
+
+You do this:
+
+#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+
+then to extract a uint16 value at offset 25 in a buffer you do this:
+
+char *buffer = foo_bar();
+uint16 xx = SVAL(buffer,25);
+
+We are using the byteoder independence of the ANSI C bitshifts to do
+the work. A good optimising compiler should turn this into efficient
+code, especially if it happens to have the right byteorder :-)
+
+I know these macros can be made a bit tidier by removing some of the
+casts, but you need to look at byteorder.h as a whole to see the
+reasoning behind them. byteorder.h defines the following macros:
+
+SVAL(buf,pos) - extract a 2 byte SMB value
+IVAL(buf,pos) - extract a 4 byte SMB value
+SVALS(buf,pos) signed version of SVAL()
+IVALS(buf,pos) signed version of IVAL()
+
+SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer
+SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer
+SSVALS(buf,pos,val) - signed version of SSVAL()
+SIVALS(buf,pos,val) - signed version of SIVAL()
+
+RSVAL(buf,pos) - like SVAL() but for NMB byte ordering
+RSVALS(buf,pos) - like SVALS() but for NMB byte ordering
+RIVAL(buf,pos) - like IVAL() but for NMB byte ordering
+RIVALS(buf,pos) - like IVALS() but for NMB byte ordering
+RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering
+RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering
+RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering
+
+it also defines lots of intermediate macros, just ignore those :-)
+
+*/
+
+/* some switch macros that do both store and read to and from SMB buffers */
+
+#define RW_PCVAL(read,inbuf,outbuf,len) \
+ { if (read) { PCVAL (inbuf,0,outbuf,len); } \
+ else { PSCVAL(inbuf,0,outbuf,len); } }
+
+#define RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
+ { if (read) { if (big_endian) { RPIVAL(inbuf,0,outbuf,len); } else { PIVAL(inbuf,0,outbuf,len); } } \
+ else { if (big_endian) { RPSIVAL(inbuf,0,outbuf,len); } else { PSIVAL(inbuf,0,outbuf,len); } } }
+
+#define RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
+ { if (read) { if (big_endian) { RPSVAL(inbuf,0,outbuf,len); } else { PSVAL(inbuf,0,outbuf,len); } } \
+ else { if (big_endian) { RPSSVAL(inbuf,0,outbuf,len); } else { PSSVAL(inbuf,0,outbuf,len); } } }
+
+#define RW_CVAL(read, inbuf, outbuf, offset) \
+ { if (read) { (outbuf) = CVAL (inbuf,offset); } \
+ else { SCVAL(inbuf,offset,outbuf); } }
+
+#define RW_IVAL(read, big_endian, inbuf, outbuf, offset) \
+ { if (read) { (outbuf) = ((big_endian) ? RIVAL(inbuf,offset) : IVAL (inbuf,offset)); } \
+ else { if (big_endian) { RSIVAL(inbuf,offset,outbuf); } else { SIVAL(inbuf,offset,outbuf); } } }
+
+#define RW_SVAL(read, big_endian, inbuf, outbuf, offset) \
+ { if (read) { (outbuf) = ((big_endian) ? RSVAL(inbuf,offset) : SVAL (inbuf,offset)); } \
+ else { if (big_endian) { RSSVAL(inbuf,offset,outbuf); } else { SSVAL(inbuf,offset,outbuf); } } }
+
+#undef CAREFUL_ALIGNMENT
+
+/* we know that the 386 can handle misalignment and has the "right"
+ byteorder */
+#ifdef __i386__
+#define CAREFUL_ALIGNMENT 0
+#endif
+
+#ifndef CAREFUL_ALIGNMENT
+#define CAREFUL_ALIGNMENT 1
+#endif
+
+#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
+#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
+
+
+#if CAREFUL_ALIGNMENT
+
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
+#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
+#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
+#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
+#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
+#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
+#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
+#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
+#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
+
+#else /* CAREFUL_ALIGNMENT */
+
+/* this handles things for architectures like the 386 that can handle
+ alignment errors */
+/*
+ WARNING: This section is dependent on the length of int16 and int32
+ being correct
+*/
+
+/* get single value from an SMB buffer */
+#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
+#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
+#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
+#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+
+/* store single value in an SMB buffer */
+#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
+#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
+#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
+#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
+
+#endif /* CAREFUL_ALIGNMENT */
+
+/* macros for reading / writing arrays */
+
+#define SMBMACRO(macro,buf,pos,val,len,size) \
+{ int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
+
+#define SSMBMACRO(macro,buf,pos,val,len,size) \
+{ int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
+
+/* reads multiple data from an SMB buffer */
+#define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
+#define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2)
+#define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4)
+#define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1)
+#define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2)
+#define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4)
+
+/* stores multiple data in an SMB buffer */
+#define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1)
+#define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2)
+#define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4)
+#define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1)
+#define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2)
+#define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4)
+
+
+/* now the reverse routines - these are used in nmb packets (mostly) */
+#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
+#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
+
+#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
+#define RSVALS(buf,pos) SREV(SVALS(buf,pos))
+#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
+#define RIVALS(buf,pos) IREV(IVALS(buf,pos))
+#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
+#define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val))
+#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
+#define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val))
+
+/* reads multiple data from an SMB buffer (big-endian) */
+#define RPSVAL(buf,pos,val,len) SMBMACRO(RSVAL,buf,pos,val,len,2)
+#define RPIVAL(buf,pos,val,len) SMBMACRO(RIVAL,buf,pos,val,len,4)
+#define RPSVALS(buf,pos,val,len) SMBMACRO(RSVALS,buf,pos,val,len,2)
+#define RPIVALS(buf,pos,val,len) SMBMACRO(RIVALS,buf,pos,val,len,4)
+
+/* stores multiple data in an SMB buffer (big-endian) */
+#define RPSSVAL(buf,pos,val,len) SSMBMACRO(RSSVAL,buf,pos,val,len,2)
+#define RPSIVAL(buf,pos,val,len) SSMBMACRO(RSIVAL,buf,pos,val,len,4)
+#define RPSSVALS(buf,pos,val,len) SSMBMACRO(RSSVALS,buf,pos,val,len,2)
+#define RPSIVALS(buf,pos,val,len) SSMBMACRO(RSIVALS,buf,pos,val,len,4)
+
+#define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \
+ { RW_PCVAL(read,inbuf,outbuf,len) \
+ DEBUG(5,("%s%04x %s: ", \
+ tab_depth(depth), base,string)); \
+ if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
+ { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
+ DEBUG(5,("\n")); }
+
+#define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
+ { RW_PSVAL(read,big_endian,inbuf,outbuf,len) \
+ DEBUG(5,("%s%04x %s: ", \
+ tab_depth(depth), base,string)); \
+ if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
+ { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
+ DEBUG(5,("\n")); }
+
+#define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
+ { RW_PIVAL(read,big_endian,inbuf,outbuf,len) \
+ DEBUG(5,("%s%04x %s: ", \
+ tab_depth(depth), base,string)); \
+ if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
+ { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
+ DEBUG(5,("\n")); }
+
+#define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
+ { RW_CVAL(read,inbuf,outbuf,0) \
+ DEBUG(5,("%s%04x %s: %02x\n", \
+ tab_depth(depth), base, string, outbuf)); }
+
+#define DBG_RW_SVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
+ { RW_SVAL(read,big_endian,inbuf,outbuf,0) \
+ DEBUG(5,("%s%04x %s: %04x\n", \
+ tab_depth(depth), base, string, outbuf)); }
+
+#define DBG_RW_IVAL(string,depth,base,read,big_endian,inbuf,outbuf) \
+ { RW_IVAL(read,big_endian,inbuf,outbuf,0) \
+ DEBUG(5,("%s%04x %s: %08x\n", \
+ tab_depth(depth), base, string, outbuf)); }
+
+#endif /* _BYTEORDER_H */
diff --git a/libntlm-0.21/smbdes.c b/libntlm-0.21/smbdes.c
new file mode 100644
index 00000000..e3ab78af
--- /dev/null
+++ b/libntlm-0.21/smbdes.c
@@ -0,0 +1,399 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+
+ a partial implementation of DES designed for use in the
+ SMB authentication protocol
+
+ Copyright (C) Andrew Tridgell 1998
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "smbdes.h"
+
+/* NOTES:
+
+ This code makes no attempt to be fast! In fact, it is a very
+ slow implementation
+
+ This code is NOT a complete DES implementation. It implements only
+ the minimum necessary for SMB authentication, as used by all SMB
+ products (including every copy of Microsoft Windows95 ever sold)
+
+ In particular, it can only do a unchained forward DES pass. This
+ means it is not possible to use this code for encryption/decryption
+ of data, instead it is only useful as a "hash" algorithm.
+
+ There is no entry point into this code that allows normal DES operation.
+
+ I believe this means that this code does not come under ITAR
+ regulations but this is NOT a legal opinion. If you are concerned
+ about the applicability of ITAR regulations to this code then you
+ should confirm it for yourself (and maybe let me know if you come
+ up with a different answer to the one above)
+*/
+
+
+#define uchar unsigned char
+
+static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
+ 1, 58, 50, 42, 34, 26, 18,
+ 10, 2, 59, 51, 43, 35, 27,
+ 19, 11, 3, 60, 52, 44, 36,
+ 63, 55, 47, 39, 31, 23, 15,
+ 7, 62, 54, 46, 38, 30, 22,
+ 14, 6, 61, 53, 45, 37, 29,
+ 21, 13, 5, 28, 20, 12, 4};
+
+static uchar perm2[48] = {14, 17, 11, 24, 1, 5,
+ 3, 28, 15, 6, 21, 10,
+ 23, 19, 12, 4, 26, 8,
+ 16, 7, 27, 20, 13, 2,
+ 41, 52, 31, 37, 47, 55,
+ 30, 40, 51, 45, 33, 48,
+ 44, 49, 39, 56, 34, 53,
+ 46, 42, 50, 36, 29, 32};
+
+static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
+ 60, 52, 44, 36, 28, 20, 12, 4,
+ 62, 54, 46, 38, 30, 22, 14, 6,
+ 64, 56, 48, 40, 32, 24, 16, 8,
+ 57, 49, 41, 33, 25, 17, 9, 1,
+ 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5,
+ 63, 55, 47, 39, 31, 23, 15, 7};
+
+static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
+ 4, 5, 6, 7, 8, 9,
+ 8, 9, 10, 11, 12, 13,
+ 12, 13, 14, 15, 16, 17,
+ 16, 17, 18, 19, 20, 21,
+ 20, 21, 22, 23, 24, 25,
+ 24, 25, 26, 27, 28, 29,
+ 28, 29, 30, 31, 32, 1};
+
+static uchar perm5[32] = { 16, 7, 20, 21,
+ 29, 12, 28, 17,
+ 1, 15, 23, 26,
+ 5, 18, 31, 10,
+ 2, 8, 24, 14,
+ 32, 27, 3, 9,
+ 19, 13, 30, 6,
+ 22, 11, 4, 25};
+
+
+static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
+ 39, 7, 47, 15, 55, 23, 63, 31,
+ 38, 6, 46, 14, 54, 22, 62, 30,
+ 37, 5, 45, 13, 53, 21, 61, 29,
+ 36, 4, 44, 12, 52, 20, 60, 28,
+ 35, 3, 43, 11, 51, 19, 59, 27,
+ 34, 2, 42, 10, 50, 18, 58, 26,
+ 33, 1, 41, 9, 49, 17, 57, 25};
+
+
+static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+
+static uchar sbox[8][4][16] = {
+ {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
+ {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
+ {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
+ {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
+
+ {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
+ {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
+ {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
+ {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
+
+ {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
+ {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
+ {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
+ {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
+
+ {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
+ {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
+ {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
+ {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
+
+ {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
+ {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
+ {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
+ {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
+
+ {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
+ {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
+ {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
+ {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
+
+ {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
+ {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
+ {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
+ {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
+
+ {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
+ {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
+ {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
+ {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
+
+static void permute(char *out, char *in, uchar *p, int n)
+{
+ int i;
+ for (i=0;i<n;i++)
+ out[i] = in[p[i]-1];
+}
+
+static void lshift(char *d, int count, int n)
+{
+ char out[64];
+ int i;
+ for (i=0;i<n;i++)
+ out[i] = d[(i+count)%n];
+ for (i=0;i<n;i++)
+ d[i] = out[i];
+}
+
+static void concat(char *out, char *in1, char *in2, int l1, int l2)
+{
+ while (l1--)
+ *out++ = *in1++;
+ while (l2--)
+ *out++ = *in2++;
+}
+
+static void xor(char *out, char *in1, char *in2, int n)
+{
+ int i;
+ for (i=0;i<n;i++)
+ out[i] = in1[i] ^ in2[i];
+}
+
+static void dohash(char *out, char *in, char *key, int forw)
+{
+ int i, j, k;
+ char pk1[56];
+ char c[28];
+ char d[28];
+ char cd[56];
+ char ki[16][48];
+ char pd1[64];
+ char l[32], r[32];
+ char rl[64];
+
+ permute(pk1, key, perm1, 56);
+
+ for (i=0;i<28;i++)
+ c[i] = pk1[i];
+ for (i=0;i<28;i++)
+ d[i] = pk1[i+28];
+
+ for (i=0;i<16;i++) {
+ lshift(c, sc[i], 28);
+ lshift(d, sc[i], 28);
+
+ concat(cd, c, d, 28, 28);
+ permute(ki[i], cd, perm2, 48);
+ }
+
+ permute(pd1, in, perm3, 64);
+
+ for (j=0;j<32;j++) {
+ l[j] = pd1[j];
+ r[j] = pd1[j+32];
+ }
+
+ for (i=0;i<16;i++) {
+ char er[48];
+ char erk[48];
+ char b[8][6];
+ char cb[32];
+ char pcb[32];
+ char r2[32];
+
+ permute(er, r, perm4, 48);
+
+ xor(erk, er, ki[forw ? i : 15 - i], 48);
+
+ for (j=0;j<8;j++)
+ for (k=0;k<6;k++)
+ b[j][k] = erk[j*6 + k];
+
+ for (j=0;j<8;j++) {
+ int m, n;
+ m = (b[j][0]<<1) | b[j][5];
+
+ n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
+
+ for (k=0;k<4;k++)
+ b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
+ }
+
+ for (j=0;j<8;j++)
+ for (k=0;k<4;k++)
+ cb[j*4+k] = b[j][k];
+ permute(pcb, cb, perm5, 32);
+
+ xor(r2, l, pcb, 32);
+
+ for (j=0;j<32;j++)
+ l[j] = r[j];
+
+ for (j=0;j<32;j++)
+ r[j] = r2[j];
+ }
+
+ concat(rl, r, l, 32, 32);
+
+ permute(out, rl, perm6, 64);
+}
+
+static void str_to_key(unsigned char *str,unsigned char *key)
+{
+ int i;
+
+ key[0] = str[0]>>1;
+ key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
+ key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
+ key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
+ key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
+ key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
+ key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
+ key[7] = str[6]&0x7F;
+ for (i=0;i<8;i++) {
+ key[i] = (key[i]<<1);
+ }
+}
+
+
+static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
+{
+ int i;
+ char outb[64];
+ char inb[64];
+ char keyb[64];
+ unsigned char key2[8];
+
+ str_to_key(key, key2);
+
+ for (i=0;i<64;i++) {
+ inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
+ keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
+ outb[i] = 0;
+ }
+
+ dohash(outb, inb, keyb, forw);
+
+ for (i=0;i<8;i++) {
+ out[i] = 0;
+ }
+
+ for (i=0;i<64;i++) {
+ if (outb[i])
+ out[i/8] |= (1<<(7-(i%8)));
+ }
+}
+
+void E_P16(unsigned char *p14,unsigned char *p16)
+{
+ unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
+ smbhash(p16, sp8, p14, 1);
+ smbhash(p16+8, sp8, p14+7, 1);
+}
+
+void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
+{
+ smbhash(p24, c8, p21, 1);
+ smbhash(p24+8, c8, p21+7, 1);
+ smbhash(p24+16, c8, p21+14, 1);
+}
+
+void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
+{
+ smbhash(out, in, p14, 0);
+ smbhash(out+8, in+8, p14+7, 0);
+}
+
+void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out)
+{
+ smbhash(out, in, p14, 1);
+ smbhash(out+8, in+8, p14+7, 1);
+}
+
+void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
+{
+ unsigned char buf[8];
+
+ smbhash(buf, in, key, 1);
+ smbhash(out, buf, key+9, 1);
+}
+
+void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
+{
+ unsigned char buf[8];
+ static unsigned char key2[8];
+
+ smbhash(buf, in, key, 1);
+ key2[0] = key[7];
+ smbhash(out, buf, key2, 1);
+}
+
+void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw)
+{
+ static unsigned char key2[8];
+
+ smbhash(out, in, key, forw);
+ key2[0] = key[7];
+ smbhash(out + 8, in + 8, key2, forw);
+}
+
+void SamOEMhash( unsigned char *data, unsigned char *key, int val)
+{
+ unsigned char s_box[256];
+ unsigned char index_i = 0;
+ unsigned char index_j = 0;
+ unsigned char j = 0;
+ int ind;
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ s_box[ind] = (unsigned char)ind;
+ }
+
+ for( ind = 0; ind < 256; ind++)
+ {
+ unsigned char tc;
+
+ j += (s_box[ind] + key[ind%16]);
+
+ tc = s_box[ind];
+ s_box[ind] = s_box[j];
+ s_box[j] = tc;
+ }
+ for( ind = 0; ind < (val ? 516 : 16); ind++)
+ {
+ unsigned char tc;
+ unsigned char t;
+
+ index_i++;
+ index_j += s_box[index_i];
+
+ tc = s_box[index_i];
+ s_box[index_i] = s_box[index_j];
+ s_box[index_j] = tc;
+
+ t = s_box[index_i] + s_box[index_j];
+ data[ind] = data[ind] ^ s_box[t];
+ }
+}
diff --git a/libntlm-0.21/smbdes.h b/libntlm-0.21/smbdes.h
new file mode 100644
index 00000000..f890fcd5
--- /dev/null
+++ b/libntlm-0.21/smbdes.h
@@ -0,0 +1,9 @@
+
+extern void E_P16(unsigned char *p14,unsigned char *p16);
+extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
+extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
+extern void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out);
+extern void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
+extern void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
+extern void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
+extern void SamOEMhash( unsigned char *data, unsigned char *key, int val);
diff --git a/libntlm-0.21/smbencrypt.c b/libntlm-0.21/smbencrypt.c
new file mode 100644
index 00000000..e58f0d41
--- /dev/null
+++ b/libntlm-0.21/smbencrypt.c
@@ -0,0 +1,323 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1998
+ Modified by Jeremy Allison 1995.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define DEBUG(a,b) ;
+
+extern int DEBUGLEVEL;
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "smbbyteorder.h"
+#include "smbdes.h"
+#include "smbmd4.h"
+
+typedef unsigned char uchar;
+typedef signed short int16;
+typedef unsigned short uint16;
+typedef int BOOL;
+#define False 0
+#define True 1
+
+/****************************************************************************
+ Like strncpy but always null terminates. Make sure there is room!
+ The variable n should always be one less than the available size.
+****************************************************************************/
+
+char *StrnCpy(char *dest,const char *src, size_t n)
+{
+ char *d = dest;
+ if (!dest) return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
+ while (n-- && (*d++ = *src++)) ;
+ *d = 0;
+ return(dest);
+}
+
+size_t skip_multibyte_char(char c)
+{
+return 0;
+}
+
+
+/*******************************************************************
+safe string copy into a known length string. maxlength does not
+include the terminating zero.
+********************************************************************/
+
+char *safe_strcpy(char *dest,const char *src, size_t maxlength)
+{
+ size_t len;
+
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
+ return NULL;
+ }
+
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ len = strlen(src);
+
+ if (len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
+ (int)(len-maxlength), src));
+ len = maxlength;
+ }
+
+ memcpy(dest, src, len);
+ dest[len] = 0;
+ return dest;
+}
+
+
+void strupper(char *s)
+{
+while (*s)
+ {
+ {
+ size_t skip = skip_multibyte_char( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (islower(*s))
+ *s = toupper(*s);
+ s++;
+ }
+ }
+ }
+}
+
+extern void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
+
+/*
+ This implements the X/Open SMB password encryption
+ It takes a password, a 8 byte "crypt key" and puts 24 bytes of
+ encrypted password into p24
+ */
+
+void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
+ {
+ uchar p14[15], p21[21];
+
+ memset(p21,'\0',21);
+ memset(p14,'\0',14);
+ StrnCpy((char *)p14,(char *)passwd,14);
+
+ strupper((char *)p14);
+ E_P16(p14, p21);
+
+ SMBOWFencrypt(p21, c8, p24);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
+ dump_data(100, (char *)p21, 16);
+ dump_data(100, (char *)c8, 8);
+ dump_data(100, (char *)p24, 24);
+#endif
+ }
+
+/* Routines for Windows NT MD4 Hash functions. */
+static int _my_wcslen(int16 *str)
+{
+ int len = 0;
+ while(*str++ != 0)
+ len++;
+ return len;
+}
+
+/*
+ * Convert a string into an NT UNICODE string.
+ * Note that regardless of processor type
+ * this must be in intel (little-endian)
+ * format.
+ */
+
+static int _my_mbstowcs(int16 *dst, uchar *src, int len)
+{
+ int i;
+ int16 val;
+
+ for(i = 0; i < len; i++) {
+ val = *src;
+ SSVAL(dst,0,val);
+ dst++;
+ src++;
+ if(val == 0)
+ break;
+ }
+ return i;
+}
+
+/*
+ * Creates the MD4 Hash of the users password in NT UNICODE.
+ */
+
+void E_md4hash(uchar *passwd, uchar *p16)
+{
+ int len;
+ int16 wpwd[129];
+
+ /* Password cannot be longer than 128 characters */
+ len = strlen((char *)passwd);
+ if(len > 128)
+ len = 128;
+ /* Password must be converted to NT unicode */
+ _my_mbstowcs(wpwd, passwd, len);
+ wpwd[len] = 0; /* Ensure string is null terminated */
+ /* Calculate length in bytes */
+ len = _my_wcslen(wpwd) * sizeof(int16);
+
+ mdfour(p16, (unsigned char *)wpwd, len);
+}
+
+/* Does both the NT and LM owfs of a user's password */
+void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16])
+{
+ char passwd[130];
+
+ memset(passwd,'\0',130);
+ safe_strcpy( passwd, pwd, sizeof(passwd)-1);
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ memset(nt_p16, '\0', 16);
+ E_md4hash((uchar *)passwd, nt_p16);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
+ dump_data(120, passwd, strlen(passwd));
+ dump_data(100, (char *)nt_p16, 16);
+#endif
+
+ /* Mangle the passwords into Lanman format */
+ passwd[14] = '\0';
+ strupper(passwd);
+
+ /* Calculate the SMB (lanman) hash functions of the password */
+
+ memset(p16, '\0', 16);
+ E_P16((uchar *) passwd, (uchar *)p16);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
+ dump_data(120, passwd, strlen(passwd));
+ dump_data(100, (char *)p16, 16);
+#endif
+ /* clear out local copy of user's password (just being paranoid). */
+ memset(passwd, '\0', sizeof(passwd));
+}
+
+/* Does the des encryption from the NT or LM MD4 hash. */
+void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
+{
+ uchar p21[21];
+
+ memset(p21,'\0',21);
+
+ memcpy(p21, passwd, 16);
+ E_P24(p21, c8, p24);
+}
+
+/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
+void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
+{
+ uchar p21[21];
+
+ memset(p21,'\0',21);
+ memcpy(p21, passwd, 8);
+ memset(p21 + 8, 0xbd, 8);
+
+ E_P24(p21, ntlmchalresp, p24);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
+ dump_data(100, (char *)p21, 21);
+ dump_data(100, (char *)ntlmchalresp, 8);
+ dump_data(100, (char *)p24, 24);
+#endif
+}
+
+
+/* Does the NT MD4 hash then des encryption. */
+
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
+{
+ uchar p21[21];
+
+ memset(p21,'\0',21);
+
+ E_md4hash(passwd, p21);
+ SMBOWFencrypt(p21, c8, p24);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
+ dump_data(100, (char *)p21, 16);
+ dump_data(100, (char *)c8, 8);
+ dump_data(100, (char *)p24, 24);
+#endif
+}
+
+#if 0
+
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
+{
+ int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
+
+ if (new_pw_len > 512)
+ {
+ DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
+ return False;
+ }
+
+ /*
+ * Now setup the data area.
+ * We need to generate a random fill
+ * for this area to make it harder to
+ * decrypt. JRA.
+ */
+ generate_random_buffer((unsigned char *)data, 516, False);
+ if (unicode)
+ {
+ struni2( &data[512 - new_pw_len], passwd);
+ }
+ else
+ {
+ fstrcpy( &data[512 - new_pw_len], passwd);
+ }
+ SIVAL(data, 512, new_pw_len);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("make_oem_passwd_hash\n"));
+ dump_data(100, data, 516);
+#endif
+ SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
+
+ return True;
+}
+
+#endif
diff --git a/libntlm-0.21/smbencrypt.h b/libntlm-0.21/smbencrypt.h
new file mode 100644
index 00000000..0f33b062
--- /dev/null
+++ b/libntlm-0.21/smbencrypt.h
@@ -0,0 +1,2 @@
+void SMBencrypt(char *passwd, uint8 *c8, uint8 *p24);
+void SMBNTencrypt(char *passwd, uint8 *c8, uint8 *p24);
diff --git a/libntlm-0.21/smbmd4.c b/libntlm-0.21/smbmd4.c
new file mode 100644
index 00000000..f43d797d
--- /dev/null
+++ b/libntlm-0.21/smbmd4.c
@@ -0,0 +1,172 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ a implementation of MD4 designed for use in the SMB authentication protocol
+ Copyright (C) Andrew Tridgell 1997-1998.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "smbmd4.h"
+
+typedef unsigned uint32;
+
+/* NOTE: This code makes no attempt to be fast!
+
+ It assumes that a int is at least 32 bits long
+*/
+
+static uint32 A, B, C, D;
+
+static uint32 F(uint32 X, uint32 Y, uint32 Z)
+{
+ return (X&Y) | ((~X)&Z);
+}
+
+static uint32 G(uint32 X, uint32 Y, uint32 Z)
+{
+ return (X&Y) | (X&Z) | (Y&Z);
+}
+
+static uint32 H(uint32 X, uint32 Y, uint32 Z)
+{
+ return X^Y^Z;
+}
+
+static uint32 lshift(uint32 x, int s)
+{
+ x &= 0xFFFFFFFF;
+ return ((x<<s)&0xFFFFFFFF) | (x>>(32-s));
+}
+
+#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
+#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s)
+#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s)
+
+/* this applies md4 to 64 byte chunks */
+static void mdfour64(uint32 *M)
+{
+ int j;
+ uint32 AA, BB, CC, DD;
+ uint32 X[16];
+
+ for (j=0;j<16;j++)
+ X[j] = M[j];
+
+ AA = A; BB = B; CC = C; DD = D;
+
+ ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
+ ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
+ ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
+ ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
+ ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
+ ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
+ ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
+ ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
+
+ ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
+ ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
+ ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
+ ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
+ ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
+ ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
+ ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
+ ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
+
+ ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
+ ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
+ ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
+ ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
+ ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
+ ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
+ ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
+ ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
+
+ A += AA; B += BB; C += CC; D += DD;
+
+ A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
+ C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
+
+ for (j=0;j<16;j++)
+ X[j] = 0;
+}
+
+static void copy64(uint32 *M, unsigned char *in)
+{
+ int i;
+
+ for (i=0;i<16;i++)
+ M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
+ (in[i*4+1]<<8) | (in[i*4+0]<<0);
+}
+
+static void copy4(unsigned char *out,uint32 x)
+{
+ out[0] = x&0xFF;
+ out[1] = (x>>8)&0xFF;
+ out[2] = (x>>16)&0xFF;
+ out[3] = (x>>24)&0xFF;
+}
+
+/* produce a md4 message digest from data of length n bytes */
+void mdfour(unsigned char *out, unsigned char *in, int n)
+{
+ unsigned char buf[128];
+ uint32 M[16];
+ uint32 b = n * 8;
+ int i;
+
+ A = 0x67452301;
+ B = 0xefcdab89;
+ C = 0x98badcfe;
+ D = 0x10325476;
+
+ while (n > 64) {
+ copy64(M, in);
+ mdfour64(M);
+ in += 64;
+ n -= 64;
+ }
+
+ for (i=0;i<128;i++)
+ buf[i] = 0;
+ memcpy(buf, in, n);
+ buf[n] = 0x80;
+
+ if (n <= 55) {
+ copy4(buf+56, b);
+ copy64(M, buf);
+ mdfour64(M);
+ } else {
+ copy4(buf+120, b);
+ copy64(M, buf);
+ mdfour64(M);
+ copy64(M, buf+64);
+ mdfour64(M);
+ }
+
+ for (i=0;i<128;i++)
+ buf[i] = 0;
+ copy64(M, buf);
+
+ copy4(out, A);
+ copy4(out+4, B);
+ copy4(out+8, C);
+ copy4(out+12, D);
+
+ A = B = C = D = 0;
+}
+
+
diff --git a/libntlm-0.21/smbmd4.h b/libntlm-0.21/smbmd4.h
new file mode 100644
index 00000000..af739949
--- /dev/null
+++ b/libntlm-0.21/smbmd4.h
@@ -0,0 +1 @@
+extern void mdfour(unsigned char *out, unsigned char *in, int n);
diff --git a/libntlm-0.21/smbutil.c b/libntlm-0.21/smbutil.c
new file mode 100644
index 00000000..415e0665
--- /dev/null
+++ b/libntlm-0.21/smbutil.c
@@ -0,0 +1,218 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+#include <string.h>
+#include "ntlm.h"
+#include "smbencrypt.h"
+#include "smbbyteorder.h"
+
+char versionString[] ="libntlm version 0.21";
+
+/* Utility routines that handle NTLM auth structures. */
+
+/* The [IS]VAL macros are to take care of byte order for non-Intel
+ * Machines -- I think this file is OK, but it hasn't been tested.
+ * The other files (the ones stolen from Samba) should be OK.
+ */
+
+
+/* I am not crazy about these macros -- they seem to have gotten
+ * a bit complex. A new scheme for handling string/buffer fields
+ * in the structures probably needs to be designed
+ */
+
+#define AddBytes(ptr, header, buf, count) \
+{ \
+if (buf && count) \
+ { \
+ SSVAL(&ptr->header.len,0,count); \
+ SSVAL(&ptr->header.maxlen,0,count); \
+ SIVAL(&ptr->header.offset,0,((ptr->buffer - ((uint8*)ptr)) + ptr->bufIndex)); \
+ memcpy(ptr->buffer+ptr->bufIndex, buf, count); \
+ ptr->bufIndex += count; \
+ } \
+else \
+ { \
+ ptr->header.len = \
+ ptr->header.maxlen = 0; \
+ SIVAL(&ptr->header.offset,0,ptr->bufIndex); \
+ } \
+}
+
+#define AddString(ptr, header, string) \
+{ \
+char *p = string; \
+int len = 0; \
+if (p) len = strlen(p); \
+AddBytes(ptr, header, ((unsigned char*)p), len); \
+}
+
+#define AddUnicodeString(ptr, header, string) \
+{ \
+char *p = string; \
+unsigned char *b = NULL; \
+int len = 0; \
+if (p) \
+ { \
+ len = strlen(p); \
+ b = strToUnicode(p); \
+ } \
+AddBytes(ptr, header, b, len*2); \
+}
+
+
+#define GetUnicodeString(structPtr, header) \
+unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
+#define GetString(structPtr, header) \
+toString((((char *)structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
+#define DumpBuffer(fp, structPtr, header) \
+dumpRaw(fp,((unsigned char*)structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
+
+
+static void dumpRaw(FILE *fp, unsigned char *buf, size_t len)
+ {
+ int i;
+
+ for (i=0; i<len; ++i)
+ fprintf(fp,"%02x ",buf[i]);
+
+ fprintf(fp,"\n");
+ }
+
+static char *unicodeToString(char *p, size_t len)
+ {
+ int i;
+ static char buf[1024];
+
+ assert(len+1 < sizeof buf);
+
+ for (i=0; i<len; ++i)
+ {
+ buf[i] = *p & 0x7f;
+ p += 2;
+ }
+
+ buf[i] = '\0';
+ return buf;
+ }
+
+static unsigned char *strToUnicode(char *p)
+ {
+ static unsigned char buf[1024];
+ size_t l = strlen(p);
+ int i = 0;
+
+ assert(l*2 < sizeof buf);
+
+ while (l--)
+ {
+ buf[i++] = *p++;
+ buf[i++] = 0;
+ }
+
+ return buf;
+ }
+
+static unsigned char *toString(char *p, size_t len)
+ {
+ static unsigned char buf[1024];
+
+ assert(len+1 < sizeof buf);
+
+ memcpy(buf,p,len);
+ buf[len] = 0;
+ return buf;
+ }
+
+void dumpSmbNtlmAuthRequest(FILE *fp, tSmbNtlmAuthRequest *request)
+ {
+ fprintf(fp,"NTLM Request:\n");
+ fprintf(fp," Ident = %s\n",request->ident);
+ fprintf(fp," mType = %d\n",IVAL(&request->msgType,0));
+ fprintf(fp," Flags = %08x\n",IVAL(&request->flags,0));
+ fprintf(fp," User = %s\n",GetString(request,user));
+ fprintf(fp," Domain = %s\n",GetString(request,domain));
+ }
+
+void dumpSmbNtlmAuthChallenge(FILE *fp, tSmbNtlmAuthChallenge *challenge)
+ {
+ fprintf(fp,"NTLM Challenge:\n");
+ fprintf(fp," Ident = %s\n",challenge->ident);
+ fprintf(fp," mType = %d\n",IVAL(&challenge->msgType,0));
+ fprintf(fp," Domain = %s\n",GetUnicodeString(challenge,uDomain));
+ fprintf(fp," Flags = %08x\n",IVAL(&challenge->flags,0));
+ fprintf(fp," Challenge = "); dumpRaw(fp, challenge->challengeData,8);
+ }
+
+void dumpSmbNtlmAuthResponse(FILE *fp, tSmbNtlmAuthResponse *response)
+ {
+ fprintf(fp,"NTLM Response:\n");
+ fprintf(fp," Ident = %s\n",response->ident);
+ fprintf(fp," mType = %d\n",IVAL(&response->msgType,0));
+ fprintf(fp," LmResp = "); DumpBuffer(fp,response,lmResponse);
+ fprintf(fp," NTResp = "); DumpBuffer(fp,response,ntResponse);
+ fprintf(fp," Domain = %s\n",GetUnicodeString(response,uDomain));
+ fprintf(fp," User = %s\n",GetUnicodeString(response,uUser));
+ fprintf(fp," Wks = %s\n",GetUnicodeString(response,uWks));
+ fprintf(fp," sKey = "); DumpBuffer(fp, response,sessionKey);
+ fprintf(fp," Flags = %08x\n",IVAL(&response->flags,0));
+ }
+
+void buildSmbNtlmAuthRequest(tSmbNtlmAuthRequest *request, char *user, char *domain)
+ {
+ char *u = strdup(user);
+ char *p = strchr(u,'@');
+
+ if (p)
+ {
+ if (!domain)
+ domain = p+1;
+ *p = '\0';
+ }
+
+ request->bufIndex = 0;
+ memcpy(request->ident,"NTLMSSP\0\0\0",8);
+ SIVAL(&request->msgType,0,1);
+ SIVAL(&request->flags,0,0x0000b207); /* have to figure out what these mean */
+ AddString(request,user,u);
+ AddString(request,domain,domain);
+ free(u);
+ }
+
+void buildSmbNtlmAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, char *user, char *password)
+ {
+ uint8 lmRespData[24];
+ uint8 ntRespData[24];
+ char *d = strdup(GetUnicodeString(challenge,uDomain));
+ char *domain = d;
+ char *u = strdup(user);
+ char *p = strchr(u,'@');
+
+ if (p)
+ {
+ domain = p+1;
+ *p = '\0';
+ }
+
+ SMBencrypt(password, challenge->challengeData, lmRespData);
+ SMBNTencrypt(password, challenge->challengeData, ntRespData);
+
+ response->bufIndex = 0;
+ memcpy(response->ident,"NTLMSSP\0\0\0",8);
+ SIVAL(&response->msgType,0,3);
+
+ AddBytes(response,lmResponse,lmRespData,24);
+ AddBytes(response,ntResponse,ntRespData,24);
+ AddUnicodeString(response,uDomain,domain);
+ AddUnicodeString(response,uUser,u);
+ AddUnicodeString(response,uWks,u);
+ AddString(response,sessionKey,NULL);
+
+ response->flags = challenge->flags;
+
+ free(d);
+ free(u);
+ }
+
diff --git a/libntlm-0.21/test/COPYING b/libntlm-0.21/test/COPYING
new file mode 100755
index 00000000..a43ea212
--- /dev/null
+++ b/libntlm-0.21/test/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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
+
+ Appendix: 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.
+
+ <signature of Ty Coon>, 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/libntlm-0.21/test/Makefile b/libntlm-0.21/test/Makefile
new file mode 100644
index 00000000..d99dcb09
--- /dev/null
+++ b/libntlm-0.21/test/Makefile
@@ -0,0 +1,6 @@
+dumper: dumper.c getargs.o
+ gcc -g -I.. -o dumper dumper.c getargs.o ../libntlm.a
+
+clean:
+ rm -f *.a *.o dumper *.bak *~ \#*\#
+
diff --git a/libntlm-0.21/test/README b/libntlm-0.21/test/README
new file mode 100644
index 00000000..bcff72ac
--- /dev/null
+++ b/libntlm-0.21/test/README
@@ -0,0 +1,19 @@
+
+Dumper is a simple command line utility to display in readable
+format base64 NTLM messages. Given a base64 NTLM challenge, a
+username and a password, it will optionally generate and
+display a response message.
+
+Note that there are multiple correct response messages message
+depending on what order the string data is placed at the end of
+the frame. There is no required order. Dumper should always
+generate the string data in the same order (and thus identical
+base64 responses), even on different architectures.
+
+It's possible that another application will generate a
+different but also correct response message.
+
+Run "dumper -?" for help.
+
+Someday I'll write more documentation...
+
diff --git a/libntlm-0.21/test/dumper.c b/libntlm-0.21/test/dumper.c
new file mode 100644
index 00000000..aa84d127
--- /dev/null
+++ b/libntlm-0.21/test/dumper.c
@@ -0,0 +1,237 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ntlm.h>
+
+#include "getargs.h"
+
+int from64tobits(char *out, const char *in);
+void to64frombits(unsigned char *out, const unsigned char *in, int inlen);
+
+int dumpReq;
+int dumpChal;
+int dumpResp;
+int genResp;
+int dumpRaw;
+int dumpb64only;
+int genReq;
+
+char *username = "joeuser";
+char *password = "joespw";
+
+argSpec argSpecArray[] =
+{
+ {'q', OptionBoolean, &dumpReq, NULL, "dump NTLM request", NULL},
+ {'Q', OptionBoolean, &genReq, NULL, "generate (and dump) NTLM request", NULL},
+ {'c', OptionBoolean, &dumpChal, NULL, "dump NTLM challange", NULL},
+ {'g', OptionBoolean, &genResp, NULL, "generate (and dump) NTLM response given a challenge", NULL},
+ {'r', OptionBoolean, &dumpResp, NULL, "dump NTLM response", NULL},
+ {'R', OptionBoolean, &dumpRaw, NULL, "dump raw bytes", NULL},
+ {'6', OptionBoolean, &dumpb64only, NULL, "dump generated base64 only", NULL},
+ {'u', OptionString, &username, NULL, "username", NULL},
+ {'p', OptionString, &password, NULL, "password", NULL},
+};
+
+int argSpecCount = (sizeof argSpecArray / sizeof argSpecArray[0]);
+char *progName;
+
+void usage(void)
+{
+ printf("usage: %s [options] [base-64-string]\n", progName);
+ printf(" %s -? will display options\n", progName);
+}
+
+unsigned char buf[4096];
+unsigned char buf2[4096];
+
+int main(int argc, char *argv[])
+{
+ int rawLen = 0;
+ int argsUsed;
+ int i;
+
+ progName = argv[0];
+
+ argsUsed = getargs(argc, argv, argSpecArray, argSpecCount);
+
+ if (argsUsed < 0)
+ {
+ usage();
+ exit(1);
+ }
+
+ argc -= argsUsed;
+ argv += argsUsed;
+
+ if (argc != 1 && argc != 0)
+ {
+ usage();
+ exit(1);
+ }
+
+
+ if (argc == 1)
+ {
+ rawLen = from64tobits(buf,argv[0]);
+ if (genReq)
+ fprintf(stderr,"%s: extra argument with -Q ignored\n",progName);
+ }
+ else
+ {
+ if (dumpReq || dumpChal || dumpResp || dumpRaw)
+ {
+ fprintf(stderr,"%s: -q -r -c -R specified but no base64 data\n",progName);
+ return 1;
+ }
+ }
+
+
+ printf("Converted base64 string to %d data bytes\n",rawLen);
+
+ if (dumpReq)
+ dumpSmbNtlmAuthRequest(stdout,(tSmbNtlmAuthRequest*)buf);
+ else if (dumpChal)
+ dumpSmbNtlmAuthChallenge(stdout,(tSmbNtlmAuthChallenge*)buf);
+ else if (dumpResp)
+ dumpSmbNtlmAuthResponse(stdout,(tSmbNtlmAuthResponse*)buf);
+
+ if (dumpRaw)
+ for (i=0; i<rawLen; ++i)
+ printf("%3d: %02x\n",i,buf[i]);
+
+ if (genReq)
+ {
+ buildSmbNtlmAuthRequest((tSmbNtlmAuthRequest*)buf2,username,NULL);
+ to64frombits(buf, buf2, SmbLength((tSmbNtlmAuthResponse*)buf2));
+
+ printf("%s\n",buf);
+
+ if (!dumpb64only)
+ dumpSmbNtlmAuthRequest(stdout,(tSmbNtlmAuthRequest*)buf2);
+ }
+
+ if (genResp)
+ {
+ buildSmbNtlmAuthResponse((tSmbNtlmAuthChallenge*)buf,
+ (tSmbNtlmAuthResponse*)buf2,
+ username,password);
+
+ to64frombits(buf, buf2, SmbLength((tSmbNtlmAuthResponse*)buf2));
+
+ printf("%s\n",buf);
+
+ if (!dumpb64only)
+ dumpSmbNtlmAuthResponse(stdout,(tSmbNtlmAuthResponse*)buf2);
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+/*
+ * base64.c -- base-64 conversion routines.
+ *
+ * For license terms, see the file COPYING in this directory.
+ *
+ * This base 64 encoding is defined in RFC2045 section 6.8,
+ * "Base64 Content-Transfer-Encoding", but lines must not be broken in the
+ * scheme used here.
+ */
+
+/*
+ * This code borrowed from fetchmail sources
+ */
+
+
+static const char base64digits[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+#define BAD -1
+static const char base64val[] = {
+ BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
+ BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
+ BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
+ BAD, 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,BAD, BAD,BAD,BAD,BAD,
+ BAD, 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,BAD, BAD,BAD,BAD,BAD
+};
+#define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
+
+void to64frombits(unsigned char *out, const unsigned char *in, int inlen)
+/* raw bytes in quasi-big-endian order to base 64 string (NUL-terminated) */
+{
+ for (; inlen >= 3; inlen -= 3)
+ {
+ *out++ = base64digits[in[0] >> 2];
+ *out++ = base64digits[((in[0] << 4) & 0x30) | (in[1] >> 4)];
+ *out++ = base64digits[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
+ *out++ = base64digits[in[2] & 0x3f];
+ in += 3;
+ }
+ if (inlen > 0)
+ {
+ unsigned char fragment;
+
+ *out++ = base64digits[in[0] >> 2];
+ fragment = (in[0] << 4) & 0x30;
+ if (inlen > 1)
+ fragment |= in[1] >> 4;
+ *out++ = base64digits[fragment];
+ *out++ = (inlen < 2) ? '=' : base64digits[(in[1] << 2) & 0x3c];
+ *out++ = '=';
+ }
+ *out = '\0';
+}
+
+int from64tobits(char *out, const char *in)
+/* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
+{
+ int len = 0;
+ register unsigned char digit1, digit2, digit3, digit4;
+
+ if (in[0] == '+' && in[1] == ' ')
+ in += 2;
+ if (*in == '\r')
+ return(0);
+
+ do {
+ digit1 = in[0];
+ if (DECODE64(digit1) == BAD)
+ return(-1);
+ digit2 = in[1];
+ if (DECODE64(digit2) == BAD)
+ return(-1);
+ digit3 = in[2];
+ if (digit3 != '=' && DECODE64(digit3) == BAD)
+ return(-1);
+ digit4 = in[3];
+ if (digit4 != '=' && DECODE64(digit4) == BAD)
+ return(-1);
+ in += 4;
+ *out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
+ ++len;
+ if (digit3 != '=')
+ {
+ *out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
+ ++len;
+ if (digit4 != '=')
+ {
+ *out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
+ ++len;
+ }
+ }
+ } while
+ (*in && *in != '\r' && digit4 != '=');
+
+ return (len);
+}
+
+/* base64.c ends here */
diff --git a/libntlm-0.21/test/getargs.c b/libntlm-0.21/test/getargs.c
new file mode 100644
index 00000000..ca81fc4d
--- /dev/null
+++ b/libntlm-0.21/test/getargs.c
@@ -0,0 +1,240 @@
+#include "getargs.h"
+#include <stdio.h>
+#include <string.h>
+
+double dummy(double x)
+{
+return x * 56.7;
+}
+
+static int findString(char *name, char **namelist)
+ {
+ int i;
+
+ for (i=0; *namelist; ++namelist, ++i)
+ if (!strcmp(name, *namelist))
+ return i;
+ return -1;
+ }
+
+static char *progName;
+
+typedef int (*fptrNoParam)(void);
+typedef int (*fptrParam)(char*);
+
+static void errorMsg(char c, const char *expected, const char *got)
+ {
+ fprintf(stderr,"%s: option -%c expected %s parameter, got '%s'\n",progName,c,expected,got);
+ }
+
+static void prOptions(argSpec arg[], int specCount)
+ {
+ int i;
+ fprintf(stderr,"%s: options: \n",progName);
+
+ for (i=0; i<specCount; ++i)
+ {
+ fprintf(stderr," -%c ",arg[i].optionChar);
+ switch (arg[i].optionType)
+ {
+ case OptionInteger: fprintf(stderr,"<integer> "); break;
+ case OptionLong: fprintf(stderr,"<long> "); break;
+ case OptionDouble: fprintf(stderr,"<float> "); break;
+ case OptionString: fprintf(stderr,"<string> "); break;
+ case OptionBoolean: fprintf(stderr," "); break;
+ case OptionEnumerated: fprintf(stderr,"<string> "); break;
+ }
+ fprintf(stderr,arg[i].helpString);
+ if (arg[i].optionType == OptionEnumerated)
+ {
+ char **s;
+ int d = *(unsigned*)arg[i].optionPtr;
+ int n;
+ fprintf(stderr,"\n");
+ fprintf(stderr," where <string> is one of:\n");
+ for (n=0,s=arg[i].enumValues; *s; ++s,++n)
+ fprintf(stderr," %s%s\n",*s,n==d ? " (default)" : "");
+ }
+ else
+ {
+ switch (arg[i].optionType)
+ {
+ case OptionInteger: fprintf(stderr," (default %d)\n",*(int*)arg[i].optionPtr); break;
+ case OptionLong: fprintf(stderr," (default %ld)\n",*(long*)arg[i].optionPtr); break;
+ case OptionDouble: fprintf(stderr," (default %f)\n",*(double*)arg[i].optionPtr); break;
+ case OptionString: fprintf(stderr," (default '%s')\n",*(char**)arg[i].optionPtr); break;
+ case OptionBoolean: fprintf(stderr,"\n"); break;
+ case OptionEnumerated: break;
+ }
+ }
+ }
+ }
+
+union
+ {
+ int i;
+ long l;
+ double d;
+ char *p;
+ }trash;
+
+int getargs(int argc, char *argv[], argSpec arg[], int specCount)
+ {
+ int argsUsed;
+ char *p;
+ int a;
+ int argDone;
+
+ progName = argv[0];
+ argsUsed = 1;
+ ++argv;
+
+ while (argsUsed < argc)
+ {
+ /* at this point, argv[0] is the next item to be processed */
+
+ p = argv[0];
+
+ if (*p != '-')
+ return argsUsed;
+
+ ++argsUsed;
+ ++argv;
+
+ ++p;
+
+ if (*p =='?')
+ {
+ prOptions(arg,specCount);
+ return -1;
+ }
+
+ argDone = 0;
+
+ for (a=0; a<specCount;)
+ {
+ char *optionArgPtr = "";
+ void *optionPtr = &trash;
+
+ if (*p == arg[a].optionChar)
+ {
+ if (arg[a].optionType != OptionBoolean)
+ {
+ if (p[1] != '\0')
+ optionArgPtr = p+1;
+ else
+ {
+ optionArgPtr = argv[0];
+ ++argsUsed;
+ ++argv;
+ }
+
+ if (argsUsed > argc)
+ {
+ errorMsg(*p,"","");
+ return -1;
+ }
+ }
+
+ if (arg[a].optionPtr)
+ optionPtr = arg[a].optionPtr;
+
+ switch (arg[a].optionType)
+ {
+ case OptionInteger:
+ {
+ char *format = "%d";
+ if (optionArgPtr[0]=='x')
+ {
+ format = "%x";
+ ++optionArgPtr;
+ }
+ else if (optionArgPtr[0]=='0' && optionArgPtr[1]=='x')
+ {
+ format = "%x";
+ optionArgPtr+=2;
+ }
+
+ if (sscanf(optionArgPtr,format,optionPtr) != 1)
+ {
+ errorMsg(*p,"integer",optionArgPtr);
+ return -1;
+ }
+ break;
+ }
+
+ case OptionLong:
+ if (sscanf(optionArgPtr,"%ld",(long*)optionPtr) != 1)
+ {
+ errorMsg(*p,"long",optionArgPtr);
+ return -1;
+ }
+ break;
+
+ case OptionString:
+ *((char**)optionPtr) = strdup(optionArgPtr);
+ break;
+
+ case OptionDouble:
+ if (sscanf(optionArgPtr,"%lf",(double*)optionPtr) != 1)
+ {
+ errorMsg(*p,"floating point",optionArgPtr);
+ return -1;
+ }
+ break;
+
+ case OptionBoolean:
+ *((int*)optionPtr) = 1;
+ break;
+
+ case OptionEnumerated:
+ if ((*((int*)optionPtr) = findString(optionArgPtr,arg[a].enumValues)) < 0)
+ {
+ char **n = arg[a].enumValues;
+ fprintf(stderr,"%s: option -%c expects parameter to be one of:\n",progName,*p);
+ while (*n)
+ {
+ fprintf(stderr," %s\n",*n);
+ ++n;
+ }
+ return -1;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (arg[a].funcPtr)
+ {
+ int s = (*arg[a].funcPtr)(optionArgPtr);
+ if (s<0)
+ return s;
+ }
+
+ if (arg[a].optionType == OptionBoolean)
+ {
+ ++p;
+ if (*p != '\0')
+ {
+ a = 0;
+ continue;
+ }
+ }
+
+ argDone = 1;
+ break;
+ }
+ ++a;
+ }
+
+ if (!argDone)
+ {
+ fprintf(stderr,"%s: unrecognized option '%c'\n",progName,*p);
+ prOptions(arg,specCount);
+ return -1;
+ }
+ }
+ return argsUsed;
+ }
+
diff --git a/libntlm-0.21/test/getargs.h b/libntlm-0.21/test/getargs.h
new file mode 100644
index 00000000..1f5a1857
--- /dev/null
+++ b/libntlm-0.21/test/getargs.h
@@ -0,0 +1,19 @@
+typedef struct
+ {
+ char optionChar;
+ enum
+ {
+ OptionInteger,
+ OptionDouble,
+ OptionLong,
+ OptionString,
+ OptionBoolean,
+ OptionEnumerated
+ } optionType;
+ void *optionPtr;
+ int (*funcPtr)(char *param);
+ char *helpString;
+ char **enumValues;
+ }argSpec;
+
+extern int getargs(int argc, char *argv[], argSpec *arg, int numberSpecs);