pax_global_header00006660000000000000000000000064146026310450014513gustar00rootroot0000000000000052 comment=dd620697dbc3a4e06fa83a5666018a1128c8ac4d jmk-foofus-medusa-dd62069/000077500000000000000000000000001460263104500154075ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/.github/000077500000000000000000000000001460263104500167475ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/.github/workflows/000077500000000000000000000000001460263104500210045ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/.github/workflows/c-cpp.yml000066400000000000000000000013521460263104500225320ustar00rootroot00000000000000name: C/C++ CI on: push: pull_request: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: prepare autoconf run: autoreconf -if - name: install dependencies (minimal build) run: sudo apt install build-essential autoconf libssl-dev - name: configure run: ./configure - name: make run: make - name: install dependencies (full build) run: | sudo apt update sudo apt install libpq5 libpq-dev libssh2-1 libssh2-1-dev libgnutls28-dev libsvn-dev freerdp2-dev - name: configure run: ./configure - name: make run: make - name: make check run: make check - name: make distcheck run: make distcheck jmk-foofus-medusa-dd62069/AUTHORS000066400000000000000000000015041460263104500164570ustar00rootroot00000000000000JoMo-Kun --------------------------------------- *Medusa core design/implementation *Modules: SMBNT, MS-SQL, SSH2, MySQL, VNC, Wrapper, CVS, NCP, PostgreSQL, SMTP/VRFY, SNMP, SVN, VmAuthd, HTTP (NTLM), PcAnywhere, POP3, RDP fizzgig --------------------------------------- *Networking code *Implementation of loadable module code *Modules: TELNET, HTTP pMonkey --------------------------------------- *Modules: AFP, FTP, IMAP, MySQL, REXEC, RLOGIN, RSH, SMTP-AUTH Foofus --------------------------------------- *Design of loadable modules Bokojan --------------------------------------- *Testing scripts Luciano Bello --------------------------------------- *Modules: WEB-FORM jmk-foofus-medusa-dd62069/COPYING000066400000000000000000000432541460263104500164520ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. jmk-foofus-medusa-dd62069/ChangeLog000066400000000000000000000313421460263104500171640ustar00rootroot00000000000000================================================================ Version 2.3 (2024/04) ================================================================ Medusa Core Updates: - General code clean-up and compiler warning squashing - Updated OpenSSL calls from 1.x to 3.x - Log timestamps on password checks - Multiple bugfixes from contributors (see commit log) Module Updates: RDP - FreeRDP 2.0 support SMBNT - SMBv2/3 and SMB signing support (libsmb2) VNC - Removed UltraVNC MS-Logon I/II support due to OpenSSL updates ================================================================ Version 2.2 ================================================================ Medusa Core Updates: - General code clean-up and compiler warning squashing Module Updates: HTTP - NTLM2 session response support - Report domain name provided in NTLM challenge (verbose output) - Allow inclusion of custom headers RDP - Initial release of RDP module (FreeRDP-based) - Support for pass-the-hash authentication SMB - Report account access (admin vs user-level) through ADMIN$ connection SMTP-VRFY - Added EXPN/RCPT support SSH - Fix OS X multi-thread issues ================================================================ Version 2.1.1 ================================================================ Minor release updates: - GCC 4.7 compile issue ("-module" removed) - SMBNT: fix infinite loop issue when testing against OS X - SNMP: remove socket flushing that caused us to miss passwords - IMAP: less restrictive regex to better match OK responses - POP3: restart connection after each attempt to deal with shunning ================================================================ Version 2.1 ================================================================ Medusa Core Updates: - Combo format now accepts "host:user:lm hash:ntlm hash" - Autoconf updates and fixes - Removed PCRE library dependency (using stock glibc regex support) Module Updates: - Numerous bug-fixes across modules (e.g., SSH2 thread-safety) - Support for UltraVNC MS-Logon (local/domain Windows credentials) Additional Updates: - Third-party GUI released: http://wiki.taksmind.org/index.php?title=Medusa-gui ================================================================ Version 2.0 ================================================================ Medusa Core Updates: -Pool-based thread handling Previous version destroyed threads following the completion of a host or user test. The use of a thread pool should decrease the overall application overhead by limiting the frequency of thread destruction and creation. The original code ran into issues in several specific situations (e.g. testing over a thousand users with only a single password). Such cases resulted in a large number of threads being created and destroyed in short order, frequently resulting in an application crash. The thread pool should eliminate this particular problem. -Modules now request next credential set (username + password) Modules previously called getNextPass(), which returned a valid password until the password list for the user being tested was exhausted. At that point, the module exited and the login thread was destroyed. A new thread and module instance would be created for the next user to test. We now use getNextCredetialSet(), which returns a valid user and password. This allows the module to get the next user to test and decide whether the connection needs to be completely torn down or not. -Secondary user credential queue added for missed login tests. In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. The previous version simply printed the username and password combinations which were not tested and moved on. We now push these missed credentials into a host specific queue. Once the login threads have finished their normal checks, they move on to this queue and retry the previously missed credentials. In some cases, say it's the last thread that pushed something into the queue before exiting, we kick-off a clean-up thread to walk through any remaining items. -Host and User-level Resume Support for host and user-level resuming of a scan. When Medusa receives a SIGINT, it will calculate and display a "resume map". This map can then be supplied to the next run. For example, "medusa [OPTIONS PREVIOUSLY USED] -Z h6u1u2h8.". This map describes which hosts were completed and which systems had not been touched. If a host was partially completed, it describes which users had been tested for that specific system. It should be noted that password-level resuming is not supported. If a user's password list was only partially completed, testing of the user will be restarted on resume. Module Updates: FTP -Misc. fixes IMAP -Domain module option for BASIC/NTLM authentication types -Allow auth type to be specified -Misc. fixes (NTLM base64 length, restart HTTP connection after each request) IMAP -Domain module option for LOGIN/NTLM authentication types -Regex-based server response matching for better handling of slow targets -Misc. fixes (handle dropped connections, force TLSv1, base64 length) MSSQL -Auto SQL port identification via "SQL Ping" technique NCP -Misc. fixes (connection retry code) POP3 -Domain module option for NTLM authentication type -Regex-based server response matching for better handling of slow targets -Misc. fixes (base64 length) SMTP -Regex-based server response matching for better handling of slow targets SMTP-VRFY -Misc. fixes (don't include "@" if no domain specified) SSH -Detect and warn if being built on Debian/Ubuntu system (broken libssh2) VMAUTHD -Regex-based server response matching for better handling of slow targets Web-Form -Misc. fixes WRAPPER -Misc. fixes (fix handling of short usernames/passwords) ================================================================ Version 1.5 ================================================================ Medusa Core Updates: -Provides additional information about current account check (e.g. 172.22.110.58 (60 of 104, 51 complete)) -Support for simple resume by host. -Bug fix for "-e" option -Bug fix for displaying hostname vs. IP -Added function for printing a specified length of binary data in hex Module Updates: AFP -Added new module for Apple Filing Protocol from pmonkey HTTP -NTLM auth bug fix -Digest authentication support (MD5 and MD5-sess) IMAP -STARTTLS extension support -NTLM support MYSQL -Misc. bug fixes POP3 -STARTTLS extension support -Better handling of connections dropped by remote server -Support user-supplied domain names -LOGIN, PLAIN, and NTLM support SMBNT -Created framework for different authentication levels (e.g. LM, NTLM, etc). -Support for basic LM authentication to allow for case insensitive bruting -NTLMv2/LMv2 support (Vista bruting) -Fix for guest user check -Support for "DOMAIN\USER" and "DOMAIN\\USER" style names SMTP -Renamed SMTP-AUTH to SMTP -NTLM support SMTP-VRFY -Misc. bug fixes SSH -Honor number of user specified retries -Restart connection when server fails to respond with auth modes after several attempts TELNET -Basic AS/400 Telnet / TN5250 support -Log hosts supplying only a password prompt (non-AAA) VMAUTHD -Misc. bug fixes WEB-FORM -Misc. bug fixes for user-supplied FORM-DATA value Misc. Updates: -Added ZSH Functions file -Updated Medusa ebuild version and added new module dependencies. ================================================================ Version 1.4 ================================================================ Medusa Core Updates: -Major re-working of the autoconf setup. Modules can now be enabled/disabled individually. Also, modules for which the base dependencies are not satisfied are simply not built. In the past they were compiled, but left in a non-functional state. The default is to build all "stable" modules. -APR version detection -Misc bug fix in networking code -SSL socket rework. Fixes issue with concurrent mixed SSL and non-SSL connections (FTPS). Module Updates: FTP -Added support for explicit and implicit SFTP -Better handling of FTP banners HTTP -Now leaves user specified value intact within Host: header -Minor code cleanup IMAP -LOGIN AUTH support -Added TAG module parameter -No longer restarts connection after each attempt NNTP -Added module with AUTHINFO support POP3 -No longer restarts connection after each attempt MySQL -Misc bug fixes / error handling -Added MySQL pre-4.1 pass-the-hash support NCP -Misc bug fixes SMBNT -Misc bug fixes SMTP-AUTH -AUTH PLAIN support -AUTH LOGIN (e.g. Exchange) support SSH -Handles new libssh2 error messages -Libssh2 (0.18) should no longer cause Medusa to hang on SSHv1 hosts or when the target refuses to send its banner. -Added banner parameter verification (Luciano Bello) VNC -Misc bug fixes WEB-FORM -Added new module from Luciano Bello WRAPPER -Better handling of failed attempts within oracle.pl script ================================================================ Version 1.3 ================================================================ Medusa Core Updates: -Module listing fix for OpenBSD/AMD64 -Autoconf tweaks for NCP & SVN checks -Autoconf tweaks for Solaris/OpenBSD -Removed unnecessary IP address checks -Other minor bug fixes ================================================================ Version 1.2 ================================================================ Moved following modules to stable: NCP, VNC, PostgreSQL, SVN, CVS, VmAuthd, SNMP Medusa Core Updates: -Compile on x86_64, Mac OS X. -Minor bug fixes. -Modified license with OpenSSL GPL exemption. Module Updates: SMBNT -Added AS/400 target support. -Global "-e" option now works with module "PASS:HASH". FTP -Modified response parsing code to support AS/400 brute-forcing. REXEC -Modified response parsing code. Wrapper -Added oracle script. -Added SMB NULL session script. ================================================================ Version 1.1 ================================================================ Added following modules (unstable): CVS, NCP, PostgreSQL, SMTP/VRFY, SNMP, SVN, VmAuthd, VNC Moved following modules to stable: PcAnywhere, FTP, IMAP, RSH, REXEC, RLOGIN, and generic wrapper Medusa Core Updates: -Display module list sorted alphabetically -Compiles on OpenBSD -Added delayed receive functions which allow the modules to specify the timeout for both the initial socket read and the second "is any more data there?" check. -Modified SSL connect function. The function now takes an already existing socket and switches it over to SSL. This is needed for modules like VMAUTHD. -Major rework of network receive function. Original code was copied from Hydra and seemed to have some issues. Module Updates: HTTP -Added check for 301 error code (success) -NTLM authentication support IMAP -Minor code cleanup MySQL -Added support for testing accounts without password PcAnywhere -Added sleep to deal with servers freaking out when attempts arrive too quickly POP3 -Added AS/400 mode. Examines error codes to give us better information about account status. SMBNT -Added check to detect non-existent accounts when auditing an XP client Telnet -Moved receive functions to new delayed receive functions. This is slower, but we should actually be able to brute devices with long logon banners now. Wrapper -Added support for scripts to pass error messages back to Medusa. Misc. Updates: Rdesktop -Added better success/failure detection -Added support to detect various error messages -Added basic W2K support -Added basic OS detection Ebuilds -Updated libssh2 ebuild based on bugs.gentoo.org feedback. -Updated Medusa ebuild based on bugs.gentoo.org feedback. -Updated Medusa version and added new module dependencies. -Modified ncpfs ebuild for "install-dev" option. ================================================================ Version 1.0 ================================================================ Initial release Modules (stable): HTTP, MS-SQL, SMBNT, SSHv2, Telnet, POP3 and MySQL Modules (unstable): RSH, RLOGIN, REXEC, FTP, IMAP, PcAnywhere, and generic wrapper jmk-foofus-medusa-dd62069/INSTALL000066400000000000000000000366141460263104500164520ustar00rootroot00000000000000Installation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without warranty of any kind. Basic Installation ================== Briefly, the shell command './configure && make && make install' should configure, build, and install this package. The following more-detailed instructions are generic; see the 'README' file for instructions specific to this package. Some packages provide this 'INSTALL' file but do not implement all of the features documented below. The lack of an optional feature in a given package is not necessarily a bug. More recommendations for GNU packages can be found in *note Makefile Conventions: (standards)Makefile Conventions. The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a 'Makefile' in each directory of the package. It may also create one or more '.h' files containing system-dependent definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a file 'config.log' containing compiler output (useful mainly for debugging 'configure'). It can also use an optional file (typically called 'config.cache' and enabled with '--cache-file=config.cache' or simply '-C') that saves the results of its tests to speed up reconfiguring. Caching is disabled by default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try to figure out how 'configure' could check whether to do them, and mail diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at some point 'config.cache' contains results you don't want to keep, you may remove or edit it. The file 'configure.ac' (or 'configure.in') is used to create 'configure' by a program called 'autoconf'. You need 'configure.ac' if you want to change it or regenerate 'configure' using a newer version of 'autoconf'. The simplest way to compile this package is: 1. 'cd' to the directory containing the package's source code and type './configure' to configure the package for your system. Running 'configure' might take a while. While running, it prints some messages telling which features it is checking for. 2. Type 'make' to compile the package. 3. Optionally, type 'make check' to run any self-tests that come with the package, generally using the just-built uninstalled binaries. 4. Type 'make install' to install the programs and any data files and documentation. When installing into a prefix owned by root, it is recommended that the package be configured and built as a regular user, and only the 'make install' phase executed with root privileges. 5. Optionally, type 'make installcheck' to repeat any self-tests, but this time using the binaries in their final installed location. This target does not install anything. Running this target as a regular user, particularly if the prior 'make install' required root privileges, verifies that the installation completed correctly. 6. You can remove the program binaries and object files from the source code directory by typing 'make clean'. To also remove the files that 'configure' created (so you can compile the package for a different kind of computer), type 'make distclean'. There is also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. 7. Often, you can also type 'make uninstall' to remove the installed files again. In practice, not all packages have tested that uninstallation works correctly, even though it is required by the GNU Coding Standards. 8. Some packages, particularly those that use Automake, provide 'make distcheck', which can by used by developers to test that all other targets like 'make install' and 'make uninstall' work correctly. This target is generally not run by end users. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. You can give 'configure' initial values for configuration parameters by setting variables in the command line or in the environment. Here is an example: ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run the 'configure' script. 'configure' automatically checks for the source code in the directory that 'configure' is in and in '..'. This is known as a "VPATH" build. With a non-GNU 'make', it is safer to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use 'make distclean' before reconfiguring for another architecture. On MacOS X 10.5 and later systems, you can create libraries and executables that work on multiple system types--known as "fat" or "universal" binaries--by specifying multiple '-arch' options to the compiler but only a single '-arch' option to the preprocessor. Like this: ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ CPP="gcc -E" CXXCPP="g++ -E" This is not guaranteed to produce working output in all cases, you may have to build one architecture at a time and combine the results using the 'lipo' tool if you have problems. Installation Names ================== By default, 'make install' installs the package's commands under '/usr/local/bin', include files under '/usr/local/include', etc. You can specify an installation prefix other than '/usr/local' by giving 'configure' the option '--prefix=PREFIX', where PREFIX must be an absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you pass the option '--exec-prefix=PREFIX' to 'configure', the package uses PREFIX as the prefix for installing programs and libraries. Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give options like '--bindir=DIR' to specify different values for particular kinds of files. Run 'configure --help' for a list of the directories you can set and what kinds of files go in them. In general, the default for these options is expressed in terms of '${prefix}', so that specifying just '--prefix' will affect all of the other directory specifications that were not explicitly provided. The most portable way to affect installation locations is to pass the correct locations to 'configure'; however, many packages provide one or both of the following shortcuts of passing variable assignments to the 'make install' command line to change installation locations without having to reconfigure or recompile. The first method involves providing an override variable for each affected directory. For example, 'make install prefix=/alternate/directory' will choose an alternate location for all directory configuration variables that were expressed in terms of '${prefix}'. Any directories that were specified during 'configure', but not in terms of '${prefix}', must each be overridden at install time for the entire installation to be relocated. The approach of makefile variable overrides for each directory variable is required by the GNU Coding Standards, and ideally causes no recompilation. However, some platforms have known limitations with the semantics of shared libraries that end up requiring recompilation when using this method, particularly noticeable in packages that use GNU Libtool. The second method involves providing the 'DESTDIR' variable. For example, 'make install DESTDIR=/alternate/directory' will prepend '/alternate/directory' before all installation names. The approach of 'DESTDIR' overrides is not required by the GNU Coding Standards, and does not work on platforms that have drive letters. On the other hand, it does better at avoiding recompilation issues, and works well even when some directory options were not specified in terms of '${prefix}' at 'configure' time. Optional Features ================= If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving 'configure' the option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. Some packages pay attention to '--enable-FEATURE' options to 'configure', where FEATURE indicates an optional part of the package. They may also pay attention to '--with-PACKAGE' options, where PACKAGE is something like 'gnu-as' or 'x' (for the X Window System). The 'README' should mention any '--enable-' and '--with-' options that the package recognizes. For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, you can use the 'configure' options '--x-includes=DIR' and '--x-libraries=DIR' to specify their locations. Some packages offer the ability to configure how verbose the execution of 'make' will be. For these packages, running './configure --enable-silent-rules' sets the default to minimal output, which can be overridden with 'make V=1'; while running './configure --disable-silent-rules' sets the default to verbose, which can be overridden with 'make V=0'. Particular systems ================== On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC is not installed, it is recommended to use the following options in order to use an ANSI C compiler: ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" and if that doesn't work, install pre-built binaries of GCC for HP-UX. HP-UX 'make' updates targets which have the same time stamps as their prerequisites, which makes it generally unusable when shipped generated files such as 'configure' are involved. Use GNU 'make' instead. On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its '' header file. The option '-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended to try ./configure CC="cc" and if that doesn't work, try ./configure CC="cc -nodtk" On Solaris, don't put '/usr/ucb' early in your 'PATH'. This directory contains several dysfunctional programs; working variants of these programs are available in '/usr/bin'. So, if you need '/usr/ucb' in your 'PATH', put it _after_ '/usr/bin'. On Haiku, software installed for all users goes in '/boot/common', not '/usr/local'. It is recommended to use the following options: ./configure --prefix=/boot/common Specifying the System Type ========================== There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the _same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the '--build=TYPE' option. TYPE can either be a short name for the system type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file 'config.sub' for the possible values of each field. If 'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will eventually be run) with '--host=TYPE'. Sharing Defaults ================ If you want to set default values for 'configure' scripts to share, you can create a site shell script called 'config.site' that gives default values for variables like 'CC', 'cache_file', and 'prefix'. 'configure' looks for 'PREFIX/share/config.site' if it exists, then 'PREFIX/etc/config.site' if it exists. Or, you can set the 'CONFIG_SITE' environment variable to the location of the site script. A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an Autoconf limitation. Until the limitation is lifted, you can use this workaround: CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash 'configure' Invocation ====================== 'configure' recognizes the following options to control how it operates. '--help' '-h' Print a summary of all of the options to 'configure', and exit. '--help=short' '--help=recursive' Print a summary of the options unique to this package's 'configure', and exit. The 'short' variant lists options used only in the top level, while the 'recursive' variant lists options also present in any nested packages. '--version' '-V' Print the version of Autoconf used to generate the 'configure' script, and exit. '--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. '--config-cache' '-C' Alias for '--cache-file=config.cache'. '--quiet' '--silent' '-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). '--srcdir=DIR' Look for the package's source code in directory DIR. Usually 'configure' can determine that directory automatically. '--prefix=DIR' Use DIR as the installation prefix. *note Installation Names:: for more details, including other options available for fine-tuning the installation locations. '--no-create' '-n' Run the configure checks, but stop before creating any output files. 'configure' also accepts some other, not widely useful, options. Run 'configure --help' for more details. jmk-foofus-medusa-dd62069/LICENSE000066400000000000000000000431771460263104500164300ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {description} Copyright (C) {year} {fullname} 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. {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 Lesser General Public License instead of this License. jmk-foofus-medusa-dd62069/Makefile.am000066400000000000000000000003201460263104500174360ustar00rootroot00000000000000AUTOMAKE_OPTIONS = gnu SUBDIRS = src man_MANS = docs/medusa.1 EXTRA_DIST_HTML != ls $(srcdir)/docs/*.html EXTRA_DIST = docs/medusa.1 $(EXTRA_DIST_HTML) misc/net-analyzer/medusa-2.2.ebuild misc/zsh/_medusa jmk-foofus-medusa-dd62069/Makefile.cvs000066400000000000000000000000761460263104500176440ustar00rootroot00000000000000default: all all: aclocal autoheader automake autoconf jmk-foofus-medusa-dd62069/Makefile.in000066400000000000000000000675361460263104500174750ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = depcomp = am__maybe_remake_depfiles = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" NROFF = nroff MANS = $(man_MANS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ COPYING ChangeLog INSTALL NEWS README TODO compile \ config.guess config.sub depcomp install-sh ltmain.sh missing \ mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APR_CONFIG = @APR_CONFIG@ APR_INCLUDE_DIR = @APR_INCLUDE_DIR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_MOD_PATH = @DEFAULT_MOD_PATH@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODULE_LIBS = @MODULE_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu SUBDIRS = src man_MANS = docs/medusa.1 EXTRA_DIST = docs/medusa.1 $(EXTRA_DIST_HTML) misc/net-analyzer/medusa-2.2.ebuild misc/zsh/_medusa all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu --ignore-deps'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu --ignore-deps \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu --ignore-deps Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile $(MANS) config.h installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-man install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-man1 install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ dist-zstd distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \ tags-am uninstall uninstall-am uninstall-man uninstall-man1 .PRECIOUS: Makefile EXTRA_DIST_HTML != ls $(srcdir)/docs/*.html # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: jmk-foofus-medusa-dd62069/NEWS000066400000000000000000000000001460263104500160740ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/README000077700000000000000000000000001460263104500175412README.mdustar00rootroot00000000000000jmk-foofus-medusa-dd62069/README.md000066400000000000000000000022761460263104500166750ustar00rootroot00000000000000# Foofus.net ~ Medusa **Medusa Parallel Network Login Auditor** Copyright (C) 2024 Joe Mondloch
JoMo-Kun / jmk@foofus.net Medusa is a speedy, parallel, and modular, login brute-forcer. The goal is to support as many services which allow remote authentication as possible. The author considers the following items as some of the key features of this application: - Thread-based parallel testing. Brute-force testing can be performed against multiple hosts, users or passwords concurrently. - Flexible user input. Target information (host/user/password) can be specified in a variety of ways. For example, each item can be either a single entry or a file containing multiple entries. Additionally, a combination file format allows the user to refine their target listing. - Modular design. Each service module exists as an independent .mod file. This means that no modifications are necessary to the core application in order to extend the supported list of services for brute-forcing. - Multiple protocols supported. Many services are currently supported (e.g. SMB [SMBv1-3 w/ SMB signing], HTTP, MS-SQL, POP3, RDP, SSHv2, among others). Documentation: https://jmk-foofus.github.io/medusa/medusa.html jmk-foofus-medusa-dd62069/TODO000066400000000000000000000004171460263104500161010ustar00rootroot00000000000000Future Plans: *Account lockout Microsoft SMB services can often be queried for the account lockout policy or how many attempts are remaining on an account before it is locked. Medusa should be able to auto-detect these values and tested up to the lockout threshold. jmk-foofus-medusa-dd62069/aclocal.m4000066400000000000000000000742651460263104500172650ustar00rootroot00000000000000# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, [m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR jmk-foofus-medusa-dd62069/compile000077500000000000000000000163271460263104500167760ustar00rootroot00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2018 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jmk-foofus-medusa-dd62069/config.guess000077500000000000000000001263731460263104500177430ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval "$set_cc_for_build" cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" # If ldd exists, use it to detect musl libc. if command -v ldd >/dev/null && \ ldd --version 2>&1 | grep -q ^musl then LIBC=musl fi ;; esac # Note: order is significant - the case branches are not exclusive. case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine="${arch}${endian}"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" exit ;; *:MidnightBSD:*:*) echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) echo "$UNAME_MACHINE"-unknown-sortix exit ;; *:Redox:*:*) echo "$UNAME_MACHINE"-unknown-redox exit ;; mips:OSF1:*.*) echo mips-dec-osf1 exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval "$set_cc_for_build" SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ [ "$TARGET_BINARY_INTERFACE"x = x ] then echo m88k-dg-dgux"$UNAME_RELEASE" else echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` case "$UNAME_MACHINE" in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if [ "$HP_ARCH" = "" ]; then eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ "$HP_ARCH" = hppa2.0w ] then eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo "$UNAME_MACHINE"-unknown-osf1mk else echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) case "$UNAME_MACHINE" in x86) echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; i*:UWIN*:*) echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval "$set_cc_for_build" sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; mips64el:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) if objdump -f /bin/sh | grep -q elf32-x86-64; then echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 else echo "$UNAME_MACHINE"-pc-linux-"$LIBC" fi exit ;; xtensa*:Linux:*:*) echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv"$UNAME_RELEASE" else echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; NSV-*:NONSTOP_KERNEL:*:*) echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac echo "$0: unable to guess system type" >&2 case "$UNAME_MACHINE:$UNAME_SYSTEM" in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: jmk-foofus-medusa-dd62069/config.h.in000066400000000000000000000066301460263104500174370ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Location of medusa module files */ #undef DEFAULT_MOD_PATH /* Define to 1 if you have the `asprintf' function. */ #undef HAVE_ASPRINTF /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Found GnuTLS Library */ #undef HAVE_GNUTLS /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Found AFPFS-NG Library */ #undef HAVE_LIBAFPFS /* Define to 1 if you have the `c' library (-lc). */ #undef HAVE_LIBC /* Define to 1 if you have the `crypto' library (-lcrypto). */ #undef HAVE_LIBCRYPTO /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Found FreeRDP2 Library */ #undef HAVE_LIBFREERDP2 /* Found Libgcrypt Library */ #undef HAVE_LIBGCRYPT /* Found NCP Library */ #undef HAVE_LIBNCP /* Found PostgreSQL Library */ #undef HAVE_LIBPQ /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Found libsmb2 Library */ #undef HAVE_LIBSMB2 /* Found SSH2 Library */ #undef HAVE_LIBSSH2 /* Found OpenSSL Library */ #undef HAVE_LIBSSL /* Found SVN Library */ #undef HAVE_LIBSVN_CLIENT_1 /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_CRYPTO_H /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_SSL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasestr' function. */ #undef HAVE_STRCASESTR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Found SVN Library version 1.8 or greater */ #undef HAVE_SVN_CLIENT_LIST3 /* Found SVN Library version 1.10 or greater */ #undef HAVE_SVN_CLIENT_LIST4 /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vasprintf' function. */ #undef HAVE_VASPRINTF /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* SMBNT SMBv2 Support Enabled */ #undef SMBNT_SMB2_SUPPORT_ENABLED /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION jmk-foofus-medusa-dd62069/config.sub000077500000000000000000001064501460263104500174000ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2018 Free Software Foundation, Inc. timestamp='2018-02-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 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, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo "$1" | sed 's/-[^-]*$//'` if [ "$basic_machine" != "$1" ] then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; asmjs) basic_machine=asmjs-unknown ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2*) basic_machine=m68k-bull os=-sysv3 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=$os"spe" ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; nsv-tandem) basic_machine=nsv-tandem ;; nsx-tandem) basic_machine=nsx-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh5el) basic_machine=sh5le-unknown ;; simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; x64) basic_machine=x86_64-pc ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases that might get confused # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # es1800 is here to avoid being matched by es* (a different OS) -es1800*) os=-ose ;; # Now accept the basic system types. # The portable systems comes first. # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -xray | -os68k* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4*) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -pikeos*) # Until real need of OS specific support for # particular features comes up, bare metal # configurations are quite functional. case $basic_machine in arm*) os=-eabi ;; *) os=-elf ;; esac ;; -nacl*) ;; -ios) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; pru-*) os=-elf ;; *-be) os=-beos ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac echo "$basic_machine$os" exit # Local variables: # eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: jmk-foofus-medusa-dd62069/configure000077500000000000000000010010721460263104500173170ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for medusa 2.3_rc1. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='medusa' PACKAGE_TARNAME='medusa' PACKAGE_VERSION='2.3_rc1' PACKAGE_STRING='medusa 2.3_rc1' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="src/medusa.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS DEFAULT_MOD_PATH MODULE_LIBS BUILD_MODULE_WEB_FORM_FALSE BUILD_MODULE_WEB_FORM_TRUE BUILD_MODULE_WRAPPER_FALSE BUILD_MODULE_WRAPPER_TRUE BUILD_MODULE_VNC_FALSE BUILD_MODULE_VNC_TRUE BUILD_MODULE_VMAUTHD_FALSE BUILD_MODULE_VMAUTHD_TRUE BUILD_MODULE_TELNET_FALSE BUILD_MODULE_TELNET_TRUE BUILD_MODULE_SVN_FALSE BUILD_MODULE_SVN_TRUE APR_INCLUDE_DIR APR_CONFIG BUILD_MODULE_SSH_FALSE BUILD_MODULE_SSH_TRUE BUILD_MODULE_SNMP_FALSE BUILD_MODULE_SNMP_TRUE BUILD_MODULE_SMTP_VRFY_FALSE BUILD_MODULE_SMTP_VRFY_TRUE BUILD_MODULE_SMTP_FALSE BUILD_MODULE_SMTP_TRUE BUILD_MODULE_SMBNT_SMB2_FALSE BUILD_MODULE_SMBNT_SMB2_TRUE BUILD_MODULE_SMBNT_FALSE BUILD_MODULE_SMBNT_TRUE BUILD_MODULE_RSH_FALSE BUILD_MODULE_RSH_TRUE BUILD_MODULE_RLOGIN_FALSE BUILD_MODULE_RLOGIN_TRUE BUILD_MODULE_REXEC_FALSE BUILD_MODULE_REXEC_TRUE BUILD_MODULE_RDP_FALSE BUILD_MODULE_RDP_TRUE BUILD_MODULE_POSTGRES_FALSE BUILD_MODULE_POSTGRES_TRUE BUILD_MODULE_POP3_FALSE BUILD_MODULE_POP3_TRUE BUILD_MODULE_PCANYWHERE_FALSE BUILD_MODULE_PCANYWHERE_TRUE BUILD_MODULE_NNTP_FALSE BUILD_MODULE_NNTP_TRUE BUILD_MODULE_NCP_FALSE BUILD_MODULE_NCP_TRUE BUILD_MODULE_MYSQL_FALSE BUILD_MODULE_MYSQL_TRUE BUILD_MODULE_MSSQL_FALSE BUILD_MODULE_MSSQL_TRUE BUILD_MODULE_IMAP_FALSE BUILD_MODULE_IMAP_TRUE BUILD_MODULE_HTTP_FALSE BUILD_MODULE_HTTP_TRUE BUILD_MODULE_FTP_FALSE BUILD_MODULE_FTP_TRUE BUILD_MODULE_CVS_FALSE BUILD_MODULE_CVS_TRUE BUILD_MODULE_AFP_FALSE BUILD_MODULE_AFP_TRUE OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_debug with_postgresql with_afpfsng with_ssl enable_module_afp enable_module_cvs enable_module_ftp enable_module_http enable_module_imap enable_module_mssql enable_module_mysql enable_module_ncp enable_module_nntp enable_module_pcanywhere enable_module_pop3 enable_module_postgres with_freerdp enable_module_rdp enable_module_rexec enable_module_rlogin enable_module_rsh enable_module_smbnt with_libsmb2 enable_module_smbnt_smb2 enable_module_smtp enable_module_smtp_vrfy enable_module_snmp enable_module_ssh enable_module_svn enable_module_telnet enable_module_vmauthd enable_module_vnc enable_module_wrapper enable_module_web_form with_default_mod_path ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures medusa 2.3_rc1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/medusa] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of medusa 2.3_rc1:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-debug=no/yes turn on debugging (default=yes) --enable-module-afp=no/yes Enable AFP module (default=no) --enable-module-cvs=no/yes Enable CVS module (default=yes) --enable-module-ftp=no/yes Enable FTP module (default=yes) --enable-module-http=no/yes Enable HTTP module (default=yes) --enable-module-imap=no/yes Enable IMAP module (default=yes) --enable-module-mssql=no/yes Enable MSSQL module (default=yes) --enable-module-mysql=no/yes Enable MYSQL module (default=yes) --enable-module-ncp=no/yes Enable NCP module (default=yes) --enable-module-nntp=no/yes Enable NNTP module (default=yes) --enable-module-pcanywhere=no/yes Enable PCANYWHERE module (default=yes) --enable-module-pop3=no/yes Enable POP3 module (default=yes) --enable-module-postgres=no/yes Enable POSTGRES module (default=yes) --enable-module-rdp=no/yes Enable RDP module (default=yes) --enable-module-rexec=no/yes Enable REXEC module (default=yes) --enable-module-rlogin=no/yes Enable RLOGIN module (default=yes) --enable-module-rsh=no/yes Enable RSH module (default=yes) --enable-module-smbnt=no/yes Enable SMBNT module (default=yes) --enable-module-smbnt-smb2=no/yes Enable SMBNT module SMBv2 support (default=yes) --enable-module-smtp=no/yes Enable SMTP module (default=yes) --enable-module-smtp-vrfy=no/yes Enable SMTP-VRFY module (default=yes) --enable-module-snmp=no/yes Enable SNMP module (default=yes) --enable-module-ssh=no/yes Enable SSH module (default=yes) --enable-module-svn=no/yes Enable SVN module (default=yes) --enable-module-telnet=no/yes Enable TELNET module (default=yes) --enable-module-vmauthd=no/yes Enable VMAUTHD module (default=yes) --enable-module-vnc=no/yes Enable VNC module (default=yes) --enable-module-wrapper=no/yes Enable WRAPPER module (default=yes) --enable-module-web-form=no/yes Enable WEB-FORM module (default=yes) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-postgresql=prefix Prefix for postgresql include directory (default = /usr) --with-afpfsng=prefix Prefix for afpfs-ng include directory (default = /usr) --with-ssl=prefix Prefix for OpenSSL libraries --with-freerdp=prefix Prefix for FreeRDP include directory (default = /usr) --with-libsmb2=prefix Prefix for libsmb2 include directory (default = /usr) --with-default-mod-path=path Location of medusa module files (default = /usr/local/lib/medusa/modules) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF medusa configure 2.3_rc1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=$ac_mid; break else $as_nop as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_lo=$ac_mid; break else $as_nop as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_hi=$ac_mid else $as_nop as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval (void) { return $2; } static unsigned long int ulongval (void) { return $2; } #include #include int main (void) { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO" then : echo >>conftest.val; read $3 &5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by medusa $as_me 2.3_rc1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="compile missing install-sh config.guess config.sub" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 printf %s "checking target system type... " >&6; } if test ${ac_cv_target+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 printf "%s\n" "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='medusa' VERSION='2.3_rc1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 printf %s "checking size of int... " >&6; } if test ${ac_cv_sizeof_int+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_int" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 printf "%s\n" "$ac_cv_sizeof_int" >&6; } printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 printf %s "checking size of long... " >&6; } if test ${ac_cv_sizeof_long+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_long" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 printf "%s\n" "$ac_cv_sizeof_long" >&6; } printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 printf %s "checking size of long long... " >&6; } if test ${ac_cv_sizeof_long_long+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_long_long" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 printf "%s\n" "$ac_cv_sizeof_long_long" >&6; } printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 printf %s "checking size of short... " >&6; } if test ${ac_cv_sizeof_short+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_short" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 printf "%s\n" "$ac_cv_sizeof_short" >&6; } printf "%s\n" "#define SIZEOF_SHORT $ac_cv_sizeof_short" >>confdefs.h CFLAGS="${CFLAGS=}" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable debugging" >&5 printf %s "checking whether to enable debugging... " >&6; } debug_default="yes" # Check whether --enable-debug was given. if test ${enable_debug+y} then : enableval=$enable_debug; else $as_nop enable_debug=$debug_default fi if test "x$enable_debug" = "xyes"; then CPPFLAGS="$CPPFLAGS -g -DDEBUG" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi # Check whether --with-postgresql was given. if test ${with_postgresql+y} then : withval=$with_postgresql; postgresql_prefix="$withval" else $as_nop postgresql_prefix="/usr" fi # Check whether --with-afpfsng was given. if test ${with_afpfsng+y} then : withval=$with_afpfsng; afpfsng_prefix="$withval" else $as_nop afpfsng_prefix="/usr" fi if test -d "/usr/local/lib" then LDFLAGS="$LDFLAGS -L/usr/local/lib" fi CPPFLAGS="$CPPFLAGS -fPIC" CPPFLAGS="$CPPFLAGS -I/usr/include -I/usr/local/include -I${postgresql_prefix}/include/postgresql -I${postgresql_prefix}/include/pgsql -I${afpfsng_prefix}/include/afpfs-ng" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread support..." >&5 printf "%s\n" "$as_me: checking for pthread support..." >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 printf %s "checking for main in -lpthread... " >&6; } if test ${ac_cv_lib_pthread_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_pthread_main=yes else $as_nop ac_cv_lib_pthread_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 printf "%s\n" "$ac_cv_lib_pthread_main" >&6; } if test "x$ac_cv_lib_pthread_main" = xyes then : printf "%s\n" "#define HAVE_LIBPTHREAD 1" >>confdefs.h LIBS="-lpthread $LIBS" else $as_nop as_fn_error $? " *** Application requires pthread support *** " "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen/dlclose..." >&5 printf "%s\n" "$as_me: checking for dlopen/dlclose..." >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlclose in -ldl" >&5 printf %s "checking for dlclose in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlclose+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlclose (); int main (void) { return dlclose (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlclose=yes else $as_nop ac_cv_lib_dl_dlclose=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlclose" >&5 printf "%s\n" "$ac_cv_lib_dl_dlclose" >&6; } if test "x$ac_cv_lib_dl_dlclose" = xyes then : printf "%s\n" "#define HAVE_LIBDL 1" >>confdefs.h LIBS="-ldl $LIBS" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlclose in -lc" >&5 printf %s "checking for dlclose in -lc... " >&6; } if test ${ac_cv_lib_c_dlclose+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlclose (); int main (void) { return dlclose (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_c_dlclose=yes else $as_nop ac_cv_lib_c_dlclose=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_dlclose" >&5 printf "%s\n" "$ac_cv_lib_c_dlclose" >&6; } if test "x$ac_cv_lib_c_dlclose" = xyes then : printf "%s\n" "#define HAVE_LIBC 1" >>confdefs.h LIBS="-lc $LIBS" else $as_nop as_fn_error $? " *** Application requires dlopen/dlclose (e.g. libdl) *** " "$LINENO" 5 fi fi if test -d "/opt/local"; then CPPFLAGS="$CPPFLAGS -I/opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 printf %s "checking for library containing clock_gettime... " >&6; } if test ${ac_cv_search_clock_gettime+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char clock_gettime (); int main (void) { return clock_gettime (); ; return 0; } _ACEOF for ac_lib in '' rt do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO" then : ac_cv_search_clock_gettime=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_clock_gettime+y} then : break fi done if test ${ac_cv_search_clock_gettime+y} then : else $as_nop ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 printf "%s\n" "$ac_cv_search_clock_gettime" >&6; } ac_res=$ac_cv_search_clock_gettime if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi for ac_func in clock_gettime do : ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes then : printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: No clock_gettime(), using gettimeofday() instead " >&5 printf "%s\n" "$as_me: WARNING: No clock_gettime(), using gettimeofday() instead " >&2;} fi done check_libssl="false" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenSSL Library and Header files..." >&5 printf "%s\n" "$as_me: checking for OpenSSL Library and Header files..." >&6;} check_ssl_dir() { : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking $1/include/openssl/ssl.h" >&5 printf %s "checking $1/include/openssl/ssl.h... " >&6; } if test -f "$1/include/openssl/ssl.h" then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5 printf "%s\n" "found" >&6; } CPPFLAGS="$CPPFLAGS -I$1/include" LDFLAGS="$LDFLAGS -L$1/lib" return 0 else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5 printf "%s\n" "not found" >&6; } return 1 fi } # Check whether --with-ssl was given. if test ${with_ssl+y} then : withval=$with_ssl; check_ssl_dir "$withval" else $as_nop for main_dir in /usr /usr/local /usr/lib /usr/pkg /opt/local /usr/local/opt /opt; do for sub_dir in / /ssl /openssl; do check_ssl_dir "$main_dir$sub_dir" && break 2 done done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_lock in -lcrypto" >&5 printf %s "checking for CRYPTO_lock in -lcrypto... " >&6; } if test ${ac_cv_lib_crypto_CRYPTO_lock+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char CRYPTO_lock (); int main (void) { return CRYPTO_lock (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_crypto_CRYPTO_lock=yes else $as_nop ac_cv_lib_crypto_CRYPTO_lock=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_lock" >&5 printf "%s\n" "$ac_cv_lib_crypto_CRYPTO_lock" >&6; } if test "x$ac_cv_lib_crypto_CRYPTO_lock" = xyes then : printf "%s\n" "#define HAVE_LIBCRYPTO 1" >>confdefs.h LIBS="-lcrypto $LIBS" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** LibCrypto may be required for *BSD ***" >&5 printf "%s\n" "$as_me: WARNING: *** LibCrypto may be required for *BSD ***" >&2;} fi for ac_header in openssl/ssl.h openssl/crypto.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lssl" >&5 printf %s "checking for main in -lssl... " >&6; } if test ${ac_cv_lib_ssl_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_ssl_main=yes else $as_nop ac_cv_lib_ssl_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_main" >&5 printf "%s\n" "$ac_cv_lib_ssl_main" >&6; } if test "x$ac_cv_lib_ssl_main" = xyes then : printf "%s\n" "#define HAVE_LIBSSL 1" >>confdefs.h LIBS="$LIBS -lssl -lcrypto" check_libssl="true" else $as_nop as_fn_error $? " *** OpenSSL library required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. If the headers are installed in a non-standard location, specify the path with \"--with-ssl\". " "$LINENO" 5 fi else $as_nop as_fn_error $? " *** OpenSSL header files required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. If the headers are installed in a non-standard location, specify the path with \"--with-ssl\". " "$LINENO" 5 fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: *** Checking module dependencies and enabling accordingly ***" >&5 printf "%s\n" "$as_me: *** Checking module dependencies and enabling accordingly ***" >&6;} check_module_afp="false" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for AFPFS-NG Library and Header files..." >&5 printf "%s\n" "$as_me: checking for AFPFS-NG Library and Header files..." >&6;} ac_fn_c_check_header_compile "$LINENO" "afpfs-ng/afp_protocol.h" "ac_cv_header_afpfs_ng_afp_protocol_h" "$ac_includes_default" if test "x$ac_cv_header_afpfs_ng_afp_protocol_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lafpclient" >&5 printf %s "checking for main in -lafpclient... " >&6; } if test ${ac_cv_lib_afpclient_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lafpclient $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_afpclient_main=yes else $as_nop ac_cv_lib_afpclient_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_afpclient_main" >&5 printf "%s\n" "$ac_cv_lib_afpclient_main" >&6; } if test "x$ac_cv_lib_afpclient_main" = xyes then : printf "%s\n" "#define HAVE_LIBAFPFS 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lafpclient" check_module_afp="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** AFPFS-NG library required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** AFPFS-NG library required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** AFPFS-NG header files required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** AFPFS-NG header files required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. " >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable AFP module" >&5 printf %s "checking whether to enable AFP module... " >&6; } # Check whether --enable-module-afp was given. if test ${enable_module_afp+y} then : enableval=$enable_module_afp; case "${enableval}" in yes) enable_module_afp=true ;; no) enable_module_afp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-afp" "$LINENO" 5 ;; esac else $as_nop enable_module_afp=$check_module_afp fi if test x"$enable_module_afp" = "xtrue"; then BUILD_MODULE_AFP_TRUE= BUILD_MODULE_AFP_FALSE='#' else BUILD_MODULE_AFP_TRUE='#' BUILD_MODULE_AFP_FALSE= fi if test x"$enable_module_afp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable CVS module" >&5 printf %s "checking whether to enable CVS module... " >&6; } # Check whether --enable-module-cvs was given. if test ${enable_module_cvs+y} then : enableval=$enable_module_cvs; case "${enableval}" in yes) enable_module_cvs=true ;; no) enable_module_cvs=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-cvs" "$LINENO" 5 ;; esac else $as_nop enable_module_cvs="true" fi if test x"$enable_module_cvs" = "xtrue"; then BUILD_MODULE_CVS_TRUE= BUILD_MODULE_CVS_FALSE='#' else BUILD_MODULE_CVS_TRUE='#' BUILD_MODULE_CVS_FALSE= fi if test x"$enable_module_cvs" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable FTP module" >&5 printf %s "checking whether to enable FTP module... " >&6; } # Check whether --enable-module-ftp was given. if test ${enable_module_ftp+y} then : enableval=$enable_module_ftp; case "${enableval}" in yes) enable_module_ftp=true ;; no) enable_module_ftp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-ftp" "$LINENO" 5 ;; esac else $as_nop enable_module_ftp="true" fi if test x"$enable_module_ftp" = "xtrue"; then BUILD_MODULE_FTP_TRUE= BUILD_MODULE_FTP_FALSE='#' else BUILD_MODULE_FTP_TRUE='#' BUILD_MODULE_FTP_FALSE= fi if test x"$enable_module_ftp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_http=$check_libssl { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable HTTP module" >&5 printf %s "checking whether to enable HTTP module... " >&6; } # Check whether --enable-module-http was given. if test ${enable_module_http+y} then : enableval=$enable_module_http; case "${enableval}" in yes) enable_module_http=true ;; no) enable_module_http=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-http" "$LINENO" 5 ;; esac else $as_nop enable_module_http=$check_module_http fi if test x"$enable_module_http" = "xtrue"; then BUILD_MODULE_HTTP_TRUE= BUILD_MODULE_HTTP_FALSE='#' else BUILD_MODULE_HTTP_TRUE='#' BUILD_MODULE_HTTP_FALSE= fi if test x"$enable_module_http" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable IMAP module" >&5 printf %s "checking whether to enable IMAP module... " >&6; } # Check whether --enable-module-imap was given. if test ${enable_module_imap+y} then : enableval=$enable_module_imap; case "${enableval}" in yes) enable_module_imap=true ;; no) enable_module_imap=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-imap" "$LINENO" 5 ;; esac else $as_nop enable_module_imap="true" fi if test x"$enable_module_imap" = "xtrue"; then BUILD_MODULE_IMAP_TRUE= BUILD_MODULE_IMAP_FALSE='#' else BUILD_MODULE_IMAP_TRUE='#' BUILD_MODULE_IMAP_FALSE= fi if test x"$enable_module_imap" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_mssql=$check_libssl { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable MSSQL module" >&5 printf %s "checking whether to enable MSSQL module... " >&6; } # Check whether --enable-module-mssql was given. if test ${enable_module_mssql+y} then : enableval=$enable_module_mssql; case "${enableval}" in yes) enable_module_mssql=true ;; no) enable_module_mssql=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-mssql" "$LINENO" 5 ;; esac else $as_nop enable_module_mssql=$check_module_mssql fi if test x"$enable_module_mssql" = "xtrue"; then BUILD_MODULE_MSSQL_TRUE= BUILD_MODULE_MSSQL_FALSE='#' else BUILD_MODULE_MSSQL_TRUE='#' BUILD_MODULE_MSSQL_FALSE= fi if test x"$enable_module_mssql" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable MYSQL module" >&5 printf %s "checking whether to enable MYSQL module... " >&6; } # Check whether --enable-module-mysql was given. if test ${enable_module_mysql+y} then : enableval=$enable_module_mysql; case "${enableval}" in yes) enable_module_mysql=true ;; no) enable_module_mysql=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-mysql" "$LINENO" 5 ;; esac else $as_nop enable_module_mysql="true" fi if test x"$enable_module_mysql" = "xtrue"; then BUILD_MODULE_MYSQL_TRUE= BUILD_MODULE_MYSQL_FALSE='#' else BUILD_MODULE_MYSQL_TRUE='#' BUILD_MODULE_MYSQL_FALSE= fi if test x"$enable_module_mysql" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_ncp="false" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for NCPFS Library and Header files..." >&5 printf "%s\n" "$as_me: checking for NCPFS Library and Header files..." >&6;} ac_fn_c_check_header_compile "$LINENO" "ncp/nwcalls.h" "ac_cv_header_ncp_nwcalls_h" "$ac_includes_default" if test "x$ac_cv_header_ncp_nwcalls_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lncp" >&5 printf %s "checking for main in -lncp... " >&6; } if test ${ac_cv_lib_ncp_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lncp $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_ncp_main=yes else $as_nop ac_cv_lib_ncp_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncp_main" >&5 printf "%s\n" "$ac_cv_lib_ncp_main" >&6; } if test "x$ac_cv_lib_ncp_main" = xyes then : printf "%s\n" "#define HAVE_LIBNCP 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lncp" check_module_ncp="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** NCPFS library required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** NCPFS library required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** NCPFS header files required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** NCPFS header files required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using \"make install-dev\" within the NCPFS source. The NCP module will NOT be built. " >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable NCP module" >&5 printf %s "checking whether to enable NCP module... " >&6; } # Check whether --enable-module-ncp was given. if test ${enable_module_ncp+y} then : enableval=$enable_module_ncp; case "${enableval}" in yes) enable_module_ncp=true ;; no) enable_module_ncp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-ncp" "$LINENO" 5 ;; esac else $as_nop enable_module_ncp=$check_module_ncp fi if test x"$enable_module_ncp" = "xtrue"; then BUILD_MODULE_NCP_TRUE= BUILD_MODULE_NCP_FALSE='#' else BUILD_MODULE_NCP_TRUE='#' BUILD_MODULE_NCP_FALSE= fi if test x"$enable_module_ncp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable NNTP module" >&5 printf %s "checking whether to enable NNTP module... " >&6; } # Check whether --enable-module-nntp was given. if test ${enable_module_nntp+y} then : enableval=$enable_module_nntp; case "${enableval}" in yes) enable_module_nntp=true ;; no) enable_module_nntp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-nntp" "$LINENO" 5 ;; esac else $as_nop enable_module_nntp="true" fi if test x"$enable_module_nntp" = "xtrue"; then BUILD_MODULE_NNTP_TRUE= BUILD_MODULE_NNTP_FALSE='#' else BUILD_MODULE_NNTP_TRUE='#' BUILD_MODULE_NNTP_FALSE= fi if test x"$enable_module_nntp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable PCANYWHERE module" >&5 printf %s "checking whether to enable PCANYWHERE module... " >&6; } # Check whether --enable-module-pcanywhere was given. if test ${enable_module_pcanywhere+y} then : enableval=$enable_module_pcanywhere; case "${enableval}" in yes) enable_module_pcanywhere=true ;; no) enable_module_pcanywhere=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-pcanywhere" "$LINENO" 5 ;; esac else $as_nop enable_module_pcanywhere="true" fi if test x"$enable_module_pcanywhere" = "xtrue"; then BUILD_MODULE_PCANYWHERE_TRUE= BUILD_MODULE_PCANYWHERE_FALSE='#' else BUILD_MODULE_PCANYWHERE_TRUE='#' BUILD_MODULE_PCANYWHERE_FALSE= fi if test x"$enable_module_pcanywhere" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable POP3 module" >&5 printf %s "checking whether to enable POP3 module... " >&6; } # Check whether --enable-module-pop3 was given. if test ${enable_module_pop3+y} then : enableval=$enable_module_pop3; case "${enableval}" in yes) enable_module_pop3=true ;; no) enable_module_pop3=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-pop3" "$LINENO" 5 ;; esac else $as_nop enable_module_pop3="true" fi if test x"$enable_module_pop3" = "xtrue"; then BUILD_MODULE_POP3_TRUE= BUILD_MODULE_POP3_FALSE='#' else BUILD_MODULE_POP3_TRUE='#' BUILD_MODULE_POP3_FALSE= fi if test x"$enable_module_pop3" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_postgres="false" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PostgreSQL Library and Header files..." >&5 printf "%s\n" "$as_me: checking for PostgreSQL Library and Header files..." >&6;} ac_fn_c_check_header_compile "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default" if test "x$ac_cv_header_libpq_fe_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lpq" >&5 printf %s "checking for main in -lpq... " >&6; } if test ${ac_cv_lib_pq_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpq $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_pq_main=yes else $as_nop ac_cv_lib_pq_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_main" >&5 printf "%s\n" "$ac_cv_lib_pq_main" >&6; } if test "x$ac_cv_lib_pq_main" = xyes then : printf "%s\n" "#define HAVE_LIBPQ 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lpq" check_module_postgres="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** LIBPQ library required for PostgreSQL module. *** The PostgreSQL package must be installed for the PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&5 printf "%s\n" "$as_me: WARNING: *** LIBPQ library required for PostgreSQL module. *** The PostgreSQL package must be installed for the PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** LIBPQ header files required for PostgreSQL module. *** The PostgreSQL package must be installed for PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&5 printf "%s\n" "$as_me: WARNING: *** LIBPQ header files required for PostgreSQL module. *** The PostgreSQL package must be installed for PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. " >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable POSTGRES module" >&5 printf %s "checking whether to enable POSTGRES module... " >&6; } # Check whether --enable-module-postgres was given. if test ${enable_module_postgres+y} then : enableval=$enable_module_postgres; case "${enableval}" in yes) enable_module_postgres=true ;; no) enable_module_postgres=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-postgres" "$LINENO" 5 ;; esac else $as_nop enable_module_postgres=$check_module_postgres fi if test x"$enable_module_postgres" = "xtrue"; then BUILD_MODULE_POSTGRES_TRUE= BUILD_MODULE_POSTGRES_FALSE='#' else BUILD_MODULE_POSTGRES_TRUE='#' BUILD_MODULE_POSTGRES_FALSE= fi if test x"$enable_module_postgres" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_rdp="false" module_rdp_headers="false" # Check whether --with-freerdp was given. if test ${with_freerdp+y} then : withval=$with_freerdp; freerdp_prefix="$withval" else $as_nop freerdp_prefix="/usr" fi CPPFLAGS="$CPPFLAGS -I${freerdp_prefix}/include/freerdp2 -I${freerdp_prefix}/include/winpr2" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FreeRDP Library and Header files..." >&5 printf "%s\n" "$as_me: checking for FreeRDP Library and Header files..." >&6;} ac_fn_c_check_header_compile "$LINENO" "freerdp/freerdp.h" "ac_cv_header_freerdp_freerdp_h" "$ac_includes_default" if test "x$ac_cv_header_freerdp_freerdp_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lfreerdp2" >&5 printf %s "checking for main in -lfreerdp2... " >&6; } if test ${ac_cv_lib_freerdp2_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lfreerdp2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_freerdp2_main=yes else $as_nop ac_cv_lib_freerdp2_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_freerdp2_main" >&5 printf "%s\n" "$ac_cv_lib_freerdp2_main" >&6; } if test "x$ac_cv_lib_freerdp2_main" = xyes then : printf "%s\n" "#define HAVE_LIBFREERDP2 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lfreerdp2" check_module_rdp="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** FreeRDP2 library required for RDP module. *** The FreeRDP package must be installed for RDP module to function. This includes both the library and header files. Your distribution may offer packages such as freerdp2-dev/libfreerdp2, which will provide these files. " >&5 printf "%s\n" "$as_me: WARNING: *** FreeRDP2 library required for RDP module. *** The FreeRDP package must be installed for RDP module to function. This includes both the library and header files. Your distribution may offer packages such as freerdp2-dev/libfreerdp2, which will provide these files. " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** FreeRDP2 header files required for RDP module. *** The FreeRDP package must be installed for RDP module to function. This includes both the library and header files. Your distribution may offer packages such as freerdp2-dev/libwinpr2-dev, which will provide these files. " >&5 printf "%s\n" "$as_me: WARNING: *** FreeRDP2 header files required for RDP module. *** The FreeRDP package must be installed for RDP module to function. This includes both the library and header files. Your distribution may offer packages such as freerdp2-dev/libwinpr2-dev, which will provide these files. " >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable RDP module" >&5 printf %s "checking whether to enable RDP module... " >&6; } # Check whether --enable-module-rdp was given. if test ${enable_module_rdp+y} then : enableval=$enable_module_rdp; case "${enableval}" in yes) enable_module_rdp=true ;; no) enable_module_rdp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rdp" "$LINENO" 5 ;; esac else $as_nop enable_module_rdp=$check_module_rdp fi if test x"$enable_module_rdp" = "xtrue"; then BUILD_MODULE_RDP_TRUE= BUILD_MODULE_RDP_FALSE='#' else BUILD_MODULE_RDP_TRUE='#' BUILD_MODULE_RDP_FALSE= fi if test x"$enable_module_rdp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable REXEC module" >&5 printf %s "checking whether to enable REXEC module... " >&6; } # Check whether --enable-module-rexec was given. if test ${enable_module_rexec+y} then : enableval=$enable_module_rexec; case "${enableval}" in yes) enable_module_rexec=true ;; no) enable_module_rexec=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rexec" "$LINENO" 5 ;; esac else $as_nop enable_module_rexec="true" fi if test x"$enable_module_rexec" = "xtrue"; then BUILD_MODULE_REXEC_TRUE= BUILD_MODULE_REXEC_FALSE='#' else BUILD_MODULE_REXEC_TRUE='#' BUILD_MODULE_REXEC_FALSE= fi if test x"$enable_module_rexec" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable RLOGIN module" >&5 printf %s "checking whether to enable RLOGIN module... " >&6; } # Check whether --enable-module-rlogin was given. if test ${enable_module_rlogin+y} then : enableval=$enable_module_rlogin; case "${enableval}" in yes) enable_module_rlogin=true ;; no) enable_module_rlogin=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rlogin" "$LINENO" 5 ;; esac else $as_nop enable_module_rlogin="true" fi if test x"$enable_module_rlogin" = "xtrue"; then BUILD_MODULE_RLOGIN_TRUE= BUILD_MODULE_RLOGIN_FALSE='#' else BUILD_MODULE_RLOGIN_TRUE='#' BUILD_MODULE_RLOGIN_FALSE= fi if test x"$enable_module_rlogin" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable RSH module" >&5 printf %s "checking whether to enable RSH module... " >&6; } # Check whether --enable-module-rsh was given. if test ${enable_module_rsh+y} then : enableval=$enable_module_rsh; case "${enableval}" in yes) enable_module_rsh=true ;; no) enable_module_rsh=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-rsh" "$LINENO" 5 ;; esac else $as_nop enable_module_rsh="true" fi if test x"$enable_module_rsh" = "xtrue"; then BUILD_MODULE_RSH_TRUE= BUILD_MODULE_RSH_FALSE='#' else BUILD_MODULE_RSH_TRUE='#' BUILD_MODULE_RSH_FALSE= fi if test x"$enable_module_rsh" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_smbnt=$check_libssl { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SMBNT module" >&5 printf %s "checking whether to enable SMBNT module... " >&6; } # Check whether --enable-module-smbnt was given. if test ${enable_module_smbnt+y} then : enableval=$enable_module_smbnt; case "${enableval}" in yes) enable_module_smbnt=true ;; no) enable_module_smbnt=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smbnt" "$LINENO" 5 ;; esac else $as_nop enable_module_smbnt=$check_module_smbnt fi if test x"$enable_module_smbnt" = "xtrue"; then BUILD_MODULE_SMBNT_TRUE= BUILD_MODULE_SMBNT_FALSE='#' else BUILD_MODULE_SMBNT_TRUE='#' BUILD_MODULE_SMBNT_FALSE= fi if test x"$enable_module_smbnt" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_smbnt_smb2="false" # Check whether --with-libsmb2 was given. if test ${with_libsmb2+y} then : withval=$with_libsmb2; libsmb2_prefix="$withval" else $as_nop libsmb2_prefix="/usr" fi CPPFLAGS="$CPPFLAGS -I${libsmb2_prefix}/include/smb2" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsmb2 Library and Header files..." >&5 printf "%s\n" "$as_me: checking for libsmb2 Library and Header files..." >&6;} ac_fn_c_check_header_compile "$LINENO" "smb2/libsmb2.h" "ac_cv_header_smb2_libsmb2_h" "$ac_includes_default" if test "x$ac_cv_header_smb2_libsmb2_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lsmb2" >&5 printf %s "checking for main in -lsmb2... " >&6; } if test ${ac_cv_lib_smb2_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsmb2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_smb2_main=yes else $as_nop ac_cv_lib_smb2_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_smb2_main" >&5 printf "%s\n" "$ac_cv_lib_smb2_main" >&6; } if test "x$ac_cv_lib_smb2_main" = xyes then : printf "%s\n" "#define HAVE_LIBSMB2 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lsmb2" check_module_smbnt_smb2="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** libsmb2 library required for SMBNT module SMBv2 support. *** https://github.com/sahlberg/libsmb2 " >&5 printf "%s\n" "$as_me: WARNING: *** libsmb2 library required for SMBNT module SMBv2 support. *** https://github.com/sahlberg/libsmb2 " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** libsmb2 header files required for SMBNT module SMBv2 support. *** https://github.com/sahlberg/libsmb2 " >&5 printf "%s\n" "$as_me: WARNING: *** libsmb2 header files required for SMBNT module SMBv2 support. *** https://github.com/sahlberg/libsmb2 " >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SMBNT module SMBv2 support" >&5 printf %s "checking whether to enable SMBNT module SMBv2 support... " >&6; } # Check whether --enable-module-smbnt-smb2 was given. if test ${enable_module_smbnt_smb2+y} then : enableval=$enable_module_smbnt_smb2; case "${enableval}" in yes) enable_module_smbnt_smb2=true ;; no) enable_module_smbnt_smb2=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smbnt-smb2" "$LINENO" 5 ;; esac else $as_nop enable_module_smbnt_smb2=$check_module_smbnt_smb2 fi if test x"$enable_module_smbnt_smb2" = "xtrue"; then BUILD_MODULE_SMBNT_SMB2_TRUE= BUILD_MODULE_SMBNT_SMB2_FALSE='#' else BUILD_MODULE_SMBNT_SMB2_TRUE='#' BUILD_MODULE_SMBNT_SMB2_FALSE= fi if test x"$enable_module_smbnt_smb2" = "xtrue"; then printf "%s\n" "#define SMBNT_SMB2_SUPPORT_ENABLED 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SMTP module" >&5 printf %s "checking whether to enable SMTP module... " >&6; } # Check whether --enable-module-smtp was given. if test ${enable_module_smtp+y} then : enableval=$enable_module_smtp; case "${enableval}" in yes) enable_module_smtp=true ;; no) enable_module_smtp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smtp" "$LINENO" 5 ;; esac else $as_nop enable_module_smtp="true" fi if test x"$enable_module_smtp" = "xtrue"; then BUILD_MODULE_SMTP_TRUE= BUILD_MODULE_SMTP_FALSE='#' else BUILD_MODULE_SMTP_TRUE='#' BUILD_MODULE_SMTP_FALSE= fi if test x"$enable_module_smtp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SMTP-VRFY module" >&5 printf %s "checking whether to enable SMTP-VRFY module... " >&6; } # Check whether --enable-module-smtp-vrfy was given. if test ${enable_module_smtp_vrfy+y} then : enableval=$enable_module_smtp_vrfy; case "${enableval}" in yes) enable_module_smtp_vrfy=true ;; no) enable_module_smtp_vrfy=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-smtp-vrfy" "$LINENO" 5 ;; esac else $as_nop enable_module_smtp_vrfy="true" fi if test x"$enable_module_smtp_vrfy" = "xtrue"; then BUILD_MODULE_SMTP_VRFY_TRUE= BUILD_MODULE_SMTP_VRFY_FALSE='#' else BUILD_MODULE_SMTP_VRFY_TRUE='#' BUILD_MODULE_SMTP_VRFY_FALSE= fi if test x"$enable_module_smtp_vrfy" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SNMP module" >&5 printf %s "checking whether to enable SNMP module... " >&6; } # Check whether --enable-module-snmp was given. if test ${enable_module_snmp+y} then : enableval=$enable_module_snmp; case "${enableval}" in yes) enable_module_snmp=true ;; no) enable_module_snmp=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-snmp" "$LINENO" 5 ;; esac else $as_nop enable_module_snmp="true" fi if test x"$enable_module_snmp" = "xtrue"; then BUILD_MODULE_SNMP_TRUE= BUILD_MODULE_SNMP_FALSE='#' else BUILD_MODULE_SNMP_TRUE='#' BUILD_MODULE_SNMP_FALSE= fi if test x"$enable_module_snmp" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_ssh="false" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Libssh2 Library files..." >&5 printf "%s\n" "$as_me: checking for Libssh2 Library files..." >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lssh2" >&5 printf %s "checking for main in -lssh2... " >&6; } if test ${ac_cv_lib_ssh2_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lssh2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_ssh2_main=yes else $as_nop ac_cv_lib_ssh2_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssh2_main" >&5 printf "%s\n" "$ac_cv_lib_ssh2_main" >&6; } if test "x$ac_cv_lib_ssh2_main" = xyes then : printf "%s\n" "#define HAVE_LIBSSH2 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lssh2" check_module_ssh="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** Libssh2 required for SSH2 module. *** Libssh2 (http://www.libssh2.org) is not the same as libssh (http://0xbadc0de.be). Make sure you have the correct library. The SSH2 module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** Libssh2 required for SSH2 module. *** Libssh2 (http://www.libssh2.org) is not the same as libssh (http://0xbadc0de.be). Make sure you have the correct library. The SSH2 module will NOT be built. " >&2;} fi if test x"$check_module_ssh" = "xtrue"; then check_libgcrypt="false" for _dir in `ld --verbose | grep SEARCH_DIR | sed -e 's/\"); */\n/g' | cut -d= -f2` do if test -f "$_dir/libssh2.so"; then LIBSSH2_PATH="$_dir/libssh2.so" fi done for _dir in "/usr/lib" "/usr/local/lib" do if test -f "$_dir/libssh2.dylib"; then LIBSSH2_PATH="$_dir/libssh2.dylib" fi done if test -z "$LIBSSH2_PATH"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: LIBSSH2 path not found. Assuming it was... " >&5 printf "%s\n" "$as_me: WARNING: LIBSSH2 path not found. Assuming it was... " >&2;} check_libgcrypt="true" fi if test -f "`which ldd`"; then LDD="ldd" elif test -f "`which otool`"; then LDD="otool -L" else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: No ldd detected. Unable to test whether Libssh2 was compiled to use libgcrypt. Assuming it was... " >&5 printf "%s\n" "$as_me: WARNING: No ldd detected. Unable to test whether Libssh2 was compiled to use libgcrypt. Assuming it was... " >&2;} check_libgcrypt="true" fi if test ! -z "`$LDD $LIBSSH2_PATH |grep libgcrypt`"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libssh2 compiled using libgcrypt. Checking additional dependencies. " >&5 printf "%s\n" "$as_me: WARNING: Libssh2 compiled using libgcrypt. Checking additional dependencies. " >&2;} check_libgcrypt="true" fi if test x"$check_libgcrypt" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Libgrcypt Library files..." >&5 printf "%s\n" "$as_me: checking for Libgrcypt Library files..." >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcry_control in -lgcrypt" >&5 printf %s "checking for gcry_control in -lgcrypt... " >&6; } if test ${ac_cv_lib_gcrypt_gcry_control+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lgcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char gcry_control (); int main (void) { return gcry_control (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_gcrypt_gcry_control=yes else $as_nop ac_cv_lib_gcrypt_gcry_control=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gcrypt_gcry_control" >&5 printf "%s\n" "$ac_cv_lib_gcrypt_gcry_control" >&6; } if test "x$ac_cv_lib_gcrypt_gcry_control" = xyes then : printf "%s\n" "#define HAVE_LIBGCRYPT 1" >>confdefs.h LIBS="$LIBS -lgcrypt" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** Libgcrypt required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgcrypt11-dev). The SSH2 module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** Libgcrypt required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgcrypt11-dev). The SSH2 module will NOT be built. " >&2;} check_module_ssh="false" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GnuTLS Library files..." >&5 printf "%s\n" "$as_me: checking for GnuTLS Library files..." >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gnutls_handshake in -lgnutls" >&5 printf %s "checking for gnutls_handshake in -lgnutls... " >&6; } if test ${ac_cv_lib_gnutls_gnutls_handshake+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lgnutls $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char gnutls_handshake (); int main (void) { return gnutls_handshake (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_gnutls_gnutls_handshake=yes else $as_nop ac_cv_lib_gnutls_gnutls_handshake=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gnutls_gnutls_handshake" >&5 printf "%s\n" "$ac_cv_lib_gnutls_gnutls_handshake" >&6; } if test "x$ac_cv_lib_gnutls_gnutls_handshake" = xyes then : printf "%s\n" "#define HAVE_GNUTLS 1" >>confdefs.h LIBS="$LIBS -lgnutls" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** GnuTLS required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgnutls-dev). The SSH2 module will NOT be built. " >&5 printf "%s\n" "$as_me: WARNING: *** GnuTLS required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgnutls-dev). The SSH2 module will NOT be built. " >&2;} check_module_ssh="false" fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SSH module" >&5 printf %s "checking whether to enable SSH module... " >&6; } # Check whether --enable-module-ssh was given. if test ${enable_module_ssh+y} then : enableval=$enable_module_ssh; case "${enableval}" in yes) enable_module_ssh=true ;; no) enable_module_ssh=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-ssh" "$LINENO" 5 ;; esac else $as_nop enable_module_ssh=$check_module_ssh fi if test x"$enable_module_ssh" = "xtrue"; then BUILD_MODULE_SSH_TRUE= BUILD_MODULE_SSH_FALSE='#' else BUILD_MODULE_SSH_TRUE='#' BUILD_MODULE_SSH_FALSE= fi if test x"$enable_module_ssh" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_svn="false" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Subversion Library and Header files..." >&5 printf "%s\n" "$as_me: checking for Subversion Library and Header files..." >&6;} # Extract the first word of "apr-1-config", so it can be a program name with args. set dummy apr-1-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_APR_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $APR_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_APR_CONFIG="$APR_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_APR_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi APR_CONFIG=$ac_cv_path_APR_CONFIG if test -n "$APR_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $APR_CONFIG" >&5 printf "%s\n" "$APR_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$APR_CONFIG"; then # Extract the first word of "apr-config", so it can be a program name with args. set dummy apr-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_APR_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $APR_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_APR_CONFIG="$APR_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_APR_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi APR_CONFIG=$ac_cv_path_APR_CONFIG if test -n "$APR_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $APR_CONFIG" >&5 printf "%s\n" "$APR_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$APR_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** apr-config/apr-1-config not found and required for SVN module *** Make sure to install libapr1-dev or whatever package your distribution uses to distribute this file. " >&5 printf "%s\n" "$as_me: WARNING: *** apr-config/apr-1-config not found and required for SVN module *** Make sure to install libapr1-dev or whatever package your distribution uses to distribute this file. " >&2;} fi fi if test -n "$APR_CONFIG"; then if test x`$APR_CONFIG --cc` = "xcc"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** Apache (apr) was compiled using Sun C compiler and not GNU gcc. *** \"$APR_CONFIG --cc\" responded with \"cc\", which usually means that your build of Apache was compiled with Sun C compiler and not with gcc. This means that the version of libtool embedded within Apache installation is also configured for Sun C compiler and not gcc. The Sun C compiler setup is incompatible because the options to each compiler are different for building shared objects and libraries. Specifically, the Sun compiler supports the \"-mt\" flag, whereas gcc does not. In order to build the SVN Medusa module, rebuild $APR_CONFIG using gcc, or remove the \"-mt\" CPPFLAGS flag from the autogenerated Medusa configuration files. " >&5 printf "%s\n" "$as_me: WARNING: *** Apache (apr) was compiled using Sun C compiler and not GNU gcc. *** \"$APR_CONFIG --cc\" responded with \"cc\", which usually means that your build of Apache was compiled with Sun C compiler and not with gcc. This means that the version of libtool embedded within Apache installation is also configured for Sun C compiler and not gcc. The Sun C compiler setup is incompatible because the options to each compiler are different for building shared objects and libraries. Specifically, the Sun compiler supports the \"-mt\" flag, whereas gcc does not. In order to build the SVN Medusa module, rebuild $APR_CONFIG using gcc, or remove the \"-mt\" CPPFLAGS flag from the autogenerated Medusa configuration files. " >&2;} else APR_INCLUDE_DIR=`$APR_CONFIG --includedir` CPPFLAGS="$CPPFLAGS `$APR_CONFIG --includes --cppflags`" as_ac_Header=`printf "%s\n" "ac_cv_header_$APR_INCLUDE_DIR/apr_tables.h" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$APR_INCLUDE_DIR/apr_tables.h" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : ac_fn_c_check_header_compile "$LINENO" "subversion-1/svn_client.h" "ac_cv_header_subversion_1_svn_client_h" "$ac_includes_default" if test "x$ac_cv_header_subversion_1_svn_client_h" = xyes then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lsvn_client-1" >&5 printf %s "checking for main in -lsvn_client-1... " >&6; } if test ${ac_cv_lib_svn_client_1_main+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvn_client-1 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svn_client_1_main=yes else $as_nop ac_cv_lib_svn_client_1_main=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svn_client_1_main" >&5 printf "%s\n" "$ac_cv_lib_svn_client_1_main" >&6; } if test "x$ac_cv_lib_svn_client_1_main" = xyes then : printf "%s\n" "#define HAVE_LIBSVN_CLIENT_1 1" >>confdefs.h MODULE_LIBS="$MODULE_LIBS -lsvn_client-1" check_module_svn="true" else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** Subversion libsvn library required for SVN module. *** " >&5 printf "%s\n" "$as_me: WARNING: *** Subversion libsvn library required for SVN module. *** " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** Subversion header files required for SVN module. (e.g., libsvn-dev) *** " >&5 printf "%s\n" "$as_me: WARNING: *** Subversion header files required for SVN module. (e.g., libsvn-dev) *** " >&2;} fi else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** APR header files required for SVN module. (e.g., libapr1-dev) *** " >&5 printf "%s\n" "$as_me: WARNING: *** APR header files required for SVN module. (e.g., libapr1-dev) *** " >&2;} fi fi else check_module_svn="false" fi if test x"$check_module_svn" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for svn_client_list4 in -lsvn_client-1" >&5 printf %s "checking for svn_client_list4 in -lsvn_client-1... " >&6; } if test ${ac_cv_lib_svn_client_1_svn_client_list4+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvn_client-1 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char svn_client_list4 (); int main (void) { return svn_client_list4 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svn_client_1_svn_client_list4=yes else $as_nop ac_cv_lib_svn_client_1_svn_client_list4=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svn_client_1_svn_client_list4" >&5 printf "%s\n" "$ac_cv_lib_svn_client_1_svn_client_list4" >&6; } if test "x$ac_cv_lib_svn_client_1_svn_client_list4" = xyes then : printf "%s\n" "#define HAVE_SVN_CLIENT_LIST4 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Found SVN Library older than version 1.10" >&5 printf "%s\n" "$as_me: WARNING: Found SVN Library older than version 1.10" >&2;} fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for svn_client_list3 in -lsvn_client-1" >&5 printf %s "checking for svn_client_list3 in -lsvn_client-1... " >&6; } if test ${ac_cv_lib_svn_client_1_svn_client_list3+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvn_client-1 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char svn_client_list3 (); int main (void) { return svn_client_list3 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svn_client_1_svn_client_list3=yes else $as_nop ac_cv_lib_svn_client_1_svn_client_list3=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svn_client_1_svn_client_list3" >&5 printf "%s\n" "$ac_cv_lib_svn_client_1_svn_client_list3" >&6; } if test "x$ac_cv_lib_svn_client_1_svn_client_list3" = xyes then : printf "%s\n" "#define HAVE_SVN_CLIENT_LIST3 1" >>confdefs.h else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Found SVN Library older than version 1.8" >&5 printf "%s\n" "$as_me: WARNING: Found SVN Library older than version 1.8" >&2;} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable SVN module" >&5 printf %s "checking whether to enable SVN module... " >&6; } # Check whether --enable-module-svn was given. if test ${enable_module_svn+y} then : enableval=$enable_module_svn; case "${enableval}" in yes) enable_module_svn=true ;; no) enable_module_svn=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-svn" "$LINENO" 5 ;; esac else $as_nop enable_module_svn=$check_module_svn fi if test x"$enable_module_svn" = "xtrue"; then BUILD_MODULE_SVN_TRUE= BUILD_MODULE_SVN_FALSE='#' else BUILD_MODULE_SVN_TRUE='#' BUILD_MODULE_SVN_FALSE= fi if test x"$enable_module_svn" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable TELNET module" >&5 printf %s "checking whether to enable TELNET module... " >&6; } # Check whether --enable-module-telnet was given. if test ${enable_module_telnet+y} then : enableval=$enable_module_telnet; case "${enableval}" in yes) enable_module_telnet=true ;; no) enable_module_telnet=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-telnet" "$LINENO" 5 ;; esac else $as_nop enable_module_telnet="true" fi if test x"$enable_module_telnet" = "xtrue"; then BUILD_MODULE_TELNET_TRUE= BUILD_MODULE_TELNET_FALSE='#' else BUILD_MODULE_TELNET_TRUE='#' BUILD_MODULE_TELNET_FALSE= fi if test x"$enable_module_telnet" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable VMAUTHD module" >&5 printf %s "checking whether to enable VMAUTHD module... " >&6; } # Check whether --enable-module-vmauthd was given. if test ${enable_module_vmauthd+y} then : enableval=$enable_module_vmauthd; case "${enableval}" in yes) enable_module_vmauthd=true ;; no) enable_module_vmauthd=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-vmauthd" "$LINENO" 5 ;; esac else $as_nop enable_module_vmauthd="true" fi if test x"$enable_module_vmauthd" = "xtrue"; then BUILD_MODULE_VMAUTHD_TRUE= BUILD_MODULE_VMAUTHD_FALSE='#' else BUILD_MODULE_VMAUTHD_TRUE='#' BUILD_MODULE_VMAUTHD_FALSE= fi if test x"$enable_module_vmauthd" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_vnc=$check_libssl { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable VNC module" >&5 printf %s "checking whether to enable VNC module... " >&6; } # Check whether --enable-module-vnc was given. if test ${enable_module_vnc+y} then : enableval=$enable_module_vnc; case "${enableval}" in yes) enable_module_vnc=true ;; no) enable_module_vnc=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-vnc" "$LINENO" 5 ;; esac else $as_nop enable_module_vnc=$check_module_vnc fi if test x"$enable_module_vnc" = "xtrue"; then BUILD_MODULE_VNC_TRUE= BUILD_MODULE_VNC_FALSE='#' else BUILD_MODULE_VNC_TRUE='#' BUILD_MODULE_VNC_FALSE= fi if test x"$enable_module_vnc" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable WRAPPER module" >&5 printf %s "checking whether to enable WRAPPER module... " >&6; } # Check whether --enable-module-wrapper was given. if test ${enable_module_wrapper+y} then : enableval=$enable_module_wrapper; case "${enableval}" in yes) enable_module_wrapper=true ;; no) enable_module_wrapper=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-wrapper" "$LINENO" 5 ;; esac else $as_nop enable_module_wrapper="true" fi if test x"$enable_module_wrapper" = "xtrue"; then BUILD_MODULE_WRAPPER_TRUE= BUILD_MODULE_WRAPPER_FALSE='#' else BUILD_MODULE_WRAPPER_TRUE='#' BUILD_MODULE_WRAPPER_FALSE= fi if test x"$enable_module_wrapper" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi check_module_web_form=$check_libssl { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable WEB-FORM module" >&5 printf %s "checking whether to enable WEB-FORM module... " >&6; } # Check whether --enable-module-web-form was given. if test ${enable_module_web_form+y} then : enableval=$enable_module_web_form; case "${enableval}" in yes) enable_module_web_form=true ;; no) enable_module_web_form=false ;; *) as_fn_error $? "bad value ${enableval} for --enable-module-web-form" "$LINENO" 5 ;; esac else $as_nop enable_module_web_form=$check_module_web_form fi if test x"$enable_module_web_form" = "xtrue"; then BUILD_MODULE_WEB_FORM_TRUE= BUILD_MODULE_WEB_FORM_FALSE='#' else BUILD_MODULE_WEB_FORM_TRUE='#' BUILD_MODULE_WEB_FORM_FALSE= fi if test x"$enable_module_web_form" = "xtrue"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5 printf "%s\n" "$as_me: " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: *******************************************************" >&5 printf "%s\n" "$as_me: *******************************************************" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Medusa Module Build Summary" >&5 printf "%s\n" "$as_me: Medusa Module Build Summary" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5 printf "%s\n" "$as_me: " >&6;} show_build_status() { if test "$1" = "true" ; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $2 Enabled" >&5 printf "%s\n" "$as_me: $2 Enabled" >&6;} else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $2 ** Disabled **" >&5 printf "%s\n" "$as_me: $2 ** Disabled **" >&6;} fi } show_build_status "${enable_module_afp}" " AFP " show_build_status "${enable_module_cvs}" " CVS " show_build_status "${enable_module_ftp}" " FTP " show_build_status "${enable_module_http}" " HTTP " show_build_status "${enable_module_imap}" " IMAP " show_build_status "${enable_module_mssql}" " MSSQL " show_build_status "${enable_module_mysql}" " MYSQL " show_build_status "${enable_module_ncp}" " NCP " show_build_status "${enable_module_nntp}" " NNTP " show_build_status "${enable_module_pcanywhere}" " PCANYWHERE " show_build_status "${enable_module_pop3}" " POP3 " show_build_status "${enable_module_postgres}" " POSTGRES " show_build_status "${enable_module_rdp}" " RDP " show_build_status "${enable_module_rexec}" " REXEC " show_build_status "${enable_module_rlogin}" " RLOGIN " show_build_status "${enable_module_rsh}" " RSH " show_build_status "${enable_module_smbnt}" " SMBNT " show_build_status "${enable_module_smbnt_smb2}" " SMBNT (SMBv2) " show_build_status "${enable_module_smtp}" " SMTP " show_build_status "${enable_module_smtp_vrfy}" " SMTP-VRFY " show_build_status "${enable_module_snmp}" " SNMP " show_build_status "${enable_module_ssh}" " SSH " show_build_status "${enable_module_svn}" " SVN " show_build_status "${enable_module_telnet}" " TELNET " show_build_status "${enable_module_vmauthd}" " VMAUTHD " show_build_status "${enable_module_vnc}" " VNC " show_build_status "${enable_module_wrapper}" " WRAPPER " show_build_status "${enable_module_web_form}" " WEB-FORM " { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5 printf "%s\n" "$as_me: " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: If a module is unexpectedly marked as disabled, check " >&5 printf "%s\n" "$as_me: If a module is unexpectedly marked as disabled, check " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: above output and verify dependancies were satisfied. " >&5 printf "%s\n" "$as_me: above output and verify dependancies were satisfied. " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5 printf "%s\n" "$as_me: " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: It should also be noted that, by default, not all of " >&5 printf "%s\n" "$as_me: It should also be noted that, by default, not all of " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: the modules are built. Incomplete modules or modules " >&5 printf "%s\n" "$as_me: the modules are built. Incomplete modules or modules " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: which have not been sufficiently tested may be " >&5 printf "%s\n" "$as_me: which have not been sufficiently tested may be " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: disabled. To enable non-default modules, use the " >&5 printf "%s\n" "$as_me: disabled. To enable non-default modules, use the " >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \"--enable-module-MODULE_NAME\" configure option." >&5 printf "%s\n" "$as_me: \"--enable-module-MODULE_NAME\" configure option." >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: *******************************************************" >&5 printf "%s\n" "$as_me: *******************************************************" >&6;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: " >&5 printf "%s\n" "$as_me: " >&6;} # strcasestr() is a nonstandard extension and requires _GNU_SOURCE (https://linux.die.net/man/3/strcasestr) CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" if test "x$ac_cv_func_strcasestr" = xyes then : printf "%s\n" "#define HAVE_STRCASESTR 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf" if test "x$ac_cv_func_asprintf" = xyes then : printf "%s\n" "#define HAVE_ASPRINTF 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf" if test "x$ac_cv_func_vasprintf" = xyes then : printf "%s\n" "#define HAVE_VASPRINTF 1" >>confdefs.h fi case "$target" in *linux*) LIBDL="-ldl -lrt -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *freebsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *netbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *openbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="-g -Wl,-E" ;; *apple-darwin*) # Modules will segfault when executed (show usage works) if medusa core # is not linked to CoreFoundation (starting with 10.6). This is believed to # be due to libsvn linking to CoreFoundation and our modules linked via # "-lsvn_client-1". See http://www.openradar.me/7209349 for more info. LIBDL="-ldl -framework CoreFoundation" # OS X Lion marked OpenSSL as deprecated. We're disabling these warnings # for now. We'll need to figure out if it's worth supporting Common Crypto # or simply requiring users to install their own OpenSSL in the future. CFLAGS="$CFLAGS -Wno-deprecated-declarations" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -bundle -flat_namespace -undefined suppress" EXTRA_LDFLAGS="" ;; *solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" LDFLAGS="$LDFLAGS -R/usr/local/lib -R/usr/local/ssl/lib -L/usr/local/ssl/lib" LIBDL="-ldl -lm -lrt -lnsl -lsocket" RDYNAMIC="-Rdynamic" EXTRA_LDFLAGS="" MODULE_LIBS="$MODULE_LIBS -G" ;; *cygwin*) CPPFLAGS="$CPPFLAGS -DCYGWIN" LIBDL="-ldl" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -shared" ;; *) LIBDL="-ldl -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; esac LDFLAGS="$LDFLAGS $RDYNAMIC $EXTRA_LDFLAGS" LIBS="$LIBS $LIBDL" test "$prefix" = NONE && prefix=${ac_default_prefix} _default_mod_path="${prefix}/lib/medusa/modules" # Check whether --with-default-mod-path was given. if test ${with_default_mod_path+y} then : withval=$with_default_mod_path; _default_mod_path="$withval" fi printf "%s\n" "#define DEFAULT_MOD_PATH \"$_default_mod_path\"" >>confdefs.h ac_config_files="$ac_config_files Makefile src/Makefile src/modsrc/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${BUILD_MODULE_AFP_TRUE}" && test -z "${BUILD_MODULE_AFP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_AFP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_CVS_TRUE}" && test -z "${BUILD_MODULE_CVS_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_CVS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_FTP_TRUE}" && test -z "${BUILD_MODULE_FTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_FTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_HTTP_TRUE}" && test -z "${BUILD_MODULE_HTTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_HTTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_IMAP_TRUE}" && test -z "${BUILD_MODULE_IMAP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_IMAP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_MSSQL_TRUE}" && test -z "${BUILD_MODULE_MSSQL_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_MSSQL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_MYSQL_TRUE}" && test -z "${BUILD_MODULE_MYSQL_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_MYSQL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_NCP_TRUE}" && test -z "${BUILD_MODULE_NCP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_NCP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_NNTP_TRUE}" && test -z "${BUILD_MODULE_NNTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_NNTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_PCANYWHERE_TRUE}" && test -z "${BUILD_MODULE_PCANYWHERE_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_PCANYWHERE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_POP3_TRUE}" && test -z "${BUILD_MODULE_POP3_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_POP3\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_POSTGRES_TRUE}" && test -z "${BUILD_MODULE_POSTGRES_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_POSTGRES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_RDP_TRUE}" && test -z "${BUILD_MODULE_RDP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_RDP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_REXEC_TRUE}" && test -z "${BUILD_MODULE_REXEC_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_REXEC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_RLOGIN_TRUE}" && test -z "${BUILD_MODULE_RLOGIN_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_RLOGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_RSH_TRUE}" && test -z "${BUILD_MODULE_RSH_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_RSH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMBNT_TRUE}" && test -z "${BUILD_MODULE_SMBNT_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMBNT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMBNT_SMB2_TRUE}" && test -z "${BUILD_MODULE_SMBNT_SMB2_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMBNT_SMB2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMTP_TRUE}" && test -z "${BUILD_MODULE_SMTP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMTP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SMTP_VRFY_TRUE}" && test -z "${BUILD_MODULE_SMTP_VRFY_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SMTP_VRFY\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SNMP_TRUE}" && test -z "${BUILD_MODULE_SNMP_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SNMP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SSH_TRUE}" && test -z "${BUILD_MODULE_SSH_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SSH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_SVN_TRUE}" && test -z "${BUILD_MODULE_SVN_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_SVN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_TELNET_TRUE}" && test -z "${BUILD_MODULE_TELNET_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_TELNET\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_VMAUTHD_TRUE}" && test -z "${BUILD_MODULE_VMAUTHD_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_VMAUTHD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_VNC_TRUE}" && test -z "${BUILD_MODULE_VNC_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_VNC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_WRAPPER_TRUE}" && test -z "${BUILD_MODULE_WRAPPER_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_WRAPPER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MODULE_WEB_FORM_TRUE}" && test -z "${BUILD_MODULE_WEB_FORM_FALSE}"; then as_fn_error $? "conditional \"BUILD_MODULE_WEB_FORM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by medusa $as_me 2.3_rc1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to the package provider." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ medusa config.status 2.3_rc1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/modsrc/Makefile") CONFIG_FILES="$CONFIG_FILES src/modsrc/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi jmk-foofus-medusa-dd62069/configure.ac000066400000000000000000001157771460263104500177170ustar00rootroot00000000000000AC_INIT([medusa],[2.3_rc1]) AC_CONFIG_SRCDIR([src/medusa.c]) AC_CONFIG_HEADERS(config.h) dnl Detect the canonical host and target build environment AC_CANONICAL_HOST AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([subdir-objects no-dependencies]) AC_LANG([C]) AC_PROG_CC AC_CHECK_SIZEOF(int,cross) AC_CHECK_SIZEOF(long,cross) AC_CHECK_SIZEOF(long long,cross) AC_CHECK_SIZEOF(short,cross) CFLAGS="${CFLAGS=}" AC_MSG_CHECKING(whether to enable debugging) debug_default="yes" AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging (default=yes)],, enable_debug=$debug_default) if test "x$enable_debug" = "xyes"; then CPPFLAGS="$CPPFLAGS -g -DDEBUG" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_ARG_WITH(postgresql, AS_HELP_STRING([--with-postgresql=prefix],[Prefix for postgresql include directory (default = /usr)]), [postgresql_prefix="$withval"], [postgresql_prefix="/usr"]) AC_ARG_WITH(afpfsng, AS_HELP_STRING([--with-afpfsng=prefix],[Prefix for afpfs-ng include directory (default = /usr)]), [afpfsng_prefix="$withval"], [afpfsng_prefix="/usr"]) dnl FreeBSD was not looking in /usr/local... dnl AC_SEARCH_LIBS ? if test -d "/usr/local/lib" then LDFLAGS="$LDFLAGS -L/usr/local/lib" fi CPPFLAGS="$CPPFLAGS -fPIC" CPPFLAGS="$CPPFLAGS -I/usr/include -I/usr/local/include -I${postgresql_prefix}/include/postgresql -I${postgresql_prefix}/include/pgsql -I${afpfsng_prefix}/include/afpfs-ng" AS_MESSAGE([checking for pthread support...]) AC_CHECK_LIB(pthread, main, [], [AC_MSG_ERROR([ *** Application requires pthread support *** ])]) AS_MESSAGE([checking for dlopen/dlclose...]) AC_CHECK_LIB(dl, dlclose, [], [AC_CHECK_LIB(c, dlclose, [], [AC_MSG_ERROR([ *** Application requires dlopen/dlclose (e.g. libdl) *** ])]) ] ) dnl MacPorts if test -d "/opt/local"; then CPPFLAGS="$CPPFLAGS -I/opt/local/include" LDFLAGS="$LDFLAGS -L/opt/local/lib" fi dnl Mac OS X doesn't have clock_gettime() AC_SEARCH_LIBS(clock_gettime, [rt]) AC_CHECK_FUNCS(clock_gettime, [], [AC_MSG_WARN([ No clock_gettime(), using gettimeofday() instead ])]) dnl ********** OpenSSL Checks ********** check_libssl="false" AS_MESSAGE([checking for OpenSSL Library and Header files...]) check_ssl_dir() { : AC_MSG_CHECKING([$1/include/openssl/ssl.h]) if test -f "$1/include/openssl/ssl.h" then AC_MSG_RESULT([found]) CPPFLAGS="$CPPFLAGS -I$1/include" LDFLAGS="$LDFLAGS -L$1/lib" return 0 else AC_MSG_RESULT([not found]) return 1 fi } AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=prefix],[Prefix for OpenSSL libraries]), [check_ssl_dir "$withval"], [ for main_dir in /usr /usr/local /usr/lib /usr/pkg /opt/local /usr/local/opt /opt; do for sub_dir in / /ssl /openssl; do check_ssl_dir "$main_dir$sub_dir" && break 2 done done ] ) AC_CHECK_LIB(crypto, CRYPTO_lock, [], [AC_MSG_WARN([ *** LibCrypto may be required for *BSD ***])]) AC_CHECK_HEADERS(openssl/ssl.h openssl/crypto.h, [AC_CHECK_LIB(ssl, main, [AC_DEFINE(HAVE_LIBSSL, 1, [Found OpenSSL Library]) LIBS="$LIBS -lssl -lcrypto" check_libssl="true"], [AC_MSG_ERROR([ *** OpenSSL library required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. If the headers are installed in a non-standard location, specify the path with "--with-ssl". ])] )], [AC_MSG_ERROR([ *** OpenSSL header files required for SSL support. *** Many of the Medusa modules depend on the OpenSSL library and header files. If multiple modules are unexpectedly disabled, this is likely the cause. Make sure to install libssl-dev, openssl-devel or whatever package your distribution uses to distribute these files. If the headers are installed in a non-standard location, specify the path with "--with-ssl". ])] ) AC_MSG_NOTICE([*** Checking module dependencies and enabling accordingly ***]) dnl ********** AFP Medusa Module Option Checks ********** check_module_afp="false" AS_MESSAGE([checking for AFPFS-NG Library and Header files...]) AC_CHECK_HEADER([afpfs-ng/afp_protocol.h], [AC_CHECK_LIB(afpclient, main, [AC_DEFINE(HAVE_LIBAFPFS, 1, [Found AFPFS-NG Library]) MODULE_LIBS="$MODULE_LIBS -lafpclient" check_module_afp="true"], [AC_MSG_WARN([ *** AFPFS-NG library required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. ])] )], [AC_MSG_WARN([ *** AFPFS-NG header files required for AFP module. *** The AFPFS-NG package must be installed for the AFP module to function. This includes both the library and header files. AFPFS-NG is available at the following site: http://alexthepuffin.googlepages.com/. The AFP module will NOT be built. ])] ) AC_MSG_CHECKING(whether to enable AFP module) AC_ARG_ENABLE(module-afp, [ --enable-module-afp=[no/yes] Enable AFP module (default=no)], [case "${enableval}" in yes) enable_module_afp=true ;; no) enable_module_afp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-afp]) ;; esac], [enable_module_afp=$check_module_afp]) AM_CONDITIONAL(BUILD_MODULE_AFP, test x"$enable_module_afp" = "xtrue") if test x"$enable_module_afp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** CVS Medusa Module Option Checks ********** AC_MSG_CHECKING(whether to enable CVS module) AC_ARG_ENABLE(module-cvs, [ --enable-module-cvs=[no/yes] Enable CVS module (default=yes)], [case "${enableval}" in yes) enable_module_cvs=true ;; no) enable_module_cvs=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-cvs]) ;; esac], [enable_module_cvs="true"]) AM_CONDITIONAL(BUILD_MODULE_CVS, test x"$enable_module_cvs" = "xtrue") if test x"$enable_module_cvs" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** FTP Medusa Module ********** AC_MSG_CHECKING(whether to enable FTP module) AC_ARG_ENABLE(module-ftp, [ --enable-module-ftp=[no/yes] Enable FTP module (default=yes)], [case "${enableval}" in yes) enable_module_ftp=true ;; no) enable_module_ftp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-ftp]) ;; esac], [enable_module_ftp="true"]) AM_CONDITIONAL(BUILD_MODULE_FTP, test x"$enable_module_ftp" = "xtrue") if test x"$enable_module_ftp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** HTTP Medusa Module ********** check_module_http=$check_libssl AC_MSG_CHECKING(whether to enable HTTP module) AC_ARG_ENABLE(module-http, [ --enable-module-http=[no/yes] Enable HTTP module (default=yes)], [case "${enableval}" in yes) enable_module_http=true ;; no) enable_module_http=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-http]) ;; esac], [enable_module_http=$check_module_http]) AM_CONDITIONAL(BUILD_MODULE_HTTP, test x"$enable_module_http" = "xtrue") if test x"$enable_module_http" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** IMAP Medusa Module ********** AC_MSG_CHECKING(whether to enable IMAP module) AC_ARG_ENABLE(module-imap, [ --enable-module-imap=[no/yes] Enable IMAP module (default=yes)], [case "${enableval}" in yes) enable_module_imap=true ;; no) enable_module_imap=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-imap]) ;; esac], [enable_module_imap="true"]) AM_CONDITIONAL(BUILD_MODULE_IMAP, test x"$enable_module_imap" = "xtrue") if test x"$enable_module_imap" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** MSSQL Medusa Module ********** check_module_mssql=$check_libssl AC_MSG_CHECKING(whether to enable MSSQL module) AC_ARG_ENABLE(module-mssql, [ --enable-module-mssql=[no/yes] Enable MSSQL module (default=yes)], [case "${enableval}" in yes) enable_module_mssql=true ;; no) enable_module_mssql=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-mssql]) ;; esac], [enable_module_mssql=$check_module_mssql]) AM_CONDITIONAL(BUILD_MODULE_MSSQL, test x"$enable_module_mssql" = "xtrue") if test x"$enable_module_mssql" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** MYSQL Medusa Module ********** AC_MSG_CHECKING(whether to enable MYSQL module) AC_ARG_ENABLE(module-mysql, [ --enable-module-mysql=[no/yes] Enable MYSQL module (default=yes)], [case "${enableval}" in yes) enable_module_mysql=true ;; no) enable_module_mysql=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-mysql]) ;; esac], [enable_module_mysql="true"]) AM_CONDITIONAL(BUILD_MODULE_MYSQL, test x"$enable_module_mysql" = "xtrue") if test x"$enable_module_mysql" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** NCP Medusa Module ********** check_module_ncp="false" AS_MESSAGE([checking for NCPFS Library and Header files...]) AC_CHECK_HEADER([ncp/nwcalls.h], [AC_CHECK_LIB(ncp, main, [AC_DEFINE(HAVE_LIBNCP, 1, [Found NCP Library]) MODULE_LIBS="$MODULE_LIBS -lncp" check_module_ncp="true"], [AC_MSG_WARN([ *** NCPFS library required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using "make install-dev" within the NCPFS source. The NCP module will NOT be built. ])] )], [AC_MSG_WARN([ *** NCPFS header files required for NCP module. *** The NCPFS package must be installed for the NCP module to function. This includes both the library and header files. If your distribution does not include these files or offer a ncpfs-devel package, the files can be manually installed using "make install-dev" within the NCPFS source. The NCP module will NOT be built. ])] ) AC_MSG_CHECKING(whether to enable NCP module) AC_ARG_ENABLE(module-ncp, [ --enable-module-ncp=[no/yes] Enable NCP module (default=yes)], [case "${enableval}" in yes) enable_module_ncp=true ;; no) enable_module_ncp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-ncp]) ;; esac], [enable_module_ncp=$check_module_ncp]) AM_CONDITIONAL(BUILD_MODULE_NCP, test x"$enable_module_ncp" = "xtrue") if test x"$enable_module_ncp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** NNTP Medusa Module ********** AC_MSG_CHECKING(whether to enable NNTP module) AC_ARG_ENABLE(module-nntp, [ --enable-module-nntp=[no/yes] Enable NNTP module (default=yes)], [case "${enableval}" in yes) enable_module_nntp=true ;; no) enable_module_nntp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-nntp]) ;; esac], [enable_module_nntp="true"]) AM_CONDITIONAL(BUILD_MODULE_NNTP, test x"$enable_module_nntp" = "xtrue") if test x"$enable_module_nntp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** PCANYWHERE Medusa Module ********** AC_MSG_CHECKING(whether to enable PCANYWHERE module) AC_ARG_ENABLE(module-pcanywhere, [ --enable-module-pcanywhere=[no/yes] Enable PCANYWHERE module (default=yes)], [case "${enableval}" in yes) enable_module_pcanywhere=true ;; no) enable_module_pcanywhere=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-pcanywhere]) ;; esac], [enable_module_pcanywhere="true"]) AM_CONDITIONAL(BUILD_MODULE_PCANYWHERE, test x"$enable_module_pcanywhere" = "xtrue") if test x"$enable_module_pcanywhere" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** POP3 Medusa Module ********** AC_MSG_CHECKING(whether to enable POP3 module) AC_ARG_ENABLE(module-pop3, [ --enable-module-pop3=[no/yes] Enable POP3 module (default=yes)], [case "${enableval}" in yes) enable_module_pop3=true ;; no) enable_module_pop3=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-pop3]) ;; esac], [enable_module_pop3="true"]) AM_CONDITIONAL(BUILD_MODULE_POP3, test x"$enable_module_pop3" = "xtrue") if test x"$enable_module_pop3" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** POSTGRES Medusa Module ********** check_module_postgres="false" AS_MESSAGE([checking for PostgreSQL Library and Header files...]) AC_CHECK_HEADER([libpq-fe.h], [AC_CHECK_LIB(pq, main, [AC_DEFINE(HAVE_LIBPQ, 1, [Found PostgreSQL Library]) MODULE_LIBS="$MODULE_LIBS -lpq" check_module_postgres="true"], [AC_MSG_WARN([ *** LIBPQ library required for PostgreSQL module. *** The PostgreSQL package must be installed for the PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. ])] )], [AC_MSG_WARN([ *** LIBPQ header files required for PostgreSQL module. *** The PostgreSQL package must be installed for PostgreSQL module to function. This includes both the library and header files. Your distribution may offer a package such as libpq-devel or postgresql-devel, which will provide these files. ])] ) AC_MSG_CHECKING(whether to enable POSTGRES module) AC_ARG_ENABLE(module-postgres, [ --enable-module-postgres=[no/yes] Enable POSTGRES module (default=yes)], [case "${enableval}" in yes) enable_module_postgres=true ;; no) enable_module_postgres=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-postgres]) ;; esac], [enable_module_postgres=$check_module_postgres]) AM_CONDITIONAL(BUILD_MODULE_POSTGRES, test x"$enable_module_postgres" = "xtrue") if test x"$enable_module_postgres" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** RDP Medusa Module ********** check_module_rdp="false" module_rdp_headers="false" AC_ARG_WITH(freerdp, AS_HELP_STRING([--with-freerdp=prefix],[Prefix for FreeRDP include directory (default = /usr)]), [freerdp_prefix="$withval"], [freerdp_prefix="/usr"]) CPPFLAGS="$CPPFLAGS -I${freerdp_prefix}/include/freerdp2 -I${freerdp_prefix}/include/winpr2" AS_MESSAGE([checking for FreeRDP Library and Header files...]) AC_CHECK_HEADER([freerdp/freerdp.h], [AC_CHECK_LIB(freerdp2, main, [AC_DEFINE(HAVE_LIBFREERDP2, 1, [Found FreeRDP2 Library]) MODULE_LIBS="$MODULE_LIBS -lfreerdp2" check_module_rdp="true"], [AC_MSG_WARN([ *** FreeRDP2 library required for RDP module. *** The FreeRDP package must be installed for RDP module to function. This includes both the library and header files. Your distribution may offer packages such as freerdp2-dev/libfreerdp2, which will provide these files. ])] )], [AC_MSG_WARN([ *** FreeRDP2 header files required for RDP module. *** The FreeRDP package must be installed for RDP module to function. This includes both the library and header files. Your distribution may offer packages such as freerdp2-dev/libwinpr2-dev, which will provide these files. ])] ) AC_MSG_CHECKING(whether to enable RDP module) AC_ARG_ENABLE(module-rdp, [ --enable-module-rdp=[no/yes] Enable RDP module (default=yes)], [case "${enableval}" in yes) enable_module_rdp=true ;; no) enable_module_rdp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rdp]) ;; esac], [enable_module_rdp=$check_module_rdp]) AM_CONDITIONAL(BUILD_MODULE_RDP, test x"$enable_module_rdp" = "xtrue") if test x"$enable_module_rdp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** REXEC Medusa Module ********** AC_MSG_CHECKING(whether to enable REXEC module) AC_ARG_ENABLE(module-rexec, [ --enable-module-rexec=[no/yes] Enable REXEC module (default=yes)], [case "${enableval}" in yes) enable_module_rexec=true ;; no) enable_module_rexec=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rexec]) ;; esac], [enable_module_rexec="true"]) AM_CONDITIONAL(BUILD_MODULE_REXEC, test x"$enable_module_rexec" = "xtrue") if test x"$enable_module_rexec" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** RLOGIN Medusa Module ********** AC_MSG_CHECKING(whether to enable RLOGIN module) AC_ARG_ENABLE(module-rlogin, [ --enable-module-rlogin=[no/yes] Enable RLOGIN module (default=yes)], [case "${enableval}" in yes) enable_module_rlogin=true ;; no) enable_module_rlogin=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rlogin]) ;; esac], [enable_module_rlogin="true"]) AM_CONDITIONAL(BUILD_MODULE_RLOGIN, test x"$enable_module_rlogin" = "xtrue") if test x"$enable_module_rlogin" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** RSH Medusa Module ********** AC_MSG_CHECKING(whether to enable RSH module) AC_ARG_ENABLE(module-rsh, [ --enable-module-rsh=[no/yes] Enable RSH module (default=yes)], [case "${enableval}" in yes) enable_module_rsh=true ;; no) enable_module_rsh=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-rsh]) ;; esac], [enable_module_rsh="true"]) AM_CONDITIONAL(BUILD_MODULE_RSH, test x"$enable_module_rsh" = "xtrue") if test x"$enable_module_rsh" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMBNT Medusa Module ********** check_module_smbnt=$check_libssl AC_MSG_CHECKING(whether to enable SMBNT module) AC_ARG_ENABLE(module-smbnt, [ --enable-module-smbnt=[no/yes] Enable SMBNT module (default=yes)], [case "${enableval}" in yes) enable_module_smbnt=true ;; no) enable_module_smbnt=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smbnt]) ;; esac], [enable_module_smbnt=$check_module_smbnt]) AM_CONDITIONAL(BUILD_MODULE_SMBNT, test x"$enable_module_smbnt" = "xtrue") if test x"$enable_module_smbnt" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMBNT Medusa Module (SMBv2 Support) ********** check_module_smbnt_smb2="false" AC_ARG_WITH(libsmb2, AS_HELP_STRING([--with-libsmb2=prefix],[Prefix for libsmb2 include directory (default = /usr)]), [libsmb2_prefix="$withval"], [libsmb2_prefix="/usr"]) CPPFLAGS="$CPPFLAGS -I${libsmb2_prefix}/include/smb2" AS_MESSAGE([checking for libsmb2 Library and Header files...]) AC_CHECK_HEADER([smb2/libsmb2.h], [AC_CHECK_LIB(smb2, main, [AC_DEFINE(HAVE_LIBSMB2, 1, [Found libsmb2 Library]) MODULE_LIBS="$MODULE_LIBS -lsmb2" check_module_smbnt_smb2="true"], [AC_MSG_WARN([ *** libsmb2 library required for SMBNT module SMBv2 support. *** https://github.com/sahlberg/libsmb2 ])] )], [AC_MSG_WARN([ *** libsmb2 header files required for SMBNT module SMBv2 support. *** https://github.com/sahlberg/libsmb2 ])] ) AC_MSG_CHECKING(whether to enable SMBNT module SMBv2 support) AC_ARG_ENABLE(module-smbnt-smb2, [ --enable-module-smbnt-smb2=[no/yes] Enable SMBNT module [SMBv2 support] (default=yes)], [case "${enableval}" in yes) enable_module_smbnt_smb2=true ;; no) enable_module_smbnt_smb2=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smbnt-smb2]) ;; esac], [enable_module_smbnt_smb2=$check_module_smbnt_smb2]) AM_CONDITIONAL(BUILD_MODULE_SMBNT_SMB2, test x"$enable_module_smbnt_smb2" = "xtrue") if test x"$enable_module_smbnt_smb2" = "xtrue"; then AC_DEFINE(SMBNT_SMB2_SUPPORT_ENABLED, 1, [SMBNT SMBv2 Support Enabled]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMTP Medusa Module ********** AC_MSG_CHECKING(whether to enable SMTP module) AC_ARG_ENABLE(module-smtp, [ --enable-module-smtp=[no/yes] Enable SMTP module (default=yes)], [case "${enableval}" in yes) enable_module_smtp=true ;; no) enable_module_smtp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smtp]) ;; esac], [enable_module_smtp="true"]) AM_CONDITIONAL(BUILD_MODULE_SMTP, test x"$enable_module_smtp" = "xtrue") if test x"$enable_module_smtp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SMTP-VRFY Medusa Module ********** AC_MSG_CHECKING(whether to enable SMTP-VRFY module) AC_ARG_ENABLE(module-smtp-vrfy, [ --enable-module-smtp-vrfy=[no/yes] Enable SMTP-VRFY module (default=yes)], [case "${enableval}" in yes) enable_module_smtp_vrfy=true ;; no) enable_module_smtp_vrfy=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-smtp-vrfy]) ;; esac], [enable_module_smtp_vrfy="true"]) AM_CONDITIONAL(BUILD_MODULE_SMTP_VRFY, test x"$enable_module_smtp_vrfy" = "xtrue") if test x"$enable_module_smtp_vrfy" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SNMP Medusa Module ********** AC_MSG_CHECKING(whether to enable SNMP module) AC_ARG_ENABLE(module-snmp, [ --enable-module-snmp=[no/yes] Enable SNMP module (default=yes)], [case "${enableval}" in yes) enable_module_snmp=true ;; no) enable_module_snmp=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-snmp]) ;; esac], [enable_module_snmp="true"]) AM_CONDITIONAL(BUILD_MODULE_SNMP, test x"$enable_module_snmp" = "xtrue") if test x"$enable_module_snmp" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SSH Medusa Module ********** check_module_ssh="false" AS_MESSAGE([checking for Libssh2 Library files...]) AC_CHECK_LIB(ssh2, main, [AC_DEFINE(HAVE_LIBSSH2, 1, [Found SSH2 Library]) MODULE_LIBS="$MODULE_LIBS -lssh2" check_module_ssh="true"], [AC_MSG_WARN([ *** Libssh2 required for SSH2 module. *** Libssh2 (http://www.libssh2.org) is not the same as libssh (http://0xbadc0de.be). Make sure you have the correct library. The SSH2 module will NOT be built. ])] ) dnl Test whether libssh2 was built with libgcrypt if test x"$check_module_ssh" = "xtrue"; then check_libgcrypt="false" for _dir in `ld --verbose | grep SEARCH_DIR | sed -e 's/\"); */\n/g' | cut -d= -f2` do if test -f "$_dir/libssh2.so"; then LIBSSH2_PATH="$_dir/libssh2.so" fi done for _dir in "/usr/lib" "/usr/local/lib" do if test -f "$_dir/libssh2.dylib"; then LIBSSH2_PATH="$_dir/libssh2.dylib" fi done if test -z "$LIBSSH2_PATH"; then AC_MSG_WARN([ LIBSSH2 path not found. Assuming it was... ]) check_libgcrypt="true" fi dnl Use otool on Mac OS X if test -f "`which ldd`"; then LDD="ldd" elif test -f "`which otool`"; then LDD="otool -L" else AC_MSG_WARN([ No ldd detected. Unable to test whether Libssh2 was compiled to use libgcrypt. Assuming it was... ]) check_libgcrypt="true" fi if test ! -z "`$LDD $LIBSSH2_PATH |grep libgcrypt`"; then AC_MSG_WARN([ Libssh2 compiled using libgcrypt. Checking additional dependencies. ]) check_libgcrypt="true" fi if test x"$check_libgcrypt" = "xtrue"; then AS_MESSAGE([checking for Libgrcypt Library files...]) AC_CHECK_LIB(gcrypt, gcry_control, [AC_DEFINE(HAVE_LIBGCRYPT, 1, [Found Libgcrypt Library]) LIBS="$LIBS -lgcrypt"], [AC_MSG_WARN([ *** Libgcrypt required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgcrypt11-dev). The SSH2 module will NOT be built. ]) check_module_ssh="false" ]) AS_MESSAGE([checking for GnuTLS Library files...]) AC_CHECK_LIB(gnutls, gnutls_handshake, [AC_DEFINE(HAVE_GNUTLS, 1, [Found GnuTLS Library]) LIBS="$LIBS -lgnutls"], [AC_MSG_WARN([ *** GnuTLS required for installed version of Libssh2 *** The default build of Libssh2 is to use OpenSSL for crypto. Several Linux distributions (e.g. Debian, Ubuntu) build it to use Libgcrypt. In order to use libssh2 in a thread-safe manner, we need to link to Libgcrypt and properly initialize it. Make sure you have the Libgcrypt/GnuTLS libraries and headers (e.g. libgnutls-dev). The SSH2 module will NOT be built. ]) check_module_ssh="false" ]) fi fi AC_MSG_CHECKING(whether to enable SSH module) AC_ARG_ENABLE(module-ssh, [ --enable-module-ssh=[no/yes] Enable SSH module (default=yes)], [case "${enableval}" in yes) enable_module_ssh=true ;; no) enable_module_ssh=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-ssh]) ;; esac], [enable_module_ssh=$check_module_ssh]) AM_CONDITIONAL(BUILD_MODULE_SSH, test x"$enable_module_ssh" = "xtrue") if test x"$enable_module_ssh" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** SVN Medusa Module ********** check_module_svn="false" AS_MESSAGE([checking for Subversion Library and Header files...]) AC_PATH_PROG(APR_CONFIG, apr-1-config) if test -z "$APR_CONFIG"; then AC_PATH_PROG(APR_CONFIG, apr-config) if test -z "$APR_CONFIG"; then AC_MSG_WARN([ *** apr-config/apr-1-config not found and required for SVN module *** Make sure to install libapr1-dev or whatever package your distribution uses to distribute this file. ]) fi fi if test -n "$APR_CONFIG"; then if test x`$APR_CONFIG --cc` = "xcc"; then AC_MSG_WARN([ *** Apache (apr) was compiled using Sun C compiler and not GNU gcc. *** "$APR_CONFIG --cc" responded with "cc", which usually means that your build of Apache was compiled with Sun C compiler and not with gcc. This means that the version of libtool embedded within Apache installation is also configured for Sun C compiler and not gcc. The Sun C compiler setup is incompatible because the options to each compiler are different for building shared objects and libraries. Specifically, the Sun compiler supports the "-mt" flag, whereas gcc does not. In order to build the SVN Medusa module, rebuild $APR_CONFIG using gcc, or remove the "-mt" CPPFLAGS flag from the autogenerated Medusa configuration files. ]) else APR_INCLUDE_DIR=`$APR_CONFIG --includedir` AC_SUBST(APR_INCLUDE_DIR) CPPFLAGS="$CPPFLAGS `$APR_CONFIG --includes --cppflags`" AC_CHECK_HEADER([$APR_INCLUDE_DIR/apr_tables.h], [AC_CHECK_HEADER([subversion-1/svn_client.h], [AC_CHECK_LIB(svn_client-1, main, [AC_DEFINE(HAVE_LIBSVN_CLIENT_1, 1, [Found SVN Library]) MODULE_LIBS="$MODULE_LIBS -lsvn_client-1" check_module_svn="true"], [AC_MSG_WARN([ *** Subversion libsvn library required for SVN module. *** ])] )], [AC_MSG_WARN([ *** Subversion header files required for SVN module. (e.g., libsvn-dev) *** ])])], [AC_MSG_WARN([ *** APR header files required for SVN module. (e.g., libapr1-dev) *** ])] ) fi else check_module_svn="false" fi if test x"$check_module_svn" = "xtrue"; then AC_CHECK_LIB(svn_client-1, svn_client_list4, [AC_DEFINE(HAVE_SVN_CLIENT_LIST4, 1, [Found SVN Library version 1.10 or greater])], [AC_MSG_WARN([Found SVN Library older than version 1.10])] ) AC_CHECK_LIB(svn_client-1, svn_client_list3, [AC_DEFINE(HAVE_SVN_CLIENT_LIST3, 1, [Found SVN Library version 1.8 or greater])], [AC_MSG_WARN([Found SVN Library older than version 1.8])] ) fi AC_MSG_CHECKING(whether to enable SVN module) AC_ARG_ENABLE(module-svn, [ --enable-module-svn=[no/yes] Enable SVN module (default=yes)], [case "${enableval}" in yes) enable_module_svn=true ;; no) enable_module_svn=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-svn]) ;; esac], [enable_module_svn=$check_module_svn]) AM_CONDITIONAL(BUILD_MODULE_SVN, test x"$enable_module_svn" = "xtrue") if test x"$enable_module_svn" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** TELNET Medusa Module ********** AC_MSG_CHECKING(whether to enable TELNET module) AC_ARG_ENABLE(module-telnet, [ --enable-module-telnet=[no/yes] Enable TELNET module (default=yes)], [case "${enableval}" in yes) enable_module_telnet=true ;; no) enable_module_telnet=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-telnet]) ;; esac], [enable_module_telnet="true"]) AM_CONDITIONAL(BUILD_MODULE_TELNET, test x"$enable_module_telnet" = "xtrue") if test x"$enable_module_telnet" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** VMAUTHD Medusa Module ********** AC_MSG_CHECKING(whether to enable VMAUTHD module) AC_ARG_ENABLE(module-vmauthd, [ --enable-module-vmauthd=[no/yes] Enable VMAUTHD module (default=yes)], [case "${enableval}" in yes) enable_module_vmauthd=true ;; no) enable_module_vmauthd=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-vmauthd]) ;; esac], [enable_module_vmauthd="true"]) AM_CONDITIONAL(BUILD_MODULE_VMAUTHD, test x"$enable_module_vmauthd" = "xtrue") if test x"$enable_module_vmauthd" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** VNC Medusa Module ********** check_module_vnc=$check_libssl AC_MSG_CHECKING(whether to enable VNC module) AC_ARG_ENABLE(module-vnc, [ --enable-module-vnc=[no/yes] Enable VNC module (default=yes)], [case "${enableval}" in yes) enable_module_vnc=true ;; no) enable_module_vnc=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-vnc]) ;; esac], [enable_module_vnc=$check_module_vnc]) AM_CONDITIONAL(BUILD_MODULE_VNC, test x"$enable_module_vnc" = "xtrue") if test x"$enable_module_vnc" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** WRAPPER Medusa Module ********** AC_MSG_CHECKING(whether to enable WRAPPER module) AC_ARG_ENABLE(module-wrapper, [ --enable-module-wrapper=[no/yes] Enable WRAPPER module (default=yes)], [case "${enableval}" in yes) enable_module_wrapper=true ;; no) enable_module_wrapper=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-wrapper]) ;; esac], [enable_module_wrapper="true"]) AM_CONDITIONAL(BUILD_MODULE_WRAPPER, test x"$enable_module_wrapper" = "xtrue") if test x"$enable_module_wrapper" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi dnl ********** Web Form Medusa Module ********** check_module_web_form=$check_libssl AC_MSG_CHECKING(whether to enable WEB-FORM module) AC_ARG_ENABLE(module-web-form, [ --enable-module-web-form=[no/yes] Enable WEB-FORM module (default=yes)], [case "${enableval}" in yes) enable_module_web_form=true ;; no) enable_module_web_form=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-module-web-form]) ;; esac], [enable_module_web_form=$check_module_web_form]) AM_CONDITIONAL(BUILD_MODULE_WEB_FORM, test x"$enable_module_web_form" = "xtrue") if test x"$enable_module_web_form" = "xtrue"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_MSG_NOTICE([]) AC_MSG_NOTICE([*******************************************************]) AC_MSG_NOTICE([ Medusa Module Build Summary]) AC_MSG_NOTICE([]) show_build_status() { if test "$1" = "true" ; then AC_MSG_NOTICE([$2 Enabled]) else AC_MSG_NOTICE([$2 ** Disabled **]) fi } show_build_status "${enable_module_afp}" " AFP " show_build_status "${enable_module_cvs}" " CVS " show_build_status "${enable_module_ftp}" " FTP " show_build_status "${enable_module_http}" " HTTP " show_build_status "${enable_module_imap}" " IMAP " show_build_status "${enable_module_mssql}" " MSSQL " show_build_status "${enable_module_mysql}" " MYSQL " show_build_status "${enable_module_ncp}" " NCP " show_build_status "${enable_module_nntp}" " NNTP " show_build_status "${enable_module_pcanywhere}" " PCANYWHERE " show_build_status "${enable_module_pop3}" " POP3 " show_build_status "${enable_module_postgres}" " POSTGRES " show_build_status "${enable_module_rdp}" " RDP " show_build_status "${enable_module_rexec}" " REXEC " show_build_status "${enable_module_rlogin}" " RLOGIN " show_build_status "${enable_module_rsh}" " RSH " show_build_status "${enable_module_smbnt}" " SMBNT " show_build_status "${enable_module_smbnt_smb2}" " SMBNT (SMBv2) " show_build_status "${enable_module_smtp}" " SMTP " show_build_status "${enable_module_smtp_vrfy}" " SMTP-VRFY " show_build_status "${enable_module_snmp}" " SNMP " show_build_status "${enable_module_ssh}" " SSH " show_build_status "${enable_module_svn}" " SVN " show_build_status "${enable_module_telnet}" " TELNET " show_build_status "${enable_module_vmauthd}" " VMAUTHD " show_build_status "${enable_module_vnc}" " VNC " show_build_status "${enable_module_wrapper}" " WRAPPER " show_build_status "${enable_module_web_form}" " WEB-FORM " AC_MSG_NOTICE([]) AC_MSG_NOTICE([ If a module is unexpectedly marked as disabled, check ]) AC_MSG_NOTICE([ above output and verify dependancies were satisfied. ]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([ It should also be noted that, by default, not all of ]) AC_MSG_NOTICE([ the modules are built. Incomplete modules or modules ]) AC_MSG_NOTICE([ which have not been sufficiently tested may be ]) AC_MSG_NOTICE([ disabled. To enable non-default modules, use the ]) AC_MSG_NOTICE([ "--enable-module-MODULE_NAME" configure option.]) AC_MSG_NOTICE([*******************************************************]) AC_MSG_NOTICE([]) # strcasestr() is a nonstandard extension and requires _GNU_SOURCE (https://linux.die.net/man/3/strcasestr) CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" AC_CHECK_FUNCS(strcasestr) AC_CHECK_FUNCS(asprintf) AC_CHECK_FUNCS(vasprintf) dnl -lm --> mysql/floor(), http/log() dnl -lrt --> clock_gettime() case "$target" in *linux*) LIBDL="-ldl -lrt -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *freebsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *netbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; *openbsd*) LIBDL="-lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="-g -Wl,-E" ;; *apple-darwin*) # Modules will segfault when executed (show usage works) if medusa core # is not linked to CoreFoundation (starting with 10.6). This is believed to # be due to libsvn linking to CoreFoundation and our modules linked via # "-lsvn_client-1". See http://www.openradar.me/7209349 for more info. LIBDL="-ldl -framework CoreFoundation" # OS X Lion marked OpenSSL as deprecated. We're disabling these warnings # for now. We'll need to figure out if it's worth supporting Common Crypto # or simply requiring users to install their own OpenSSL in the future. CFLAGS="$CFLAGS -Wno-deprecated-declarations" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -bundle -flat_namespace -undefined suppress" EXTRA_LDFLAGS="" ;; *solaris*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" LDFLAGS="$LDFLAGS -R/usr/local/lib -R/usr/local/ssl/lib -L/usr/local/ssl/lib" LIBDL="-ldl -lm -lrt -lnsl -lsocket" RDYNAMIC="-Rdynamic" EXTRA_LDFLAGS="" MODULE_LIBS="$MODULE_LIBS -G" ;; *cygwin*) CPPFLAGS="$CPPFLAGS -DCYGWIN" LIBDL="-ldl" RDYNAMIC="" MODULE_LIBS="$MODULE_LIBS -shared" ;; *) LIBDL="-ldl -lm" RDYNAMIC="-rdynamic" MODULE_LIBS="$MODULE_LIBS -shared" EXTRA_LDFLAGS="" ;; esac AC_SUBST([MODULE_LIBS]) LDFLAGS="$LDFLAGS $RDYNAMIC $EXTRA_LDFLAGS" LIBS="$LIBS $LIBDL" test "$prefix" = NONE && prefix=${ac_default_prefix} _default_mod_path="${prefix}/lib/medusa/modules" AC_ARG_WITH(default-mod-path, AS_HELP_STRING([--with-default-mod-path=path],[Location of medusa module files (default = /usr/local/lib/medusa/modules)]),[_default_mod_path="$withval"]) AC_DEFINE_UNQUOTED(DEFAULT_MOD_PATH, "$_default_mod_path", [Location of medusa module files]) AC_SUBST(DEFAULT_MOD_PATH) AC_CONFIG_FILES([Makefile src/Makefile src/modsrc/Makefile]) AC_OUTPUT jmk-foofus-medusa-dd62069/depcomp000077500000000000000000000560201460263104500167670ustar00rootroot00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jmk-foofus-medusa-dd62069/docs/000077500000000000000000000000001460263104500163375ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/docs/medusa-afp.html000066400000000000000000000014171460263104500212520ustar00rootroot00000000000000 Foofus Networking Services - Medusa::AFP

Medusa Parallel Network Login Auditor :: AFP

JoMo-Kun / jmk "AT" foofus "DOT" net

The AFP module tests accounts against the Apple Filing Protocol service.

This AFP module leverages the afpfs-ng FUSE-based client (http://alexthepuffin.googlepages.com/home). The current Medusa autoconf setup requires that the afpfs-ng header files be installed to /usr/include/afpfs-ng and the libary be located at /usr/lib/libafpclient.so.0. If this does not match your setup, modifications to the autoconf configuration will be necessary.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-compare.html000066400000000000000000000225031460263104500221310ustar00rootroot00000000000000 Foofus Networking Services - Medusa

Medusa Parallel Network Login Auditor :: Feature Comparison

JoMo-Kun / jmk "AT" foofus "DOT" net

Note: Information contained on this page for Hydra and Ncrack is based on each tool's own documentation. No confirmation of supported services has been performed.

Area Feature Medusa 2.2 Hydra 7.1 Ncrack 0.4ALPHA
* License GPL-2 GPL-3 GPL-2
Core Parallel Method pthread fork()
Service Design Modular Built-in
Speed (several comparisons are included below) ? ? ?
Generic Wrapper Module
AFP
CVS
FTP FTP
Explicit FTPS (AUTH TLS Mode as defined in RFC 4217)
Implicit FTPS (FTP over SSL (990/tcp)
HTTP Basic Auth
NTLM Auth (Windows Integrated)
Digest Authentication MD5, MD5-sess MD5
HTTP Proxy
ICQ
IMAP Method LOGIN Support
Method AUTH-PLAIN Support
Method AUTH-NTLM Support
SSL Support IMAPS, STARTTLS IMAPS, STARTTLS
LDAP
Microsoft SQL Port Auto-Detection
MS-SQL
MySQL Pre-4.1 Authentication
Pre-4.1 Hash Passing
4.1+ Authentication
NCP (NetWare) √ (ncpfs) √ (ncpfs)
NNTP √ (Original AUTHINFO) √ (Original AUTHINFO)
Oracle Database √ (via Wrapper script)
Listener
SID
PcAnywhere Supported Encryption Level None None
Supported Authenication Mode(s) Native PCA, ADS, NT, Windows Native PCA
PCNFS
POP3 Method AUTH-USER Support
Method AUTH-LOGIN Support
Method AUTH-PLAIN Support
Method AUTH-NTLM Support
SSL Support POP3S, STARTTLS POP3S POP3S, STARTTLS
PostgreSQL
RDP (Terminal Server)
Pass the Hash Support
REXEC
RLOGIN .rhost Support
Password Support
RSH
SAPR3
SIP
SMB (Microsoft Windows/Samba) Authentication Modes clear-text, LMv1, NTLMv1, LMv2, NTLMv2 clear-text, LMv1, NTLMv1, LMv2, NTLMv2 Unknown
Hash Passing
Access Detection (ADMIN$)
SMTP Method AUTH-LOGIN Support
Method AUTH-PLAIN Support
Method AUTH-NTLM Support
SSL Support STARTTLS STARTTLS
VRFY
EXPN
RCPT TO
SNMP √ (significantly faster design) √ (overwrites sysName with "HYDRA")
SOCKS5
SSHv2 √ (libssh2) √ (libssh)
SVN
TeamSpeak
Telnet Generic Telnet
Cisco (AAA/non-AAA)
Cisco enable password
AS/400 (TN5250) Support
VNC Password-less/Password-only Support
Anti-Brute Force Slowdown Support
Username/Password Support
VmWare Authentication Daemon Non-SSL Authentication
SSL Authentication
Web Form Module

Speed comparison: password list of 20 entries (valid entry at #20)
FTP / Ubuntu 11.10 vsftp 2.3.2
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  1:03.53     15.727         7.658     (e.g., -t 16)
Hydra     57.527    16.545         8.013     (e.g., -t 16)
Ncrack  1:00.01     24.017        15.009     (e.g., -g cl=16,CL=16)

Speed comparison: password list of 1003 entries (valid entry at #1000)
HTTP / Windows 2008 IIS 7.0
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  1.390       0.803        0.626       (e.g., -v 4 -t 16)
Hydra   1.443       0.855        0.790       (e.g., -t 16)
Ncrack  3.108       3.016        3.013       (e.g., -g cl=16,CL=16)

Speed comparison: password list of 1003 entries (valid entry at #986)
SMB / Windows 2008 
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  6.859       0.919        0.500       (e.g., -v 4 -t 16)
Hydra   8.216                                (doesn't handle parallel connections)
Ncrack                                       (failed to auth to test server) 

Speed comparison: password list of 10 entries (valid entry at #10)
SSH Ubuntu 11.10 OpenSSH 5.8p1
        [1 task]    [4 tasks]    [16 tasks] 
Medusa  38.039      11.943       8.067       (e.g., -v 4 -t 16)
Hydra   32.122      12.208       8.457       (e.g., -t 16)
Ncrack  30.023      27.012       24.013      (e.g., -g cl=16,CL=16)


Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-cvs.html000066400000000000000000000011131460263104500212700ustar00rootroot00000000000000 Foofus Networking Services - Medusa::CVS

Medusa Parallel Network Login Auditor :: CVS

JoMo-Kun / jmk "AT" foofus "DOT" net

The CVS module tests accounts against the CVS version control system via the pserver protocol.

The module has a single option, DIR. This allows the user to specify the target CVSROOT path. For example, :pserver:USER@HOST:/SOME_DIR. If the option is not set, the default behaviour is to use /root.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-ftp.html000066400000000000000000000007061460263104500212750ustar00rootroot00000000000000 Foofus Networking Services - Medusa::FTP

Medusa Parallel Network Login Auditor :: FTP

JoMo-Kun / jmk "AT" foofus "DOT" net

The FTP module tests accounts against the FTP and FTPS services. This includes both Explicit FTPS (AUTH TLS Mode as defined in RFC 4217) and Implicit (FTP over SSL (990/tcp)).

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-http.html000066400000000000000000000006541460263104500214650ustar00rootroot00000000000000 Foofus Networking Services - Medusa::HTTP

Medusa Parallel Network Login Auditor :: HTTP

JoMo-Kun / jmk "AT" foofus "DOT" net

The HTTP module tests accounts against HTTP/HTTPS services using BASIC-AUTH, integrated windows authentication (NTLM) and digest (MD5 and MD5-sess).

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-imap.html000066400000000000000000000010141460263104500214230ustar00rootroot00000000000000 Foofus Networking Services - Medusa::IMAP

Medusa Parallel Network Login Auditor :: IMAP

JoMo-Kun / jmk "AT" foofus "DOT" net

The IMAP module tests accounts against the IMAP service. This module supports both imap (143) and imaps (993). The IMAP module asks for the server's capabilities and then does either a LOGIN or an AUTHENTICATE PLAIN, depending on its response.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-mssql.html000066400000000000000000000016561460263104500216500ustar00rootroot00000000000000 Foofus Networking Services - Medusa::MSSQL

Medusa Parallel Network Login Auditor :: MSSQL

JoMo-Kun / jmk "AT" foofus "DOT" net

The MSSQL module tests accounts against Microsoft MS-SQL service.

It should be noted that MS-SQL Developer Edition and/or MSDE's concurrent workload governor limits you to no more than five concurrent connections to the server at any one time.

The MSSQL module will auto-detect the TCP ports used by the SQL server instances on the remote host. This is accomplished via a "SQL Ping" UDP request. If multiple instances are present on the host, only the first will be tested. Any additional instances will be reported and their respective TCP port will be noted. The auto-detection can be over-ridden by specifying a port via the Medusa "-n" option.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-mysql.html000066400000000000000000000014621460263104500216510ustar00rootroot00000000000000 Foofus Networking Services - Medusa::MySQL

Medusa Parallel Network Login Auditor :: MySQL

JoMo-Kun / jmk "AT" foofus "DOT" net

The MySQL module tests accounts against the MySQL service.

In addition to normal password brute force attempts, this module supports "pass-the-hash" abilities for older MySQL (pre-4.1) hashes. The older MySQL pre-4.1 authentication scheme is vulnerable to a pass-the-hash authentication attack. Utilizing the old-style hashes gathered from a MySQL database, a user can use Medusa to verify their validity on other servers. A modified MySQL client can also be use to connect to located services directly utilizing a valid hash.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-ncp.html000066400000000000000000000042261460263104500212650ustar00rootroot00000000000000 Foofus Networking Services - Medusa::NCP

Medusa Parallel Network Login Auditor :: NCP

JoMo-Kun / jmk "AT" foofus "DOT" net

The NCP module tests accounts against the NetWare NCP service. This module was developed using a NetWare 5.1 host as the target.

This module requires ncpfs. The ncpfs package must also be installed using the "install-dev" option. This installs both the ncpfs header files and the static libncp library. A modified Gentoo ebuild has been included in the /misc/net-fs/ncpfs directory which includes a USE flag for this option.

The module has a single option, CONTEXT. It should be noted that libncp does not by default automatically specific a user context. If it fails to resolve the name provided it appends the server's context to the username and attempts to resolve that value. It is advised that users specify a context for each account being tested. A global context can be specified using the CONTEXT option. A per-user context can be defined as part of the account name within a file containing usernames or the username passed via the command-line.

The following examples demonstrate several uses of the NCP module:

  • Specify a context for all accounts in users.txt:
    
    % medusa -h 192.168.0.20 -U users.txt -p bar -M ncp -m CONTEXT:.OU=administrators.O=foofus
    
    
  • Pass the full user context via the "-u" parameter:
    
    % medusa -h 192.168.0.20 -u username.OU=administrators.O=foofus -p bar -M ncp
    
    

Libncp, by default, also uses both the NDS and BIND authenticators. Unfortunately, the only error message returned to the module is that of the BIND authenticator. These messages are not as descriptive as NDS and only seem to report success or failure. In order to have more useful messages (account disabled/max logons exceeded/etc.), create a ~/.nwclient or /etc/ncpfs.conf file with the following text:

[Requester]
NetWare Protocol = NDS


Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-nntp.html000066400000000000000000000005571460263104500214670ustar00rootroot00000000000000 Foofus Networking Services - Medusa::NNTP

Medusa Parallel Network Login Auditor :: NNTP

JoMo-Kun / jmk "AT" foofus "DOT" net

The NNTP module tests accounts against the Network News Transfer Protocol via AUTHINFO.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-pcanywhere.html000066400000000000000000000025471460263104500226560ustar00rootroot00000000000000 Foofus Networking Services - Medusa::PcAnywhere

Medusa Parallel Network Login Auditor :: PcAnywhere

JoMo-Kun / jmk "AT" foofus "DOT" net

The PcAnywhere module tests accounts against the Symantec PcAnywhere service.

NOTE: PcAnywhere allows only one connection at a time. Running multiple threads per target may not work well.

Module based on packet captures from Server Version 10.5.1 and Client 10.0.2.

PCA Authentication Methods:
   ADS (Active Directory Services) [1]
   FTP [2]
   HTTP [2]
   HTTPS [2]
   Microsoft LDAP [2]
   Netscape LDAP [2]
   Novell LDAP [2]
   NT [1]
   pcAnywhere [1]
   Windows [3]

[1] Verified working
[2] Untested
[3] Verified to work when PcAnywhere host authenticates against domain accounts.
Authentication fails for local accounts with both the module and the PcAnywhere
client. Not sure what's going on...


Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-pop3.html000066400000000000000000000024311460263104500213620ustar00rootroot00000000000000 Foofus Networking Services - Medusa::POP3

Medusa Parallel Network Login Auditor :: POP3

JoMo-Kun / jmk "AT" foofus "DOT" net

The POP3 module tests accounts against the POP3 service.

The module has a single option, MODE. If left unset, the default behavior is to check for either "+" or "-" in the server's response to see if the attempt was successful.

If the server being tested in an AS/400, the module should be executed using the option -m MODE:AS400. This will result in the -ERR message being returned to be parsed for addition information. This is based on information gathered from the following document: Enumeration_of_AS400_users_via_pop3.pdf

The module supports both POP3 (110/tcp) and POP3S (POP3 protocol over TLS/SSL) (995/tcp). In addition, it supports the POP3 STARTTLS extention, as defined in http://www.faqs.org/rfcs/rfc2595.html. Medusa will submit a "STLS" command to the target server. If a positive response is returned, a TLS session will be initiated.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-postgres.html000066400000000000000000000011671460263104500223540ustar00rootroot00000000000000 Foofus Networking Services - Medusa::PostgreSQL

Medusa Parallel Network Login Auditor :: PostgreSQL

JoMo-Kun / jmk "AT" foofus "DOT" net

The postgres module tests accounts against the PostgreSQL service.

This module requires the PostgreSQL library: libpq.

The module has a single option, DB. This allows the user to specify the target database name. If the option is not set, the default behaviour is to use template1.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-rdp.html000066400000000000000000000022141460263104500212650ustar00rootroot00000000000000 Foofus Networking Services - Medusa::RDP

Medusa Parallel Network Login Auditor :: RDP

JoMo-Kun / jmk "AT" foofus "DOT" net

The RDP module tests accounts against the Microsoft Remote Desktop Protocol (RDP) / Terminal Service. It should be noted that will only work with target systems running Microsoft 2008 and later. Tests against Microsoft XP/2003/etc, will always report that the logon was successful.

This module requires FreeRDP. The pass-the-hash option is also only available if FreeRDP version 1.2 or greater is installed.

The following examples demonstrate several uses of the RDP module:

  • Logon attempt using pass-the-hash (NTLM):
    
    medusa -M rdp -m PASS:HASH -h 10.10.10.10 -u Administrator -p 31D78236327B9619B14ED8EC9AB454C1
    
  • Logon attempt supplying domain name (default behavior is a local logon):
    
    medusa -M rdp -m DOMAIN:CORPNAME -h 10.10.10.10 -u Administrator -p Password1 
    


Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-rexec.html000066400000000000000000000005251460263104500216110ustar00rootroot00000000000000 Foofus Networking Services - Medusa::REXEC

Medusa Parallel Network Login Auditor :: REXEC

JoMo-Kun / jmk "AT" foofus "DOT" net

The REXEC module tests accounts against the REXEC service.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-rlogin.html000066400000000000000000000005311460263104500217720ustar00rootroot00000000000000 Foofus Networking Services - Medusa::RLOGIN

Medusa Parallel Network Login Auditor :: RLOGIN

JoMo-Kun / jmk "AT" foofus "DOT" net

The RLOGIN module tests accounts against the RLOGIN service.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-rsh.html000066400000000000000000000005151460263104500212760ustar00rootroot00000000000000 Foofus Networking Services - Medusa::RSH

Medusa Parallel Network Login Auditor :: RSH

JoMo-Kun / jmk "AT" foofus "DOT" net

The RSH module tests accounts against the RSH service.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-smbnt.html000066400000000000000000000236761460263104500216420ustar00rootroot00000000000000 Foofus Networking Services - Medusa::SMBNT

Medusa Parallel Network Login Auditor :: SMBNT

JoMo-Kun / jmk "AT" foofus "DOT" net

The SMBNT module tests accounts against the Microsoft netbios-ssn (TCP/139) and microsoft-ds (TCP/445) services. Besides testing normal passwords, this module allows Medusa to directly test NTLM hashes against a Windows host. This may be useful for an auditor who has aquired a sam._ or pwdump file and would like to quickly determine which are valid entries. The SMBNT module natively supports the SMBv1 protocol. If built with libsmb2 support, it will automatically also test SMBv2/3 services and handle SMB signing.

Several "-m 'METHOD:VALUE'" options can be used with this module. The following are valid methods: AUTH, GROUP, GROUP_OTHER, PASS and NETBIOS. The following values are useful for these methods:

Method Value Description
AUTH LM Force LMv1 authentication. Since LM hashes don't store character case information, this could potentially be used to improve our ability to identify more complex passwords. For example, if the user has a password of "paSsWoRD", the only way to determine that via NTLM is to submit a value of "paSsWoRD". With LM we can simply send "password". It may also be possible to modify Samba to only do LM, so that whole mixed-case password thing can be ignored.

Unfortunately, LM authentication is not without its problems. If a password attempt is reported as failed, it could mean one of at least three different things:

* The password is indeed wrong.
* No LM hash is stored for that account.
* The GPO Network Security: LAN Manager authentication level is set as one of the following:
- Send NTLMv2 response only\refuse LM (Level 4)
- Send NTLMv2 response only\refuse LM & NTLM (Level 5)

In both of the two later cases, the password may be correct, but we won't know it. I've found no remote and anonymous way of determining the LAN Manager authentication level. My assumption was that it'd be revealed during the protocol negotiation, but that doesn't seem to be the case.
NTLM* The module will send only a NTLMv1 response. This method is the most tested option and the current default. It should work in the majority of cases, with the notable exception of when the GPO Network Security: LAN Manager authentication level is set to "Send NTLMv2 response only\refuse LM & NTLM (Level 5)".
LMv2 This option leverages the LMv2 response algorithm. The LMv2 response is used to provide pass-through authentication compatibility with older servers. The response is based on the NTLM password hash and is exactly 24 bytes. It appears that this method works against the majority of Microsoft Windows operating systems (e.g. NT 4, 2000, 2003, XP, Vista and 2008). It will likely become the default method in future releases.
NTLMv2 This option enforces the use of the NTLMv2 response algorithm. Support for this algorithm was added with Microsoft Windows with NT 4.0 SP4. It should be noted that the method doesn't currently work with Microsoft Vista. While NTLMv2 authentication with Samba and Windows 2003 functions as expected, Vista systems respond with the oh-so-helpful "INVALID_PARAMETER" error code. LMv2 authentication is recommended in cases where LM and NTLM are refused.
GROUP LOCAL* Check local account.
DOMAIN Check credentials against this hosts primary domain controller via this host.
BOTH Check both. This leaves the workgroup field set blank and then attempts to check the credentials against the host. If the account does not exist locally on the host being tested, that host then queries its domain controller.
GROUP_OTHER [user specified] Configure arbitrary domain for host to authenticate against.
PASS PASSWORD* Use a normal password.
HASH Use a LM or NTLM hash rather than a password.
MACHINE Use the Machine's NetBIOS name as the password.
NETBIOS Force NetBIOS Mode (Disable Native Win2000 Mode)
  (*) Default value

The following examples demonstrate several uses of the SMBNT module:

  • The default behavior is to test NATIVE Win2000 mode via TCP/445. If this connection fails, NETBIOS mode is checked on TCP/139. The following shows how to force the module into NETBIOS module.
    
    % medusa -h 192.168.0.20 -u administrator -e ns -M smbnt -m NETBIOS -n 139 
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password:  (1/2)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: administrator (2/2)
    
  • The following example shows how to force to module to set a domain value other than either "localhost" or the system's default domain. This can be useful when testing trust relationships between domains.
    
    % medusa -h 192.168.0.20 -u foo -p bar -M smbnt -m GROUP_OTHER:FOODOM
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks 
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: foo (1/1) Password: bar (1/1)
    
  • This example demonstrates one way that PwDump output could be used with Medusa. Each user and their respective NTLM hash within the pwdump.txt file will be tested against the hosts listed in hosts.txt.
    
    % medusa -H hosts.txt -C pwdump.txt -M smbnt -m PASS:HASH
    
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/10) User: Administrator (1/3) Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: (1/1)
    ACCOUNT FOUND: [smbnt] Host: 192.168.0.20 User: Administrator Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: [SUCCESS]
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/10) User: bar (2/3) Password: 49D58563113416EBAAD3B435B51404EE:AA3AFE73B6E0C2D87B3A428BF696AE71::: (1/1)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/10) User: foo (3/3) Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: (1/1)
    ACCOUNT FOUND: [smbnt] Host: 192.168.0.20 User: foo Password: 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: [SUCCESS]
    < snip >
    
    It should be noted that once a valid hash is located, it is often not necessary to "crack" the password in order to use it. Using a modified SAMBA client, the hash can just be "passed" directly. See this page for a SAMBA patch and several examples.

Be careful of mass domain account lockout with this module. For example, assume you are checking several accounts against many domain workstations. If you are using either the "GROUP:DOMAIN" or the "GROUP:BOTH" option and these accounts do not exist locally on the workstations, each workstation will in turn check their respective domain controller. This could cause a bunch of lockouts. Of course, it'd look like the workstations, not you, were doing it. ;)

FYI, this code is unable to test accounts on default XP hosts which are not part of a domain and do not have normal file sharing enabled. Default XP does not allow shares and returns STATUS_LOGON_FAILED for both valid and invalid credentials. XP with simple sharing enabled returns SUCCESS for both valid and invalid credentials. If anyone knows a way to test in these configurations...

The following is a basic speed test performed against several virtual machines. The test utilized a 5000 entry dictionary with the correct value at line 4998. The cell value reflects the observed average number of password attempts per second.

TARGET OS/AUTH LEVEL 2000 XP 2003 Vista 2008
LM 345.1 t/s 796.1 t/s 125.6 t/s 655 t/s* 379.3 t/s*
NTLM 357.1 t/s 821.0 t/s 140.6 t/s 546.2 t/s 373.2 t/s
LMv2 338.2 t/s 801.1 t/s 164.5 t/s 637.3 t/s 371.9 t/s
NTLMv2 364.1 t/s 812.2 t/s 165.4 t/s - -

* Did not find password in LM mode, since no LM hash is stored in default install of Vista/2008.
- Authentication failed with "INVALID_PARAMETER" response.

A potential timing-based attack was also observed during testing with 2008. It takes roughly 13 seconds to check 5000 passwords against a valid account. It takes only about 6 seconds to test the same number against a non-existant account.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-smtp-vrfy.html000066400000000000000000000016431460263104500224540ustar00rootroot00000000000000 Foofus Networking Services - Medusa::SMTP-VRFY

Medusa Parallel Network Login Auditor :: SMTP-VRFY

JoMo-Kun / jmk "AT" foofus "DOT" net

The SMTP-VRFY module can be used to enumerate which accounts are valid on a mail server. The module sends the following:

EHLO some_name
VRFY account@domain

The module expects the accounts to be checked to be supplied via the user options (-u/-U/-C). The domain should be supplied as if it were a password. The value sent via the EHLO command can be set using the -m EHLO: module option. The default is to send MEDUSA.

This module was written while testing a single mis-configured SMTP SPAM filter. Other devices probably behave differently. Some tweaking of the module may be required.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-smtp.html000066400000000000000000000005531460263104500214670ustar00rootroot00000000000000 Foofus Networking Services - Medusa::SMTP-AUTH

Medusa Parallel Network Login Auditor :: SMTP-AUTH

JoMo-Kun / jmk "AT" foofus "DOT" net

Brute force module for SMTP Authentication with TLS (STARTTLS extension).

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-snmp.html000066400000000000000000000030251460263104500214560ustar00rootroot00000000000000 Foofus Networking Services - Medusa::SNMP

Medusa Parallel Network Login Auditor :: SNMP

JoMo-Kun / jmk "AT" foofus "DOT" net

The SNMP module tests community strings against the Simple Network Management Protocol (SNMP) service.

The module has several options: TIMEOUT, VERSION and ACCESS. The default values are 2 seconds, version 1 and READ access. It should be noted that when testing for WRITE capability, the module will read the current value of sysLocation and then write that same value back to the system.

Since SNMP is a UDP-based protocol, there is no handshaking between sending and receiving transport-layer entities. Due to this connectionless communication, about the only time we know a SNMP service exists, is if we send the correct community string and the server sends a response. All other queries result in no response whatsoever. The approach we use here is to initially just send all of our SNMP GET requests. After that completes, we wait TIMEOUT seconds for any responses. If we get any responses back, we examine them to see which community strings were successful. If ACCESS:WRITE was specified, we check for write access on each of the previously successful values. This techique should allow for quick brute forcing. However, one should take care with the TIMEOUT and SEND_DELAY values as to avoid causing issues with the target service or missing response data.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-ssh.html000066400000000000000000000052721460263104500213040ustar00rootroot00000000000000 Foofus Networking Services - Medusa::SSH

Medusa Parallel Network Login Auditor :: SSH

JoMo-Kun / jmk "AT" foofus "DOT" net

The SSH module tests accounts against SSH service using SSH version 2. The module currently supports brute-forcing SSH Keyboard-interactive and Password authentication modes.

This module requires libssh2 (www.libssh2.org). This is NOT the same as libssh (0xbadc0de.be). It should be noted that the libssh2 library, and therefor, the Medusa SSH module only supports brute-forcing servers which can talk SSH version 2. Libssh2 does not have support for v1 and it looks likely that it never will.

The module has a single option, BANNER. If it's not obvious, this allows you to set the client banner sent during an authentication test. The default value is "SSH-2.0-MEDUSA".

Some notes regarding libssh2... Using the stock libssh2 library, it is likely that the user will encounter hung module threads when running Medusa. This problem is due to libssh2's libssh2_session_startup() not always returning. The cause of this hang within libssh2, I believe, stems from the SSH servers being tested getting pissed and not sending back a banner. The default behavior for OpenSSH is to allow only 10 unauthenticated connections and ignore everything else. While we weren't always running 10 threads in our tests, our threads may have been hitting it faster than it could clean up the previous connections...

This issue has been dealt with in two ways:

  • libssh2 waits forever for the ssh server to respond with a banner. This causes our threads to wait forever, which kinda blows. I've added a patch to libssh2 in the /misc directory which causes it to count to 1000 and then stop waiting. This minor patch has been submitted to the libssh2 folks and a fix will hopefully be included in a future release.
  • We now loop around the libssh2_session_startup() call. This function will fail if libssh2 was unable to negotiate a SSH session. We give it 5 shots to pass and sleep a user configurable time between each. If we fail after 5 attempts, we display that this happened and identify the host/user/pass combination that was not tested.

** As of libssh2 0.18 (devel), this issue appears to be resolved. **

It should be noted that while you can run many threads of SSH, more is not always better. As you increase past 10, you will notice the module having to retry the startup() function.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-svn.html000066400000000000000000000013131460263104500213050ustar00rootroot00000000000000 Foofus Networking Services - Medusa::SVN

Medusa Parallel Network Login Auditor :: SVN

JoMo-Kun / jmk "AT" foofus "DOT" net

The SVN module tests accounts against the Subversion (SVN) service.

This module requires the svn_client-1 library to be installed. This should have been installed as part of Subversion.

The module has a single option, BRANCH. This allows the user to specify the target SVN URL. For example, svn://host/branch. If the option is not set, the default behaviour is to use trunk.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-telnet.html000066400000000000000000000016041460263104500217750ustar00rootroot00000000000000 Foofus Networking Services - Medusa::TELNET

Medusa Parallel Network Login Auditor :: TELNET

JoMo-Kun / jmk "AT" foofus "DOT" net

The TELNET module tests accounts against the TELNET service. This module supports both telnet (23) and telnets (992).

The module currently has a single option, MODE. MODE can either be NORMAL (default) or AS400. The AS400 mode supports basic AS/400 tn5250 connections. This approach allows for more descriptive error messages than FTP when testing against an AS/400. However, POP3, if available on the AS/400, is still a better brute-force option.

The Telnet module will output to the log file hosts that were found to only have a password prompt. This may be useful when scanning for use, or lack of, AAA.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-vmauthd.html000066400000000000000000000006641460263104500221570ustar00rootroot00000000000000 Foofus Networking Services - Medusa::VMAUTHD

Medusa Parallel Network Login Auditor :: VMWAUTHD

JoMo-Kun / jmk "AT" foofus "DOT" net

The VMWAUTHD module tests accounts against the VMware Authentication Daemon. It supports both non-SSL and SSL encrypted installations of the service.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-vnc.html000066400000000000000000000016611460263104500212730ustar00rootroot00000000000000 Foofus Networking Services - Medusa::VNC

Medusa Parallel Network Login Auditor :: VNC

JoMo-Kun / jmk "AT" foofus "DOT" net

The VNC module tests accounts against the VNC service.

This module was developed using both RealVNC and UltraVNC, which support rudimentary anti-brute force functionality. RealVNC, for example, allows 5 failed attempts and then enforces a 10 second delay. For each subsequent attempt that delay is doubled. UltraVNC appears to allow 6 invalid attempts and then forces a 10 second delay between each following attempt. This module attempts to identify these situations and react appropriately by invoking sleep(). The user can set a sleep limit when brute forcing RealVNC using the MAXSLEEP parameter. Once this value has been reached, the module will exit.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-web-form.html000066400000000000000000000006451460263104500222240ustar00rootroot00000000000000 Foofus Networking Services - Medusa::Web-Form

Medusa Parallel Network Login Auditor :: Web-Form

JoMo-Kun / jmk "AT" foofus "DOT" net

Basic web form brute force module which handles GET/POST requests. Supports customizable submit parameters and server response text.

Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa-wrapper.html000066400000000000000000000027121460263104500221630ustar00rootroot00000000000000 Foofus Networking Services - Medusa::Wrapper

Medusa Parallel Network Login Auditor :: Wrapper

JoMo-Kun / jmk "AT" foofus "DOT" net

The purpose of the wrapper module is to allow the user to execute arbitrary scripts while taking advantage of Medusa managing hosts/users/passwords. Two sample scripts have been included in the wrapper directory.

This is a work in progress... The module currently uses fork() which isn't ideal. Not sure if I can kick off a thread and redirect STDIN/STDOUT for just that thread...

The initial goal for this module was to test RDP servers using rdesktop. A patch to rdesktop 1.4.1 has been included in the /misc/rdesktop directory. This extends the dictionary patch from cqure.net to work with the Medusa wrapper STDIN method. It should be noted that rdesktop doesn't appear to be able to use command-line passwords when connecting to Windows 2000 hosts. Windows 2003 and XP worked fine during testing.

The following example shows one way to use rdesktop with the wrapper module:

medusa -M wrapper -m TYPE:STDIN -m PROG:rdesktop -m ARGS:"-u %U -p - %H" -H hosts.txt -U users.txt -P passwords.txt

One possible method for hiding the graphical output from rdesktop:
% Xvfb :97 -ac -nolisten tcp &
% export DISPLAY=:97


Medusa Documentation
jmk-foofus-medusa-dd62069/docs/medusa.1000066400000000000000000000147501460263104500177060ustar00rootroot00000000000000.TH MEDUSA 1 .SH NAME MEDUSA \- Parallel Network Login Auditor .SH SYNOPSIS .B medusa [-h host|-H file] [-u username|-U file] [-p password|-P file] [-C file] -M module [OPTIONS] .SH DESCRIPTION .I Medusa is intended to be a speedy, massively parallel, modular, login brute-forcer. The goal is to support as many services which allow remote authentication as possible. The author considers following items to some of the key features of this application: *Thread-based parallel testing. Brute-force testing can be performed against multiple hosts, users or passwords concurrently. *Flexible user input. Target information (host/user/password) can be specified in a variety of ways. For example, each item can be either a single entry or a file containing multiple entries. Additionally, a combination file format allows the user to refine their target listing. *Modular design. Each service module exists as an independent .mod file. This means that no modifications are necessary to the core application in order to extend the supported list of services for brute-forcing. .SH OPTIONS .TP .B \-h [TARGET] Target hostname or IP address. .TP .B \-H [FILE] Reads target specifications from the file specified rather than from the command line. The file should contain a list separated by newlines. .TP .B \-u [TARGET] Target username. .TP .B \-U [FILE] Reads target usernames from the file specified rather than from the command line. The file should contain a list separated by newlines. .TP .B \-p [TARGET] Target password. .TP .B \-P [FILE] Reads target passwords from the file specified rather than from the command line. The file should contain a list separated by newlines. .TP .B \-C [FILE] File containing combo entries. Combo files are colon separated and in the following format: host:user:password. If any of the three fields are left empty, the respective information should be provided either as a single global value or as a list in a file. The following combinations are possible in the combo file: 1.) foo:bar:fud 2.) foo:bar: 3.) foo:: 4.) :bar:fud 5.) :bar: 6.) ::fud 7.) foo::fud Medusa also supports using PwDump files as a combo file. The format of these files should be user:id:lm:ntlm:::. We look for ':::' at the end of the first line to determine if the file contains PwDump output. .TP .B \-O [FILE] File to append log information to. Medusa will log all accounts credentials found to be valid or cause an unknown error. It will also log the start and stop times of an audit, along with the calling parameters. .TP .B \-e [n/s/ns] Additional password checks ([n] No Password, [s] Password = Username). If both options are being used, they should be specified together ("-e ns"). If only a single option is being called use either "-e n" or "-e s". .TP .B \-M [TEXT] Name of the module to execute (without the .mod extension). .TP .B \-m [TEXT] Parameter to pass to the module. This can be passed multiple times with a different parameter each time and they will all be sent to the module (i.e. -m Param1 -m Param2, etc.) .TP .B \-d Dump all known modules. .TP .B \-n [NUM] Use for non-default TCP port number. .TP .B \-s Enable SSL. .TP .B \-g [NUM] Give up after trying to connect for NUM seconds (default 3). .TP .B \-r [NUM] Sleep NUM seconds between retry attempts (default 3). .TP .B \-R [NUM] Attempt NUM retries before giving up. The total number of attempts will be NUM + 1. .TP .B \-c [NUM] Set the number of usec that are waited during a test of the established network socket. Some services (e.g. FTP, IMAP, POP3, and SMTP) may be configured to drop connections after an arbitrary number of failed logon attempts. We try to reuse the established connection to send authentication attempts until this disconnect occurs, at which point the connection is reestablished. To accomplish this, we check the socket to see if it's still alive before authenticating within select modules. The default is perform a 1 usec check. It may be necessary to specify much larger values. For example, a 1000 usec was needed against our test vsftp server to avoid issues with its built-in anti-bruteforce mechanisms. .TP .B \-t [NUM] Total number of logins to be tested concurrently. It should be noted that roughly t x T threads could be running at any one time. 381 appears to be the limit on my fairly boring Gentoo Linux host. .TP .B \-T [NUM] Total number of hosts to be tested concurrently. .TP .B \-L Parallelize logins using one username per thread. The default is to process the entire username before proceeding. .TP .B \-f Stop scanning host after first valid username/password found. .TP .B \-F Stop audit after first valid username/password found on any host. .TP .B \-b Suppress startup banner .TP .B \-q Display module's usage information. This should be used in conjunction with the "-M" option. For example, "medusa -M smbnt -q". .TP .B \-v [NUM] Verbose level [0 - 6 (more)]. All messages at or below the specified level will be displayed. The default level is 5. The following is the breakdown of the verbose levels: 0) EXIT APPLICATION 1) MESSAGE WITHOUT TAG 2) LOG MESSAGE WITHOUT TAG 3) IMPORTANT MESSAGE 4) ACCOUNT FOUND 5) ACCOUNT CHECK 6) GENERAL MESSAGE .TP .B \-w [NUM] Error debug level [0 - 10 (more)]. All messages at or below the specified level will be displayed. The default level is 5. The following is the breakdown of the error levels: 0) FATAL 1) ALERT 2) CRITICAL 3) ERROR 4) WARNING 5) NOTICE 6) INFO 7) DEBUG 8) DEBUG - AUDIT 9) DEBUG - SERVER 10) DEBUG - MODULE .TP .B \-V Display version .TP .B \-Z [TEXT] Allows basic resuming of a previous scan. The supplied parameter describes which hosts were completed, which were partially tested and which had not been started. When Medusa receives a SIGINT, it will calculate and display a "resume map". This map can then be supplied to the next run. For example, "medusa [OPTIONS PREVIOUSLY USED] -Z h6u1u2h8.". In this particular example, hosts 1-5 were completed, host 6 was partially done (user 1 was partially completed and user 2 and beyond had not been started), host 7 was completed and host 8 and beyond had not been started. Medusa will parse this map and skip hosts and users accordingly. It should be noted that only host and user-level, not password-level, resuming is supported. If a user had been previously started, but was not completed, it will be tested from the start of its respective password list. .SH AUTHOR JoMo-Kun fizzgig .SH BUGS Found a bug? Feel free to send in a patch. jmk-foofus-medusa-dd62069/docs/medusa.html000066400000000000000000000537121460263104500205130ustar00rootroot00000000000000 Foofus Networking Services - Medusa

Medusa Parallel Network Login Auditor

JoMo-Kun / jmk "AT" foofus "DOT" net

What?

Medusa is intended to be a speedy, massively parallel, modular, login brute-forcer. The goal is to support as many services which allow remote authentication as possible. The author considers following items as some of the key features of this application:

  • Thread-based parallel testing. Brute-force testing can be performed against multiple hosts, users or passwords concurrently.
  • Flexible user input. Target information (host/user/password) can be specified in a variety of ways. For example, each item can be either a single entry or a file containing multiple entries. Additionally, a combination file format allows the user to refine their target listing.
  • Modular design. Each service module exists as an independent .mod file. This means that no modifications are necessary to the core application in order to extend the supported list of services for brute-forcing.

Why?

Why create Medusa? Isn't this the same thing as THC-Hydra? Here are some of the reasons for this application:

  • Application stability. Maybe I'm just lame, but Hydra frequently crashed on me. I was no longer confident that Hydra was actually doing what it claimed to be. Rather than fix Hydra, I decided to create my own buggy application which could crash in new and exciting ways.
  • Code organization. A while back I added several features to Hydra (parallel host scanning, SMBNT module). Retro-fitting the parallel host code to Hydra was a serious pain. This was mainly due to my coding ignorance, but was probably also due to Hydra not being designed from the ground-up to support this. Medusa was designed from the start to support parallel testing of hosts, users and passwords.
  • Speed. Hydra accomplishes its parallel testing by forking off a new process for each host and instance of the service being tested. When testing many hosts/users at once this creates a large amount of overhead as user/password lists must be duplicated for each forked process. Medusa is pthread-based and does not unnecessarily duplicate information.
  • Education. I am not an experienced C programmer, nor do I consider myself an expert in multi-threaded programming. Writing this application was a training exercise for me. Hopefully, the results of it will be useful for others.

For a quick comparison of Medusa, Ncrack, and THC-Hydra see: medusa-compare.html

How?

How do I use this thing? Simply running "medusa" without any options will dump all the parameters it accepts along with their respective description. Here are several example uses:

  • Display all modules currently installed:
    % medusa -d
     
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
      Available modules in "." :
      Available modules in "/usr/local/lib/medusa/modules" :
        + mssql.mod :
          Brute force module for M$-SQL sessions : version 0.1.0
        + http.mod :
          Brute force module for HTTP : version 0.1.1
        + ssh.mod :
          Brute force module for SSH v2 sessions : version 0.1.1
        + smbnt.mod :
          Brute force module for SMB/NTLMv1 sessions : version 0.1.1
        + telnet.mod :
          Brute force module for telnet sessions : version 0.1.4
    
  • Display specific options for a given module:
    % medusa -M smbnt -q 
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    smbnt.mod (0.1.1) JoMo-Kun :: Brute force module for SMB/NTLMv1 sessions
    
    Available module options:
      GROUP:? (DOMAIN, LOCAL*, BOTH)
        Option sets NetBIOS workgroup field.
        DOMAIN: Check credentials against this hosts primary domain controller via this host.
        LOCAL:  Check local account.
        BOTH:   Check both. This leaves the workgroup field set blank and then attempts to check
                the credentials against the host. If the account does not exist locally on the
                host being tested, that host then queries its domain controller.
      GROUP_OTHER:?
        Option allows manual setting of domain to check against. Use instead of GROUP.
      PASS:?  (PASSWORD*, HASH, MACHINE)
        PASSWORD: Use normal password.
        HASH:     Use a NTLM hash rather than a password.
        MACHINE:  Use the machine's NetBIOS name as the password.
      NETBIOS
        Force NetBIOS Mode (Disable Native Win2000 Mode). Win2000 mode is the default.
        Default mode is to test TCP/445 using Native Win2000. If this fails, module will
        fall back to TCP/139 using NetBIOS mode. To test only TCP/139, use the following:
        medusa -M smbnt -m NETBIOS -n 139
    
    (*) Default value
    Usage example: "-M smbnt -m GROUP:DOMAIN -m PASS:HASH"
    
  • The following command instructs Medusa to test all passwords listed in passwords.txt against a single user (administrator) on the host 192.168.0.20 via the SMB service. The "-e ns" instructs Medusa to additionally check if the administrator account has either a blank password or has its password set to match its username (administrator).
    
    % medusa -h 192.168.0.20 -u administrator -P passwords.txt -e ns -M smbnt
    
    Medusa v1.0-rc1 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks
    
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password:  (1/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: administrator (2/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: password (3/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass1 (4/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass2 (5/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass3 (6/7)
    ACCOUNT CHECK: [smbnt] Host: 192.168.0.20 (1/1) User: administrator (1/1) Password: pass4 (7/7)
    
  • The below command-line demonstrates how to execute some of the parallel features of Medusa. Here at least 20 hosts and 10 users are tested concurrently. The "-L" options instructs Medusa to parallelize by user. This means each of the 10 threads targeting a host checks a unique user.
    
    % medusa -H hosts.txt -U users.txt -P passwords.txt -T 20 -t 10 -L -F -M smbnt
    
  • Medusa allows host/username/password data to also be set using a "combo" file. The combo file can be specified using the "-C" option. The file should contain one entry per line and have the values colon separated in the format host:user:password. If any of the three fields are left empty, the respective information should be provided either as a global value or as a list in a file. Medusa will perform a basic parameter check based on the contents of the first line in the file.

    The following combinations are possible in the combo file:

    • host:username:password
    • host:username:
    • host::
    • :username:password
    • :username:
    • ::password
    • host::password

    The following example will check each entry in the file combo.txt
    % medusa -M smbnt -C combo.txt

    The combo.txt file:
    192.168.0.20:administrator:password
    192.168.0.20:testuser:pass
    192.168.0.30:administrator:blah
    192.168.0.40:user1:foopass

    The following example will check each entry in the file combo.txt against the targets listed in hosts.txt
    % medusa -M smbnt -C combo.txt -H hosts.txt

    The combo.txt file:
    :administrator:password
    :testuser:pass
    :administrator:blah
    :user1:foopass

    Medusa also supports using PwDump files as a combo file. The format of these files should be user:id:lm:ntlm:::. We look for ':::' at the end of the first line to determine if the file contains PwDump output.

  • Resume a Medusa scan. Medusa has the ability to resume a scan which was interrupted with a SIGINT signal (e.g. CTRL-C). For example:

    Test interrupted with SIGINT
    % ../medusa -M ssh -H host.txt -U users.txt -p password
    Medusa v2.0 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks

    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: foo (1 of 4, 0 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: administrator (2 of 4, 1 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: jmk (3 of 4, 2 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.1 (1 of 11, 0 complete) User: bar (4 of 4, 3 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 1 complete) User: foo (1 of 4, 0 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 1 complete) User: administrator (2 of 4, 1 complete) Password: password (1 of 1 complete)
    ALERT: Medusa received SIGINT - Sending notification to login threads that we are are aborting.
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 1 complete) User: jmk (3 of 4, 2 complete) Password: password (1 of 1 complete)
    ALERT: To resume scan, add the following to your original command: "-Z h2u3u4h3."

    Interrupted scan being resumed
    % ../medusa -M ssh -H host.txt -U users.txt -p password -Z h2u3u4h3.
    Medusa v2.0 [http://www.foofus.net] (C) JoMo-Kun / Foofus Networks

    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 0 complete) User: jmk (3 of 4, 0 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.11 (2 of 11, 0 complete) User: bar (4 of 4, 1 complete) Password: password (1 of 1 complete)
    ACCOUNT CHECK: [ssh] Host: 192.168.0.15 (3 of 11, 1 complete) User: foo (1 of 4, 0 complete) Password: password (1 of 1 complete)

    The following is a brief discription of the resume map:

    h2u3u4h3.
    +--------- First host which was not 100% completed
      +------- First user for host which was not 100% completed
        +----- First user for host which was not started
          +--- First host which was not started
            +- Map ending mark
    

Module specific details:

Where?

GitHub
Medusa-gui (Java-based GUI developed by tak and bigmoneyhat)

Install Instructions:

General

The majority of Medusa was written and tested on Linux/Gentoo-based systems. While it has been known to work on variety of operating systems, it is quite possible there may be issues that crop up only on non-Gentoo devices. Of course, there are issues that will probably also show up on Gentoo that have so far been missed...

Medusa should be fairly straight-forward to build: "./configure; make; make install". However, this may result in a somewhat limited installation. To take full advantage of all the brute-forcing goodness that Medusa has to offer, several dependencies must be satisfied. The following table lists out the modules which have additional dependencies. In order for the modules to function, the appropriate header files must be installed on the system when the modules themselves are compiled. Additional module specific information is included within the documentation for each module.

Dependency Homepage Module Notes
OpenSSL http://www.openssl.org HTTP, MSSQL, SMBNT, SSL-based connections
LibSMB2 https://github.com/sahlberg/libsmb2 SMBNT (SMBv2 Support) SMBNT module natively supports SMBv1. If libsmb2 is present, it also supports SMBv2/3 and SMB signing.
LibSSH2 http://www.libssh2.org SSH LibSSH2 patch provided to address timing issue. Issue appears to be addressed in 0.18.
NCPFS ftp://platan.vc.cvut.cz/pub/linux/ncpfs NCP Use "make install-dev" to install header files.
LibPQ http://www.postgresql.org PostgreSQL
Subversion http://subversion.tigris.org SVN
afpfs-ng http://alexthepuffin.googlepages.com/home AFP Header files may need to be manually installed. Autoconf currently assumes install base of /usr (e.g. /usr/include/afpfs-ng)

It should also be noted that, by default, not all of the modules are built. Incomplete modules or modules which have not been sufficiently tested may be disabled. The "configure" output should identify which modules it will attempt to build. To enable non-default modules, use the "--enable-module-MODULE_NAME" configure option.

Linux/Gentoo

At this time Medusa is not available within Portage. An ebuild for Medusa has been submitted to bugs.gentoo.org, but has not yet made its way into Portage. In the meantime, all of the ebuilds can be used via Portage Overlay. For example, Medusa can be installed via the Gentoo "pentoo" overlay located at trac.pentoo.ch. Additionally, the ebuilds have been included and can also be manually installed.

The following ebuilds have been included within this distribution:

  • /misc/net-analyzer/medusa-2.1.ebuild

Some basic Portage Overlay instructions:

  • Modify /etc/make.conf
    PORTDIR_OVERLAY="/some/directory/"
  • Create the following within the PORTDIR_OVERLAY directory:
    net-analyzer/medusa
  • Place each ebuild and any accompanying files in its respective PORTDIR_OVERLAY directory.
    cd into each directory and execute:
    ebuild name_of_ebuild.ebuild digest
  • Modify /etc/portage/package.keywords
    net-analyzer/medusa ~x86

Mac OS X

First download the source code and change to the Medusa directory:

git clone https://github.com/jmk-foofus/medusa
cd medusa
Also install the needed dependencies using Homebrew:
brew cask install xquartz
brew install freerdp
Then add the Freerdp path for executing the configuration without issues:
$ export FREERDP2_CFLAGS='-I/usr/local/include'
$ export FREERDP2_LIBS='-I/usr/local/lib/freerdp'
Then build things: Note: Update OpenSSL include based on system configuration.
./configure --with-ssl=/usr/local/homebrew/Cellar/openssl@3/3.2.1/
make && make install
Then copy the binary to your binaries folder
sudo cp src/medusa  /usr/local/bin
Now you can start using Medusa:
medusa

Other Systems

Medusa has been built and basic tests performed on a variety of default system installations. The following tables includes some notes from these tests.

Medusa v2.3
Operating System Distro/Version Notes
Linux BackBox 8.1 Installed: automake, libssl-dev, libpq5, libpq-dev, libsmb2, libssh2-1, libssh2-1-dev, libsvn-dev, freerdp2-dev
Debian Sid (64-bit) Installed: build-essential, automake, libssl-dev, libpq5, libpq-dev, libsmb2, libssh2-1, libssh2-1-dev, libsvn-dev, freerdp2-dev
Fedora 23 Installed: "Development Tools", automake, afpfs-ng-devel, libssh2-devel, libpq-devel, subversion-devel, freerdp-devel
Kali 2024.1 (64-bit) Installed: automake, libssl-dev, libpq5, libpq-dev, libsmb2, libssh2-1, libssh2-1-dev, libsvn-dev, freerdp2-dev
Ubuntu 22.04 (64-bit, WSL) Installed: build-essential, automake, libssl-dev, libpq5, libpq-dev, libsmb2, libssh2-1, libssh2-1-dev, libsvn-dev, freerdp2-dev
Medusa v2.2 and earlier
Operating System Distro/Version Notes
Linux CentOS 7.1 (64-bit) Installed: "Development Tools", openssl-devel, libssh2-devel, postgresql-devel, subversion-devel, freerdp-devel
Debian 8.0.0 (64-bit) Installed: build-essential, libssl-dev, libpq5, libpq-dev, libssh2-1, libssh2-1-dev, libsvn-dev, freerdp, libfreerdp-dev, libncp, libncp-dev
Fedora 21 Installed: "Development Tools", afpfs-ng-devel, openssl-devel, libssh2-devel, postgresql-devel, subversion-devel, freerdp-devel
Kali 2020.4 (64-bit) [WSL] Installed: build-essential, autoconf, libssl-dev, libpq5, libpq-dev, libssh2-1, libssh2-1-dev, libgnutls28-dev, libsvn-dev, freerdp2-dev
Mint 17 Installed: build-essential, libssl-dev, libpq5, libpq-dev, libssh2-1, libssh2-1-dev, libgcrypt11-dev, libgnutls-dev, libsvn-dev, freerdp, libfreerdp-dev
openSUSE 11.2 Installed: patterns-openSUSE-devel_C_C++, ncpfs-devel, libssh2-devel, postgresql-devel, subversion-devel
Ubuntu 20.04 Installed: build-essential, autoconf, libssl-dev, libpq5, libpq-dev, libssh2-1, libssh2-1-dev, libgnutls28-dev, libsvn-dev, freerdp2-dev
SunOS Solaris 11 x86 Installed: developer-gnu
BSD FreeBSD 7.2 Installed: afpfs-ng, ncpfs, libssh2, postgresql, libpq, libsvn
Mac OS X OS X 10.11 (El Capitan) Installed: Homebrew, XCode, "brew install freerdp --HEAD", "brew install libssh2 postgresql subversion"
Microsoft Windows Cygwin I have been unable to build the modules under Cygwin. If anyone can figure this out, I'll buy you a beer at the next DefCon.

Who?

This fine piece of buggy software was brought to you by the geeks at Foofus.net. JoMo-Kun was the chief goon and wrote the core of Medusa along with several of the modules. Foofus created the initial design for the loadable modules. Fizzgig provided the networking code, several modules, the loadable module implementation along with also fixing a bunch JoMo-Kun's crappy stuff. pMonkey was a crazy module coding fiend. Last, but certainly not least, Heidi provided the tool's name.

Huh?

If you have questions regarding this application, feel free to contact us. Either send me email directly or join our mailing list foofus-tools. If it breaks, please send a detailed bug report. Even better, send in a patch. I make no claims that this program will do what you want it to. I've been using it during our assessments for years now successfully. Hopefully, others will have similar luck. If you find Medusa useful and want to give something back, please submit new modules, code improvements or just buy any of the Foofus.net goons a beer at the next DefCon.

Joe

© Copyright 2024, Foofus Advanced Security Services
any time. any fucknut.
jmk-foofus-medusa-dd62069/install-sh000077500000000000000000000360101460263104500174130ustar00rootroot00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) # Note that $RANDOM variable is not portable (e.g. dash); Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p' feature. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jmk-foofus-medusa-dd62069/ltmain.sh000066400000000000000000005623601460263104500172430ustar00rootroot00000000000000# ltmain.sh - Provide generalized library-building support services. # NOTE: Changing this file will not affect anything until you rerun configure. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. basename="s,^.*/,,g" # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # define SED for historic ltconfig's generated by Libtool 1.3 test -z "$SED" && SED=sed # The name of this program: progname=`echo "$progpath" | $SED $basename` modename="$progname" # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 PROGRAM=ltmain.sh PACKAGE=libtool VERSION=1.5.18 TIMESTAMP=" (1.1220.2.246 2005/05/16 10:00:18)" # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi # Same for EGREP, and just to be sure, do LTCC as well if test "X$EGREP" = X ; then EGREP=egrep fi if test "X$LTCC" = X ; then LTCC=${CC-gcc} fi # Check that we have a working $echo. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell, and then maybe $echo will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE fi # Global variables. mode=$default_mode nonopt= prev= prevopt= run= show="$echo" show_help= execute_dlfiles= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" quote_scanset='[[~#^*{};<>?'"'"' ]' if test -z "$max_cmd_len"; then i=0 testring="ABCD" new_result= # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while (test "X"`$SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \ = "XX$testring") >/dev/null 2>&1 && new_result=`expr "X$testring" : ".*" 2>&1` && max_cmd_len="$new_result" && test "$i" != 17 # 1/2 MB should be enough do i=`expr $i + 1` testring="$testring$testring" done testring= # Add a significant safety factor because C++ compilers can tack on massive # amounts of additional arguments before passing them to the linker. # It appears as though 1/2 is a usable value. max_cmd_len=`expr $max_cmd_len \/ 2` fi ##################################### # Shell function definitions: # This seems to be the best place for them # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | \ sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'` if test "X$win32_nmres" = "Ximport" ; then win32_libid_type="x86 archive import" else win32_libid_type="x86 archive static" fi fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $echo $win32_libid_type } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac CC_quoted="$CC_quoted $arg" done # user sometimes does CC=-gcc so we need to match that to 'gcc' trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"` # and sometimes libtool has CC=-gcc but user does CC=gcc extendcc=${host}-${CC} case "$@ " in "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\ "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*) tagname=CC break ;; "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\ "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then $echo "$modename: unable to infer tagged configuration" $echo "$modename: specify a tag with \`--tag'" 1>&2 exit $EXIT_FAILURE # else # $echo "$modename: using $tagname tagged configuration" fi ;; esac fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)" $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $? if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2 exit $EXIT_FAILURE fi } # func_extract_archives gentop oldlib ... func_extract_archives () { my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" my_status="" $show "${rm}r $my_gentop" $run ${rm}r "$my_gentop" $show "$mkdir $my_gentop" $run $mkdir "$my_gentop" my_status=$? if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then exit $my_status fi for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'` my_xdir="$my_gentop/$my_xlib" $show "${rm}r $my_xdir" $run ${rm}r "$my_xdir" $show "$mkdir $my_xdir" $run $mkdir "$my_xdir" status=$? if test "$status" -ne 0 && test ! -d "$my_xdir"; then exit $status fi case $host in *-darwin*) $show "Extracting $my_xabs" # Do not bother doing anything if just a dry run if test -z "$run"; then darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'` darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null` if test -n "$darwin_arches"; then darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= $show "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}" lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we have a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` lipo -create -output "$darwin_file" $darwin_files done # $darwin_filelist ${rm}r unfat-$$ cd "$darwin_orig_dir" else cd "$darwin_orig_dir" func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches fi # $run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # End of Shell function definitions ##################################### # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Parse our command line options once, thoroughly. while test "$#" -gt 0 do arg="$1" shift case $arg in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in execute_dlfiles) execute_dlfiles="$execute_dlfiles $arg" ;; tag) tagname="$arg" preserve_args="${preserve_args}=$arg" # Check whether tagname contains only valid characters case $tagname in *[!-_A-Za-z0-9,/]*) $echo "$progname: invalid tag name: $tagname" 1>&2 exit $EXIT_FAILURE ;; esac case $tagname in CC) # Don't test for the "default" C tag, as we know, it's there, but # not specially marked. ;; *) if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then taglist="$taglist $tagname" # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`" else $echo "$progname: ignoring unknown tag $tagname" 1>&2 fi ;; esac ;; *) eval "$prev=\$arg" ;; esac prev= prevopt= continue fi # Have we seen a non-optional argument yet? case $arg in --help) show_help=yes ;; --version) $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" $echo $echo "Copyright (C) 2005 Free Software Foundation, Inc." $echo "This is free software; see the source for copying conditions. There is NO" $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." exit $? ;; --config) ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath # Now print the configurations for the tags. for tagname in $taglist; do ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath" done exit $? ;; --debug) $echo "$progname: enabling shell trace mode" set -x preserve_args="$preserve_args $arg" ;; --dry-run | -n) run=: ;; --features) $echo "host: $host" if test "$build_libtool_libs" = yes; then $echo "enable shared libraries" else $echo "disable shared libraries" fi if test "$build_old_libs" = yes; then $echo "enable static libraries" else $echo "disable static libraries" fi exit $? ;; --finish) mode="finish" ;; --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; --preserve-dup-deps) duplicate_deps="yes" ;; --quiet | --silent) show=: preserve_args="$preserve_args $arg" ;; --tag) prevopt="--tag" prev=tag ;; --tag=*) set tag "$optarg" ${1+"$@"} shift prev=tag preserve_args="$preserve_args --tag" ;; -dlopen) prevopt="-dlopen" prev=execute_dlfiles ;; -*) $echo "$modename: unrecognized option \`$arg'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *) nonopt="$arg" break ;; esac done if test -n "$prevopt"; then $echo "$modename: option \`$prevopt' requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2 $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2 case $nonopt in *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*) mode=link for arg do case $arg in -c) mode=compile break ;; esac done ;; *db | *dbx | *strace | *truss) mode=execute ;; *install*|cp|mv) mode=install ;; *rm) mode=uninstall ;; *) # If we have no mode, but dlfiles were specified, then do execute mode. test -n "$execute_dlfiles" && mode=execute # Just use the default operation mode. if test -z "$mode"; then if test -n "$nonopt"; then $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 else $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 fi fi ;; esac fi # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then $echo "$modename: unrecognized option \`-dlopen'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. case $mode in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= for arg do case "$arg_mode" in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) if test -n "$libobj" ; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 exit $EXIT_FAILURE fi arg_mode=target continue ;; -static | -prefer-pic | -prefer-non-pic) later="$later $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac lastarg="$lastarg $arg" done IFS="$save_ifs" lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` # Add the arguments to base_compile. base_compile="$base_compile $lastarg" continue ;; * ) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` case $lastarg in # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly # in scan sets, and some SunOS ksh mistreat backslash-escaping # in scan sets (worked around with variable expansion), # and furthermore cannot handle '|' '&' '(' ')' in scan sets # at all, so we specify them separately. *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") lastarg="\"$lastarg\"" ;; esac base_compile="$base_compile $lastarg" done # for arg case $arg_mode in arg) $echo "$modename: you must specify an argument for -Xcompile" exit $EXIT_FAILURE ;; target) $echo "$modename: you must specify a target with \`-o'" 1>&2 exit $EXIT_FAILURE ;; *) # Get the name of the library object. [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSifmso]' case $libobj in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; *.asm) xform=asm ;; *.c++) xform=c++ ;; *.cc) xform=cc ;; *.ii) xform=ii ;; *.class) xform=class ;; *.cpp) xform=cpp ;; *.cxx) xform=cxx ;; *.f90) xform=f90 ;; *.for) xform=for ;; *.java) xform=java ;; esac libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` case $libobj in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 exit $EXIT_FAILURE ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -static) build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"` case $qlibobj in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qlibobj="\"$qlibobj\"" ;; esac if test "X$libobj" != "X$qlibobj"; then $echo "$modename: libobj name \`$libobj' may not contain shell special characters." exit $EXIT_FAILURE fi objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$obj"; then xdir= else xdir=$xdir/ fi lobj=${xdir}$objdir/$objname if test -z "$base_compile"; then $echo "$modename: you must specify a compilation command" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi $run $rm $removelist trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15 else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $run ln "$srcfile" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $echo "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi $echo "$srcfile" > "$lockfile" fi if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"` case $qsrcfile in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qsrcfile="\"$qsrcfile\"" ;; esac $run $rm "$libobj" "${libobj}T" # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. test -z "$run" && cat > ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then $show "$mv $output_obj $lobj" if $run $mv $output_obj $lobj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the PIC object to the libtool object file. test -z "$run" && cat >> ${libobj}T <> ${libobj}T </dev/null`" != "X$srcfile"; then $echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then $show "$mv $output_obj $obj" if $run $mv $output_obj $obj; then : else error=$? $run $rm $removelist exit $error fi fi # Append the name of the non-PIC object the libtool object file. # Only append if the libtool object file exists. test -z "$run" && cat >> ${libobj}T <> ${libobj}T <&2 fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi else if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi fi build_libtool_libs=no build_old_libs=yes prefer_static_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test ;; *) qarg=$arg ;; esac libtool_args="$libtool_args $qarg" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command="$compile_command @SYMFILE@" finalize_command="$finalize_command @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" if test ! -f "$arg"; then $echo "$modename: symbol file \`$arg' does not exist" exit $EXIT_FAILURE fi prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat $save_arg` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi done else $echo "$modename: link input file \`$save_arg' does not exist" exit $EXIT_FAILURE fi arg=$save_arg prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= compile_command="$compile_command $wl$qarg" finalize_command="$finalize_command $wl$qarg" continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= compile_command="$compile_command $qarg" finalize_command="$finalize_command $qarg" continue ;; shrext) shrext_cmds="$arg" prev= continue ;; darwin_framework) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" prev= continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 continue ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: more than one -exported-symbols argument is not allowed" exit $EXIT_FAILURE fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=darwin_framework compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" ;; esac continue ;; -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 exit $EXIT_FAILURE fi dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$dir:"*) ;; *) dllsearchpath="$dllsearchpath:$dir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-pw32* | *-*-beos*) # These systems don't actually have a C or math library (as such) continue ;; *-*-mingw* | *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs -framework System" continue esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. -model) compile_command="$compile_command $arg" compiler_flags="$compiler_flags $arg" finalize_command="$finalize_command $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) compiler_flags="$compiler_flags $arg" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" continue ;; -module) module=yes continue ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m* pass through architecture-specific compiler args for GCC -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" if test "$with_gcc" = "yes" ; then compiler_flags="$compiler_flags $arg" fi continue ;; -shrext) prev=shrext continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) # The PATH hackery in wrapper scripts is required on Windows # in order for the loader to find any dlls it needs. $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit $EXIT_FAILURE ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -static) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -Wc,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Wl,*) args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" case $flag in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") flag="\"$flag\"" ;; esac arg="$arg $wl$flag" compiler_flags="$compiler_flags $wl$flag" linker_flags="$linker_flags $flag" done IFS="$save_ifs" arg=`$echo "X$arg" | $Xsed -e "s/^ //"` ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; -Kthread | -mthreads | -mt | -pthread | -pthreads | -threads | -qthreaded | -kthread ) compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then pic_object= non_pic_object= # Read the .lo file # If there is no directory component, then add one. case $arg in */* | *\\*) . $arg ;; *) . ./$arg ;; esac if test -z "$pic_object" || \ test -z "$non_pic_object" || test "$pic_object" = none && \ test "$non_pic_object" = none; then $echo "$modename: cannot find name of object for \`$arg'" 1>&2 exit $EXIT_FAILURE fi # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. libobjs="$libobjs $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object non_pic_objects="$non_pic_objects $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi fi else # Only an error if not doing a dry-run. if test -z "$run"; then $echo "$modename: \`$arg' is not a valid libtool object" 1>&2 exit $EXIT_FAILURE else # Dry-run case. # Extract subdirectory from the argument. xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$xdir" = "X$arg"; then xdir= else xdir="$xdir/" fi pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"` non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"` libobjs="$libobjs $pic_object" non_pic_objects="$non_pic_objects $non_pic_object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi done # argument parsing loop if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi oldlibs= # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi # Create the object directory. if test ! -d "$output_objdir"; then $show "$mkdir $output_objdir" $run $mkdir $output_objdir status=$? if test "$status" -ne 0 && test ! -d "$output_objdir"; then exit $status fi fi # Determine the type of output case $output in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac case $host in *cygwin* | *mingw* | *pw32*) # don't eliminate duplications in $postdeps and $predeps duplicate_compiler_generated_deps=yes ;; *) duplicate_compiler_generated_deps=$duplicate_deps ;; esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if test "X$duplicate_deps" = "Xyes" ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 exit $EXIT_FAILURE ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2 continue fi name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then library_names= old_library= case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` ;; *) $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2 ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` if eval $echo \"$deplib\" 2>/dev/null \ | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $echo $echo "*** Warning: Trying to link with static lib archive $deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because the file extensions .$libext of this argument makes me believe" $echo "*** that it is just a static archive that I should not used here." else $echo $echo "*** Warning: Linking the shared library $output against the" $echo "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else $echo "$modename: cannot find the library \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Check to see that this really is a libtool archive. if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` test "X$ladir" = "X$lib" && ladir="." dlname= dlopen= dlpreopen= libdir= library_names= old_library= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then $echo "$modename: \`$lib' is not a convenience library" 1>&2 exit $EXIT_FAILURE fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 exit $EXIT_FAILURE fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 abs_ladir="$ladir" fi ;; esac laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then $echo "$modename: warning: library \`$lib' was moved." 1>&2 dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir"; then $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 exit $EXIT_FAILURE fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath " in *" $dir "*) ;; *" $absdir "*) ;; *) temp_rpath="$temp_rpath $dir" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi # This is a shared library # Warn about portability, can't link against -module's on # some systems (darwin) if test "$shouldnotlink" = yes && test "$pass" = link ; then $echo if test "$linkmode" = prog; then $echo "*** Warning: Linking the executable $output against the loadable module" else $echo "*** Warning: Linking the shared library $output against the loadable module" fi $echo "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names realname="$2" shift; shift libname=`eval \\$echo \"$libname_spec\"` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw*) major=`expr $current - $age` versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" soname=`$echo $soroot | ${SED} -e 's/^.*\///'` newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else $show "extracting exported symbol list from \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$extract_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else $show "generating import library for \`$soname'" save_ifs="$IFS"; IFS='~' cmds=$old_archive_from_expsyms_cmds for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5* ) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a module then we can not link against # it, someone is ignoring the new warnings I added if /usr/bin/file -L $add 2> /dev/null | $EGREP "bundle" >/dev/null ; then $echo "** Warning, lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $echo $echo "** And there doesn't seem to be a static archive available" $echo "** The link will probably fail, sorry" else add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case "$libdir" in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then $echo "$modename: configuration error: unsupported hardcode properties" exit $EXIT_FAILURE fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && \ test "$hardcode_minus_L" != yes && \ test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case "$libdir" in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $echo $echo "*** Warning: This system can not link to static lib archive $lib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $echo "*** But as you try to build a module library, libtool will still create " $echo "*** a static module, that should work as long as the dlopening application" $echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else convenience="$convenience $dir/$old_library" old_convenience="$old_convenience $dir/$old_library" deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if test "X$duplicate_deps" = "Xyes" ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$deplib" && dir="." # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 absdir="$dir" fi ;; esac if grep "^installed=no" $deplib > /dev/null; then path="$absdir/$objdir" else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi if test "$absdir" != "$libdir"; then $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 fi path="$absdir" fi depdepl= case $host in *-*-darwin*) # we do not want to link against static libs, # but need to link against shared eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$path/$depdepl" ; then depdepl="$path/$depdepl" fi # do not add paths which are already there case " $newlib_search_path " in *" $path "*) ;; *) newlib_search_path="$newlib_search_path $path";; esac fi path="" ;; *) path="-L$path" ;; esac ;; -l*) case $host in *-*-darwin*) # Again, we only want to link against shared libraries eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"` for tmp in $newlib_search_path ; do if test -f "$tmp/lib$tmp_libs.dylib" ; then eval depdepl="$tmp/lib$tmp_libs.dylib" break fi done path="" ;; *) continue ;; esac ;; *) continue ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac case " $deplibs " in *" $depdepl "*) ;; *) deplibs="$depdepl $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 fi if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 fi # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) if test "$module" = no; then $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 exit $EXIT_FAILURE else $echo $echo "*** Warning: Linking the shared library $output against the non-libtool" $echo "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi if test "$dlself" != no; then $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 fi set dummy $rpath if test "$#" -gt 2; then $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 fi install_libdir="$2" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 fi else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" if test -n "$8"; then $echo "$modename: too many parameters to \`-version-info'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$2" number_minor="$3" number_revision="$4" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows) current=`expr $number_major + $number_minor` age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) current=`expr $number_major + $number_minor - 1` age="$number_minor" revision="$number_minor" ;; esac ;; no) current="$2" revision="$3" age="$4" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE ;; esac if test "$age" -gt "$current"; then $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit $EXIT_FAILURE fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header major=.`expr $current - $age` versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... minor_current=`expr $current + 1` verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current"; ;; irix | nonstopux) major=`expr $current - $age + 1` case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) major=.`expr $current - $age` versuffix="$major.$age.$revision" ;; osf) major=.`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do iface=`expr $current - $loop` loop=`expr $loop - 1` verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. major=`expr $current - $age` versuffix="-$major" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit $EXIT_FAILURE ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$echo "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done if test -n "$removelist"; then $show "${rm}r $removelist" $run ${rm}r $removelist fi fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. for path in $notinst_path; do lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'` deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'` dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs -framework System" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $rm conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null \ | grep " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done # It is ok to link against an archive when # building a shared library. if $AR -t $potlib > /dev/null 2>&1; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for file magic test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a file magic. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` for a_deplib in $deplibs; do name="`expr $a_deplib : '-l\(.*\)'`" # If $name is empty we are operating on a -L argument. if test -n "$name" && test "$name" != "0"; then if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval \\$echo \"$libname_spec\"` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval $echo \"$potent_lib\" 2>/dev/null \ | ${SED} 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $echo $echo "*** Warning: linker path does not have real file for library $a_deplib." $echo "*** I have the capability to make that library automatically link in when" $echo "*** you link to this library. But I can only do this if you have a" $echo "*** shared version of the library, which you do not appear to have" $echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $echo "*** with $libname but no candidates were found. (...for regex pattern test)" else $echo "*** with $libname and none of the candidates passed a file format test" $echo "*** using a regex pattern. Last file checked: $potlib" fi fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"` done fi if $echo "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' \ | grep . >/dev/null; then $echo if test "X$deplibs_check_method" = "Xnone"; then $echo "*** Warning: inter-library dependencies are not supported in this platform." else $echo "*** Warning: inter-library dependencies are not known to be supported." fi $echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $echo $echo "*** Warning: libtool could not satisfy all declared inter-library" $echo "*** dependencies of module $libname. Therefore, libtool will create" $echo "*** a static module, that should work as long as the dlopening" $echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $echo $echo "*** However, this would only work if libtool was able to extract symbol" $echo "*** lists from a program, using \`nm' or equivalent, but libtool could" $echo "*** not find such a program. So, this module is probably useless." $echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $echo "*** The inter-library dependencies that have been dropped here will be" $echo "*** automatically added whenever a program is linked with this library" $echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $echo $echo "*** Since this library must not contain undefined symbols," $echo "*** because either the platform does not support them or" $echo "*** it was explicitly requested with -no-undefined," $echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names realname="$2" shift; shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" if len=`expr "X$cmd" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then $show "$cmd" $run eval "$cmd" || exit $? skipped_export=false else # The command line is too long to execute in one step. $show "using reloadable object file for export list..." skipped_export=: fi done IFS="$save_ifs" if test -n "$export_symbols_regex"; then $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' $show "$mv \"${export_symbols}T\" \"$export_symbols\"" $run eval '$mv "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise. $echo "creating reloadable object files..." # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$echo "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= delfiles= last_robj= k=1 output=$output_objdir/$output_la-${k}.$objext # Loop over the list of objects to be linked. for obj in $save_libobjs do eval test_cmds=\"$reload_cmds $objlist $last_robj\" if test "X$objlist" = X || { len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len"; }; then objlist="$objlist $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext k=`expr $k + 1` output=$output_objdir/$output_la-${k}.$objext objlist=$obj len=1 fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if ${skipped_export-false}; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols libobjs=$output # Append the command to create the export file. eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\" fi # Set up a command to remove the reloadable object files # after they are used. i=0 while test "$i" -lt "$k" do i=`expr $i + 1` delfiles="$delfiles $output_objdir/$output_la-${i}.$objext" done $echo "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi # Append the command to remove the reloadable object files # to the just-reset $cmds. eval cmds=\"\$cmds~\$rm $delfiles\" fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi case $output in *.lo) if test -n "$objs$old_deplibs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit $EXIT_FAILURE fi libobj="$output" obj=`$echo "X$output" | $Xsed -e "$lo2o"` ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $run $rm $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $run eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" cmds=$reload_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi if test -n "$gentop"; then $show "${rm}r $gentop" $run ${rm}r $gentop fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; esac if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 fi if test "$preload" = yes; then if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." fi fi case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` ;; esac case $host in *darwin*) # Don't allow lazy linking, it breaks C++ global constructors if test "$tagname" = CXX ; then compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" fi ;; esac compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) case :$dllsearchpath: in *":$libdir:"*) ;; *) dllsearchpath="$dllsearchpath:$libdir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then dlsyms="${outputname}S.c" else $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 fi fi if test -n "$dlsyms"; then case $dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${outputname}.nm" $show "$rm $nlist ${nlist}S ${nlist}T" $run $rm "$nlist" "${nlist}S" "${nlist}T" # Parse the name list into a source file. $show "creating $output_objdir/$dlsyms" test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ #ifdef __cplusplus extern \"C\" { #endif /* Prevent the only kind of declaration conflicts we can make. */ #define lt_preloaded_symbols some_other_symbol /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then $show "generating symbol list for \`$output'" test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi if test -n "$export_symbols_regex"; then $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $run $rm $export_symbols $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' else $run eval "${SED} -e 's/\([ ][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' fi fi for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" name=`$echo "$arg" | ${SED} -e 's%^.*/%%'` $run eval '$echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -z "$run"; then # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $mv "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if grep -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' else $echo '/* NONE */' >> "$output_objdir/$dlsyms" fi $echo >> "$output_objdir/$dlsyms" "\ #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ # define lt_ptr void * #else # define lt_ptr char * # define const #endif /* The mapping between symbol names and symbols. */ " case $host in *cygwin* | *mingw* ) $echo >> "$output_objdir/$dlsyms" "\ /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs */ struct { " ;; * ) $echo >> "$output_objdir/$dlsyms" "\ const struct { " ;; esac $echo >> "$output_objdir/$dlsyms" "\ const char *name; lt_ptr address; } lt_preloaded_symbols[] = {\ " eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ {0, (lt_ptr) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " fi pic_flag_for_symtable= case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";; esac;; *-*-hpux*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag";; esac esac # Now compile the dynamic symbol file. $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? # Clean up the generated files. $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" # Transform the symbol file into the correct name. compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ;; *) $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 exit $EXIT_FAILURE ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi if test "$need_relink" = no || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. $show "$link_command" $run eval "$link_command" status=$? # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" $run $rm "$output_objdir/${outputname}S.${objext}" fi exit $status fi if test -n "$shlibpath_var"; then # We should set the shlibpath_var rpath= for dir in $temp_rpath; do case $dir in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" ;; *) # Relative path: add a thisdir entry. rpath="$rpath\$thisdir/$dir:" ;; esac done temp_rpath="$rpath" fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $run $rm $output # Link the executable and exit $show "$link_command" $run eval "$link_command" || exit $? exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname $show "$link_command" $run eval "$link_command" || exit $? # Now create the wrapper script. $show "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if our run command is non-null. if test -z "$run"; then # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) cwrappersource=`$echo ${objdir}/lt-${outputname}.c` cwrapper=`$echo ${output}.exe` $rm $cwrappersource $cwrapper trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 cat > $cwrappersource <> $cwrappersource<<"EOF" #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef DIR_SEPARATOR #define DIR_SEPARATOR '/' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) #define HAVE_DOS_BASED_FILE_SYSTEM #ifndef DIR_SEPARATOR_2 #define DIR_SEPARATOR_2 '\\' #endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) const char *program_name = NULL; void * xmalloc (size_t num); char * xstrdup (const char *string); char * basename (const char *name); char * fnqualify(const char *path); char * strendzap(char *str, const char *pat); void lt_fatal (const char *message, ...); int main (int argc, char *argv[]) { char **newargz; int i; program_name = (char *) xstrdup ((char *) basename (argv[0])); newargz = XMALLOC(char *, argc+2); EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" newargz[1] = fnqualify(argv[0]); /* we know the script has the same name, without the .exe */ /* so make sure newargz[1] doesn't end in .exe */ strendzap(newargz[1],".exe"); for (i = 1; i < argc; i++) newargz[i+1] = xstrdup(argv[i]); newargz[argc+1] = NULL; EOF cat >> $cwrappersource <> $cwrappersource <<"EOF" } void * xmalloc (size_t num) { void * p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL ; } char * basename (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha (name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return (char *) base; } char * fnqualify(const char *path) { size_t size; char *p; char tmp[LT_PATHMAX + 1]; assert(path != NULL); /* Is it qualified already? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha (path[0]) && path[1] == ':') return xstrdup (path); #endif if (IS_DIR_SEPARATOR (path[0])) return xstrdup (path); /* prepend the current directory */ /* doesn't handle '~' */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */ p = XMALLOC(char, size); sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path); return p; } char * strendzap(char *str, const char *pat) { size_t len, patlen; assert(str != NULL); assert(pat != NULL); len = strlen(str); patlen = strlen(pat); if (patlen <= len) { str += len - patlen; if (strcmp(str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char * mode, const char * message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } EOF # we should really use a build-platform specific compiler # here, but OTOH, the wrappers (shell script and this C one) # are only useful if you want to execute the "real" binary. # Since the "real" binary is built for $host, then this # wrapper might as well be built for $host, too. $run $LTCC -s -o $cwrapper $cwrappersource ;; esac $rm $output trap "$rm $output; exit $EXIT_FAILURE" 1 2 15 $echo > $output "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then echo=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then # Yippee, \$echo works! : else # Restart under the correct shell, and then maybe \$echo will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $echo >> $output "\ # Find the directory that this script lives in. thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $echo >> $output "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || \\ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $mkdir \"\$progdir\" else $rm \"\$progdir/\$file\" fi" $echo >> $output "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $echo \"\$relink_command_output\" >&2 $rm \"\$progdir/\$file\" exit $EXIT_FAILURE fi fi $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $rm \"\$progdir/\$program\"; $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } $rm \"\$progdir/\$file\" fi" else $echo >> $output "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $echo >> $output "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $echo >> $output "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $echo >> $output "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $echo >> $output "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2*) $echo >> $output "\ exec \$progdir\\\\\$program \${1+\"\$@\"} " ;; *) $echo >> $output "\ exec \$progdir/\$program \${1+\"\$@\"} " ;; esac $echo >> $output "\ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" exit $EXIT_FAILURE fi else # The program doesn't exist. \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 \$echo \"This script is just a wrapper for \$program.\" 1>&2 $echo \"See the $PACKAGE documentation for more information.\" 1>&2 exit $EXIT_FAILURE fi fi\ " chmod +x $output fi exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do $echo "X$obj" | $Xsed -e 's%^.*/%%' done | sort | sort -uc >/dev/null 2>&1); then : else $echo "copying selected object files to avoid basename conflicts..." if test -z "$gentop"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "$mkdir $gentop" $run $mkdir "$gentop" status=$? if test "$status" -ne 0 && test ! -d "$gentop"; then exit $status fi fi save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase counter=`expr $counter + 1` case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" $run ln "$obj" "$gentop/$newobj" || $run cp "$obj" "$gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" if len=`expr "X$cmds" : ".*"` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts $echo "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done for obj in $save_oldobjs do oldobjs="$objlist $obj" objlist="$objlist $obj" eval test_cmds=\"$old_archive_cmds\" if len=`expr "X$test_cmds" : ".*"` && test "$len" -le "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do eval cmd=\"$cmd\" IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$generated"; then $show "${rm}r$generated" $run ${rm}r$generated fi # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` relink_command="$var=\"$var_value\"; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. if test -z "$run"; then for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` if test -z "$libdir"; then $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi if test "X$EGREP" = X ; then EGREP=egrep fi # We do not want portage's install root ($D) present. Check only for # this if the .la is being installed. if test "$installed" = yes && test "$D"; then eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` else mynewdependency_lib="$libdir/$name" fi # Do not add duplicates if test "$mynewdependency_lib"; then my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` if test -z "$my_little_ninja_foo_1"; then newdependency_libs="$newdependency_libs $mynewdependency_lib" fi fi ;; *) if test "$installed" = yes; then # Rather use S=WORKDIR if our version of portage supports it. # This is because some ebuild (gcc) do not use $S as buildroot. if test "$PWORKDIR"; then S="$PWORKDIR" fi # We do not want portage's build root ($S) present. my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"` if test -n "$my_little_ninja_foo_2" && test "$S"; then mynewdependency_lib="" # We do not want portage's install root ($D) present. my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"` elif test -n "$my_little_ninja_foo_3" && test "$D"; then eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` else mynewdependency_lib="$deplib" fi else mynewdependency_lib="$deplib" fi # Do not add duplicates if test "$mynewdependency_lib"; then my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"` if test -z "$my_little_ninja_foo_4"; then newdependency_libs="$newdependency_libs $mynewdependency_lib" fi fi ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlfiles="$newdlfiles $libdir/$name" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` if test -z "$libdir"; then $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 exit $EXIT_FAILURE fi newdlprefiles="$newdlprefiles $libdir/$name" done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $rm $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac # Do not add duplicates if test "$installed" = yes && test "$D"; then install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/\+:/:g'` fi $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $echo >> $output "\ relink_command=\"$relink_command\"" fi done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? ;; esac exit $EXIT_SUCCESS ;; # libtool install mode install) modename="$modename: install" # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$arg " arg="$1" shift else install_prog= arg="$nonopt" fi # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$install_prog$arg" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest="$arg" continue fi case $arg in -d) isdir=yes ;; -f) prev="-f" ;; -g) prev="-g" ;; -m) prev="-m" ;; -o) prev="-o" ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest="$arg" continue fi ;; esac # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case $arg in *$quote_scanset* | *]* | *\|* | *\&* | *\(* | *\)* | "") arg="\"$arg\"" ;; esac install_prog="$install_prog $arg" done if test -z "$install_prog"; then $echo "$modename: you must specify an install program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -n "$prev"; then $echo "$modename: the \`$prev' option requires an argument" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi if test -z "$files"; then if test -z "$dest"; then $echo "$modename: no file or destination specified" 1>&2 else $echo "$modename: you must specify a destination" 1>&2 fi $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Strip any trailing slash from the destination. dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` test "X$destdir" = "X$dest" && destdir=. destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` # Not a directory, so check to see that there is only one file specified. set dummy $files if test "$#" -gt 2; then $echo "$modename: \`$dest' is not a directory" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi library_names= old_library= relink_command= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ test "X$dir" = "X$file/" && dir= dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. if test "$inst_prefix_dir" = "$destdir"; then $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 exit $EXIT_FAILURE fi if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi $echo "$modename: warning: relinking \`$file'" 1>&2 $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 exit $EXIT_FAILURE fi fi # See the names of the shared library. set dummy $library_names if test -n "$2"; then realname="$2" shift shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. $show "$install_prog $dir/$srcname $destdir/$realname" $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? if test -n "$stripme" && test -n "$striplib"; then $show "$striplib $destdir/$realname" $run eval "$striplib $destdir/$realname" || exit $? fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. for linkname do if test "$linkname" != "$realname"; then $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" fi done fi # Do each command in the postinstall commands. lib="$destdir/$realname" cmds=$postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Install the pseudo-library for information purposes. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` instname="$dir/$name"i $show "$install_prog $instname $destdir/$name" $run eval "$install_prog $instname $destdir/$name" || exit $? # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; *.$objext) staticdest="$destfile" destfile= ;; *) $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac # Install the libtool object if requested. if test -n "$destfile"; then $show "$install_prog $file $destfile" $run eval "$install_prog $file $destfile" || exit $? fi # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` $show "$install_prog $staticobj $staticdest" $run eval "$install_prog \$staticobj \$staticdest" || exit $? fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then file=`$echo $file|${SED} 's,.exe$,,'` stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin*|*mingw*) wrapper=`$echo $file | ${SED} -e 's,.exe$,,'` ;; *) wrapper=$file ;; esac if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then notinst_deplibs= relink_command= # To insure that "foo" is sourced, and not "foo.exe", # finese the cygwin/MSYS system by explicitly sourcing "foo." # which disallows the automatic-append-.exe behavior. case $build in *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; *) wrapperdot=${wrapper} ;; esac # If there is no directory component, then add one. case $file in */* | *\\*) . ${wrapperdot} ;; *) . ./${wrapperdot} ;; esac # Check the variables that should have been set. if test -z "$notinst_deplibs"; then $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 exit $EXIT_FAILURE fi finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. case $lib in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done relink_command= # To insure that "foo" is sourced, and not "foo.exe", # finese the cygwin/MSYS system by explicitly sourcing "foo." # which disallows the automatic-append-.exe behavior. case $build in *cygwin* | *mingw*) wrapperdot=${wrapper}. ;; *) wrapperdot=${wrapper} ;; esac # If there is no directory component, then add one. case $file in */* | *\\*) . ${wrapperdot} ;; *) . ./${wrapperdot} ;; esac outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then tmpdir="/tmp" test -n "$TMPDIR" && tmpdir="$TMPDIR" tmpdir="$tmpdir/libtool-$$" save_umask=`umask` umask 0077 if $mkdir "$tmpdir"; then umask $save_umask else umask $save_umask $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 continue fi file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'` outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ${rm}r "$tmpdir" continue fi file="$outputname" else $echo "$modename: warning: cannot relink \`$file'" 1>&2 fi else # Install the binary that we compiled earlier. file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyways case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'` ;; esac ;; esac $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" ;; esac done for file in $staticlibs; do name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` # Set up the ranlib parameters. oldlib="$destdir/$name" $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? if test -n "$stripme" && test -n "$old_striplib"; then $show "$old_striplib $oldlib" $run eval "$old_striplib $oldlib" || exit $? fi # Do each command in the postinstall commands. cmds=$old_postinstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$future_libdirs"; then $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 fi if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi ;; # libtool finish mode finish) modename="$modename: finish" libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. cmds=$finish_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" || admincmds="$admincmds $cmd" done IFS="$save_ifs" fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $run eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. test "$show" = : && exit $EXIT_SUCCESS $echo "----------------------------------------------------------------------" $echo "Libraries have been installed in:" for libdir in $libdirs; do $echo " $libdir" done $echo $echo "If you ever happen to want to link against installed libraries" $echo "in a given directory, LIBDIR, you must either use libtool, and" $echo "specify the full pathname of the library, or use the \`-LLIBDIR'" $echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $echo " - add LIBDIR to the \`$shlibpath_var' environment variable" $echo " during execution" fi if test -n "$runpath_var"; then $echo " - add LIBDIR to the \`$runpath_var' environment variable" $echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $echo " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $echo " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $echo $echo "See any operating system documentation about shared libraries for" $echo "more information, such as the ld(1) and ld.so(8) manual pages." $echo "----------------------------------------------------------------------" exit $EXIT_SUCCESS ;; # libtool execute mode execute) modename="$modename: execute" # The first argument is the command name. cmd="$nonopt" if test -z "$cmd"; then $echo "$modename: you must specify a COMMAND" 1>&2 $echo "$help" exit $EXIT_FAILURE fi # Handle -dlopen flags immediately. for file in $execute_dlfiles; do if test ! -f "$file"; then $echo "$modename: \`$file' is not a file" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi dir= case $file in *.la) # Check to see that this really is a libtool archive. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi # Read the libtool library. dlname= library_names= # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" continue fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 exit $EXIT_FAILURE fi ;; *.lo) # Just add the directory containing the .lo file. dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. ;; *) $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. case $file in */* | *\\*) . $file ;; *) . ./$file ;; esac # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` args="$args \"$file\"" done if test -z "$run"; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables if test "${save_LC_ALL+set}" = set; then LC_ALL="$save_LC_ALL"; export LC_ALL fi if test "${save_LANG+set}" = set; then LANG="$save_LANG"; export LANG fi # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" $echo "export $shlibpath_var" fi $echo "$cmd$args" exit $EXIT_SUCCESS fi ;; # libtool clean and uninstall mode clean | uninstall) modename="$modename: $mode" rm="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) rm="$rm $arg"; rmforce=yes ;; -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac done if test -z "$rm"; then $echo "$modename: you must specify an RM program" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE fi rmdirs= origobjdir="$objdir" for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$file"; then dir=. objdir="$origobjdir" else objdir="$dir/$origobjdir" fi name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if (test -L "$file") >/dev/null 2>&1 \ || (test -h "$file") >/dev/null 2>&1 \ || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" if test "$mode" = uninstall; then if test -n "$library_names"; then # Do each command in the postuninstall commands. cmds=$postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. cmds=$old_postuninstall_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $show "$cmd" $run eval "$cmd" if test "$?" -ne 0 && test "$rmforce" != yes; then exit_status=1 fi done IFS="$save_ifs" fi # FIXME: should reinstall the best remaining shared library. fi fi ;; *.lo) # Possibly a libtool object, so verify it. if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # Read the .lo file . $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" \ && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" \ && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) file=`$echo $file|${SED} 's,.exe$,,'` noexename=`$echo $name|${SED} 's,.exe$,,'` # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then relink_command= . $dir/$noexename # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac $show "$rm $rmfiles" $run $rm $rmfiles || exit_status=1 done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then $show "rmdir $dir" $run rmdir $dir >/dev/null 2>&1 fi done exit $exit_status ;; "") $echo "$modename: you must specify a MODE" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE ;; esac if test -z "$exec_cmd"; then $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$generic_help" 1>&2 exit $EXIT_FAILURE fi fi # test -z "$show_help" if test -n "$exec_cmd"; then eval exec $exec_cmd exit $EXIT_FAILURE fi # We need to display help for each of the modes. case $mode in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... Provide generalized library-building support services. --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --finish same as \`--mode=finish' --help display this help message and exit --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] --quiet same as \`--silent' --silent don't print informational messages --tag=TAG use configuration variables from tag TAG --version print version information MODE must be one of the following: clean remove files from the build directory compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for a more detailed description of MODE. Report bugs to ." exit $EXIT_SUCCESS ;; clean) $echo \ "Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $echo \ "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $echo \ "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $echo \ "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $echo \ "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -static do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $echo \ "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$help" 1>&2 exit $EXIT_FAILURE ;; esac $echo $echo "Try \`$modename --help' for more information about other modes." exit $? # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: jmk-foofus-medusa-dd62069/misc/000077500000000000000000000000001460263104500163425ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/misc/gen_lm_ntlm.pl000077500000000000000000000010071460263104500211730ustar00rootroot00000000000000#!/usr/bin/perl use Crypt::SmbHash; $username = $ARGV[0]; $password = $ARGV[1]; if ( !$password ) { print "Not enough arguments\n"; print "Usage: $0 username password\n"; exit 1; } ntlmgen $password, $lm, $nt; printf "%s::%s:%s:::\n", $username, $lm, $nt; #my @lm = split(//, $lm); #print "LM: "; #for($i=0; $i<32; $i=$i+2) { print "0x", $lm[$i], $lm[$i+1], ", "; } #print "\n"; #my @nt = split(//, $nt); #print "NT: "; #for($i=0; $i<32; $i=$i+2) { print "0x", $nt[$i], $nt[$i+1], ", "; } #print "\n"; jmk-foofus-medusa-dd62069/misc/net-analyzer/000077500000000000000000000000001460263104500207535ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/misc/net-analyzer/medusa-2.2.ebuild000066400000000000000000000014341460263104500237200ustar00rootroot00000000000000# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ DESCRIPTION="Parallel Network Login Auditor" HOMEPAGE="http://www.foofus.net/jmk/medusa.html" SRC_URI="http://www.foofus.net/jmk/tools/${P}.tar.gz" RESTRICT="nomirror" LICENSE="GPL-2" SLOT="0" KEYWORDS="~amd64 ~x86" RESTRICT="nostrip" IUSE="" DEPEND=" ssl? ( dev-libs/openssl ) ssh2? ( net-libs/libssh2 ) ncp? ( net-fs/ncpfs ) postgres? ( dev-db/libpq ) rdp? ( net-misc/freerdp ) svn? ( dev-util/subversion ) " src_compile() { econf \ --with-default-mod-path="/usr/lib/medusa/modules" \ || die "econf failed" emake || die "emake failed" } src_install() { make DESTDIR="${D}" install || die "Install failed!" dodoc README TODO ChangeLog dohtml doc/*.html } jmk-foofus-medusa-dd62069/misc/test_scripts/000077500000000000000000000000001460263104500210705ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/misc/test_scripts/medusa_agent.py000077500000000000000000000052201460263104500241000ustar00rootroot00000000000000#!/usr/bin/env python import xmlrpclib,subprocess, urllib, tarfile,os,sys, socket from SimpleXMLRPCServer import SimpleXMLRPCServer def download_file ( url ): file = url.split( "/" ) dir_name, bla = file[5].split(".tar") path = "/root/" (file_name, header) = urllib.urlretrieve(url) tar = tarfile.open(file_name) tar.extractall(path=path) tar.close() return dir_name def configure( dir_path): os.chdir("/root/" + dir_path) #configure = subprocess.Popen( "./configure --enable-module-afp 2>&1",shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,).stdout configure = subprocess.Popen( "./configure 2>&1",shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,).stdout configure_messages = configure.read().split('\n') return configure_messages def make_medusa(): make = subprocess.Popen("export LC_CTYPE=C && make", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,).stdout make_messages = make.read().split('\n') return make_messages def install_medusa(): make_install = subprocess.Popen("export LC_CTYPE=C && make install", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,).stdout make_install_messages = make_install.read().split('\n') return make_install_messages def cleanup_install_files(): os.chdir("/root/") os.system("rm -rf /root/medusa-*") message = "done" return message def medusa_module_test(): medusa_module_test = subprocess.Popen("/usr/local/bin/medusa -d", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,).stdout medusa_module_test = medusa_module_test.read().split('\n') return medusa_module_test def run_medusa_tests(service,target_host, usernames, passwords, options): medusa_test_output = subprocess.Popen("/usr/local/bin/medusa -M " + service + " -h " + target_host + " -e ns -u " + usernames + " -p '" + passwords + "' " + options , shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,).stdout medusa_output_data = medusa_test_output.read().strip('\n') return medusa_output_data def main(): print "Agent has started\n" server = SimpleXMLRPCServer(('0.0.0.0', 31137)) server.register_function (download_file, "download_file") server.register_function (configure, "configure") server.register_function (make_medusa,"make_medusa") server.register_function (install_medusa, "install_medusa") server.register_function (cleanup_install_files, "cleanup_install_files") server.register_function (medusa_module_test,"medusa_module_test") server.register_function (run_medusa_tests, "run_medusa_tests") server.serve_forever() if __name__ == "__main__": try: main() sys.exit(0) except KeyboardInterrupt: print "\nEnding program. Have a nice day" sys.exit(1) jmk-foofus-medusa-dd62069/misc/test_scripts/medusa_controller.py000077500000000000000000000236461460263104500252010ustar00rootroot00000000000000#!/usr/bin/env python import xmlrpclib, re, sys, socket from optparse import OptionParser from time import strftime #static global variables MEDUSA_VER = "2.1_devel" status_log = open("status.log",'a') pattern = re.compile ('error', re.IGNORECASE) module_pattern = re.compile('.*\.mod : .*? : version.*', re.IGNORECASE) services_pattern = re.compile('error', re.IGNORECASE) time = strftime("%Y-%m-%d %H:%M:%S") #function time...wooo its function time. def test_medusa_modules(host): host_log = open(host.strip('\n'), 'a') module_error_flag = False host_log = open(host, 'a') host_ip = socket.gethostbyname(host) try: proxy = xmlrpclib.ServerProxy("http://" + host_ip + ":31137/") except socket.error: status_log.write("%s: Unable to connect %s.\n" %(time,host)) return False #Test medusa modules try: module_test_data = proxy.medusa_module_test() except socket.error: status_log.write("%s: Unable to connect %s.\n" %(time,host)) return False for x in module_test_data: host_log.write( "%s: %s: Module build information:%s.\n" %(time,host,x.strip('\n'))) #matches = module_pattern.search(str(x)) #if matches != None: # status_log.write( "%s: %s: Module failed to build:%s.\n" %(time,host,x.strip('\n'))) # module_error_flag = True #if not module_error_flag: # host_log.write("%s: %s: Modules were complied correctly.\n" %(time, host,)) def test_medusa(host,config_file): #test medusa services host_log = open(host.strip('\n'), 'a') host_log = open(host, 'a') host_ip = socket.gethostbyname(host) try: proxy = xmlrpclib.ServerProxy("http://" + host_ip + ":31137/") except socket.error: status_log.write("%s: Unable to connect %s.\n" %(time,host)) return False tests = read_file(config_file) for x in tests: vars = x.split(':', 4) target_host = vars[0] service = vars[1] user_name = vars[2] passwd = vars[3] if len(vars) != 4 : options = vars[4] else: options = " " host_log.write("\n%s: Starting medusa tests for %s.\n" %(time, target_host)) test_data = proxy.run_medusa_tests(service, target_host,user_name,passwd,options) matched = services_pattern.search(test_data) if matched: host_log.write(test_data + "\n") status_log.write("%s: %s: Failed service test: %s on target: %s.\n" %(time,host,service,target_host)) else: host_log.write(test_data + "\n") status_log.write("%s: %s: passed service test : %s on target host: %s.\n" %(time,host, service, target_host)) return True def install_medusa(host): fail_check_flag = False host_ip = socket.gethostbyname(host) try: proxy = xmlrpclib.ServerProxy("http://" + host_ip + ":31137/") file_path = proxy.download_file("http://www.foofus.net/jmk/tmp/medusa-%s.tar.gz" %(MEDUSA_VER,)) except socket.error: status_log.write("%s: Unable to connect %s\n" %(time,host,)) return False #Open log after we make sure that we can open a connect to the remote host. host_log = open(host.strip('\n'), 'a') configure_log_data= proxy.configure(file_path) host_log.write("%s: Issuing configure:\n" %(time,)) for x in configure_log_data: try: matches = pattern.search(str(x)) if matches: status_log.write("%s: %s: Configure failed please check logs for %s.\n" %(time, host.strip('\n'),host.strip('\n'))) host_log.write( x + "\n") fail_check_flag = True else: host_log.write(x + "\n") except UnicodeEncodeError: pass make_log_data = proxy.make_medusa() host_log.write("%s: Issuing make:\n" %(time,)) for x in make_log_data: try: matches = pattern.search(str(x)) if matches: status_log.write("%s: %s: Make failed please check logs for %s.\n" %(time, host.strip('\n'),host.strip('\n'))) host_log.write(x+ "\n") fail_check_flag = True else: host_log.write(x + "\n") except UnicodeEncodeError: pass make_install_log = proxy.install_medusa() host_log.write("%s: Issuing make install:\n" %(time,)) for x in make_install_log: try: matches = pattern.search(str(x)) if matches: status_log.write("%s: %s: Make install failed please check logs for %s.\n" %(time,host.strip('\n'),host.strip('\n'))) host_log.write(x+ "\n") fail_check_flag = True else: host_log.write(x + "\n") except UnicodeEncodeError: pass if not fail_check_flag: proxy.cleanup_install_files() status_log.write( "%s: %s: Passed medusa install.\n" %(time,host.strip('\n'))) return True else: return False def build_medusa(host): fail_check_flag = False host_ip = socket.gethostbyname(host) try: proxy = xmlrpclib.ServerProxy("http://" + host_ip + ":31137/") file_path = proxy.download_file("http://www.foofus.net/jmk/tmp/medusa-%s.tar.gz" %(MEDUSA_VER,)) except socket.error: status_log.write("%s: Unable to connect %s\n" %(time,host,)) return False #Open log after we make sure that we can open a connect to the remote host. host_log = open(host.strip('\n'), 'a') configure_log_data= proxy.configure(file_path) host_log.write("%s: Issuing configure:\n" %(time,)) for x in configure_log_data: try: matches = pattern.search(str(x)) if matches: status_log.write("%s: %s: Configure failed please check logs for %s.\n" %(time, host.strip('\n'),host.strip('\n'))) host_log.write( x + "\n") fail_check_flag = True else: host_log.write(x + "\n") except UnicodeEncodeError: pass make_log_data = proxy.make_medusa() host_log.write("%s: Issuing make:\n" %(time,)) for x in make_log_data: try: matches = pattern.search(str(x)) if matches: status_log.write("%s: %s: Make failed please check logs for %s.\n" %(time, host.strip('\n'),host.strip('\n'))) host_log.write(x+ "\n") fail_check_flag = True else: host_log.write(x + "\n") except UnicodeEncodeError: pass if not fail_check_flag: proxy.cleanup_install_files() status_log.write( "%s: %s: Passed medusa configure and build.\n" %(time,host.strip('\n'))) return True else: return False def read_file ( filename): try: f = open( filename, 'r') list = f.readlines() return list except IOError: print "Error: Can not read %s.\n" %(filename,) sys.exit(1) def options_list(usage): parser = OptionParser() parser.add_option( "-c", "--config",dest ="config_file", help="-c/--config: Configuration file for the device you want to test medusa against\n") parser.add_option("-f", "--file", dest="hosts_file", help="-f/--file: File with a lists of hosts to build medusa on\n") parser.add_option("-H","--host", dest="host", help="-H/--host: host to build medusa on\n") parser.add_option("-i", "--install", dest ="install_medusa" ,action="store_true", help= "-i/--install: used to install medusa on host\n") parser.add_option("-t", "--test", dest="test_medusa", action="store_true", help="-t/-test:Just run medusa tests on hosts\n") parser.add_option("-b", "--build", dest="build_medusa", action="store_true", help="-b/--build will download and build medusa. It will not install it.") (options, args) = parser.parse_args() config_file = options.config_file hosts_file = options.hosts_file host = options.host install_medusa_flag = options.install_medusa test_medusa_flag = options.test_medusa build_medusa_flag = options.build_medusa if hosts_file == None and host == None: print "Missing option.\nUsage: %s\n" %(usage,) sys.exit(1) elif config_file == None and test_medusa_flag == True: print "Missing option.\nUsage: %s\n" %(usage,) sys.exit(1) else: if hosts_file == None: hosts_file = 0 return (hosts_file,host,config_file, install_medusa_flag, test_medusa_flag, build_medusa_flag) def main(): usage = "-f/--file: File with a list of hosts to build medusa on\n-H/--host: Host to build medusa on\n-c/--config: Configuration file for the device you want to test medusa on\nFile format is as follows: host:service:user:pass.\n-i/--install: used to install medusa on host.\n-t/--test:Just run medusa tests on hosts.\n-b/-build will download and build medusa. It will not install it.\n" (hosts_file,host, config_file, install_medusa_flag, test_medusa_flag, build_medusa_flag) = options_list(usage) if hosts_file != 0: hosts = read_file(hosts_file) if install_medusa_flag and test_medusa_flag == 1: print "Plase wait while Medusa is installed and tested are being run.\n" for host in hosts: status = install_medusa(host.strip('\n')) if status: test_medusa_modules(host.strip('\n')) test_medusa(host.strip('\n'), config_file) elif install_medusa_flag == 1: print "Plase wait while medusa is being installed\n" for host in hosts: install_medusa(host.strip('\n')) test_medusa_modules(host.strip('\n')) elif test_medusa_flag == 1: print "Please wait while medusa is being tested\n" for host in hosts: test_medusa(host.strip('n'), config_file) elif build_medusa_flag == 1: print "Please wait while medusa is being build\n" for host in hosts: build_medusa(host.strip('\n')) else: print "Do you know what you are doing?\n" + usage + "\n" sys.exit(1) else: if install_medusa_flag and test_medusa_flag == 1: print "Plase wait while Medusa is installed and tested are being run.\n" status = install_medusa(host) if status: test_medusa_modules(host) test_medusa(host, config_file) elif install_medusa_flag == 1: print "Plase wait while medusa is being installed\n" install_medusa(host) test_medusa_modules(host) elif test_medusa_flag == 1: print "Please wait while medusa is being tested\n" test_medusa(host, config_file) elif build_medusa_flag == 1: build_medusa(host.strip('\n')) else: print "Do you know what you are doing?\n" + usage + "\n" sys.exit(1) if __name__ == "__main__": try: main() print "Program completed" except KeyboardInterrupt: print "\noooo got a CTL-C from the console. Exiting. I hope next time you know what you are doing." jmk-foofus-medusa-dd62069/misc/zsh/000077500000000000000000000000001460263104500171465ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/misc/zsh/_medusa000066400000000000000000000050731460263104500205130ustar00rootroot00000000000000#compdef medusa # Copy this file to your global zsh site-functions directory # ex: /usr/local/share/zsh/site-functions # Written by Bismark (bismark@foofus.net) # Date: 09/22/2008 # # Modified by Bismark (bismark@foofus.net) # Date: 01/24/2010 # Changes: # Removed completion prompts for options that do not have a value # Added option removal for conflicting options. # # Modified by Bismark (bismark@foofus.net) # Date: 05/12/2015 # Changes: # Fixed -C combo option to properly search for a file typeset -A opt_args _select_module() { local modules modules=( $(medusa -d | grep + | awk '/.mod/ {print $2}' | cut -d"." -f 1) ) _wanted select-module expl 'Module' compadd "$@" -a - modules } _medusa() { local expl context state line ret=1 local -A opt_args _arguments \ '-b[Suppress startup banner]' \ '-O[File to append log information to.]:Log file:_files' \ '-M[Name of the module to execute (without the .mod extension)]:Module:_select_module' \ '*-m[Parameter to pass to the module.]:Module Parameters' \ '-d[Dump all known modules.]:Dump Modules' \ '-n[Use for non-default TCP port number.]:tcp port' \ '-s[Enable SSL.]' \ '-g[Give up after trying to connect for NUM seconds (default 3).]:Retry seconds' \ '-r[Sleep number of seconds between retry attempts (default 3).]:Sleep seconds' \ '-R[Attempted retries before giving up. The total number of attempts will be retries + 1.]:Retries' \ '-t[Total number of logins to be tested concurrently]:Concurrent Logins' \ '-T[Total number of hosts to be tested concurrently.]:Concurrent Hosts' \ '-L[Parallelize logins using one username per thread.]' \ '-f[Stop scanning host after first valid username/password found.]' \ '-F[Stop audit after first valid username/password found on any host.]' \ '-q[Display module’s usage information.]' \ '-v[Verbose level (0 - 6)]:Verbosity:(0 1 2 3 4 5 6)' \ '-w[Error debug level (0 - 10)]:Debug:(0 1 2 3 4 5 6 7 8 9 10)' \ '-V[Display version]' \ "-e[Additional password checks]:Additional password checks:_values 'Additional password checks' 'n[No Password]' 's[Password = Username]' 'ns[No Password & Password = Username]'":'(n s ns)' \ '(-H -C)-h[Target hostname or IP address.]:Hostname or IP Address' \ '(-h -C)-H[Read Targets from a file.]:Hosts file:_files' \ '(-U -u -P -p)-C[File containing combo entries. (see man page)]:Combo file:_files' \ '(-U -C)-u[Username.]:Username' \ '(-P -C)-p[Password.]:Password' \ '(-u -C)-U[Read Usernames from a file.]:Username file:_files' \ '(-P -C)-P[Read Passwords from a file.]:Password file:_files' && return 0 return 1 } _medusa "$@" jmk-foofus-medusa-dd62069/missing000077500000000000000000000153361460263104500170160ustar00rootroot00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2018 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jmk-foofus-medusa-dd62069/mkinstalldirs000077500000000000000000000067231460263104500202250ustar00rootroot00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2018-03-07.03; # UTC # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' IFS=" "" $nl" errstatus=0 dirmode= usage="\ Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... Create each directory DIR (with mode MODE, if specified), including all leading file name components. Report bugs to ." # process command line arguments while test $# -gt 0 ; do case $1 in -h | --help | --h*) # -h for help echo "$usage" exit $? ;; -m) # -m PERM arg shift test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } dirmode=$1 shift ;; --version) echo "$0 $scriptversion" exit $? ;; --) # stop option processing shift break ;; -*) # unknown option echo "$usage" 1>&2 exit 1 ;; *) # first non-opt arg break ;; esac done for file do if test -d "$file"; then shift else break fi done case $# in 0) exit 0 ;; esac # Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and # mkdir -p a/c at the same time, both will detect that a is missing, # one will create a, then the other will try to create a and die with # a "File exists" error. This is a problem when calling mkinstalldirs # from a parallel make. We use --version in the probe to restrict # ourselves to GNU mkdir, which is thread-safe. case $dirmode in '') if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -p -- $*" exec mkdir -p -- "$@" else # On NextStep and OpenStep, the 'mkdir' command does not # recognize any option. It will interpret all options as # directories to create, and then abort because '.' already # exists. test -d ./-p && rmdir ./-p test -d ./--version && rmdir ./--version fi ;; *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else # Clean up after NextStep and OpenStep mkdir. for d in ./-m ./-p ./--version "./$dirmode"; do test -d $d && rmdir $d done fi ;; esac for file do case $file in /*) pathcomp=/ ;; *) pathcomp= ;; esac oIFS=$IFS IFS=/ set fnord $file shift IFS=$oIFS for d do test "x$d" = x && continue pathcomp=$pathcomp$d case $pathcomp in -*) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr else if test ! -z "$dirmode"; then echo "chmod $dirmode $pathcomp" lasterr= chmod "$dirmode" "$pathcomp" || lasterr=$? if test ! -z "$lasterr"; then errstatus=$lasterr fi fi fi fi pathcomp=$pathcomp/ done done exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: jmk-foofus-medusa-dd62069/sample/000077500000000000000000000000001460263104500166705ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/sample/combo-1.txt000066400000000000000000000003371460263104500206710ustar00rootroot00000000000000192.168.0.1:user1:pass1 192.168.0.1:user1:pass2 192.168.0.1:user2:pass2 192.168.0.1:user3:pass3-1 192.168.0.1:user3:pass3-2 192.168.0.3:user4:pass1 192.168.0.10:user5:pass1 192.168.0.10:user6:pass1 192.168.0.10:user5:pass3 jmk-foofus-medusa-dd62069/sample/combo-2.txt000066400000000000000000000001641460263104500206700ustar00rootroot00000000000000192.168.0.1:user1: 192.168.0.1:user2: 192.168.0.1:user3: 192.168.0.3:user4: 192.168.0.10:user5: 192.168.0.10:user6: jmk-foofus-medusa-dd62069/sample/combo-3.txt000066400000000000000000000000301460263104500206610ustar00rootroot00000000000000host1:: host2:: host3:: jmk-foofus-medusa-dd62069/sample/combo-4.txt000066400000000000000000000001201460263104500206620ustar00rootroot00000000000000:user1:pass1 :user2:pass2 :user3:pass3-1 :user4:pass1 :user5:pass1 :user6:pass1 jmk-foofus-medusa-dd62069/sample/combo-5.txt000066400000000000000000000000401460263104500206640ustar00rootroot00000000000000:user0: :user1: :user2: :user5: jmk-foofus-medusa-dd62069/sample/combo-6.txt000066400000000000000000000000301460263104500206640ustar00rootroot00000000000000::pass1 ::pass2 ::pass3 jmk-foofus-medusa-dd62069/sample/combo-7.txt000066400000000000000000000002131460263104500206700ustar00rootroot00000000000000192.168.0.1::pass1 192.168.0.1::pass2 192.168.0.1::pass3-1 192.168.0.1::pass3-2 192.168.0.3::pass1 192.168.0.10::pass1 192.168.0.10::pass3 jmk-foofus-medusa-dd62069/sample/combo.txt000066400000000000000000000000711460263104500205260ustar00rootroot00000000000000foo:bar:fud foo:bar: foo:: :bar:fud :bar: ::fud foo::fud jmk-foofus-medusa-dd62069/sample/hosts.txt000066400000000000000000000001661460263104500205740ustar00rootroot00000000000000192.168.0.1 192.168.0.3 192.168.0.10 192.168.0.11 192.168.0.12 192.168.0.14 192.168.0.157 192.168.0.202 192.168.0.251 jmk-foofus-medusa-dd62069/sample/passwords.txt000066400000000000000000000000411460263104500214510ustar00rootroot00000000000000password pass1 pass2 pass3 pass4 jmk-foofus-medusa-dd62069/sample/passwords_simple.txt000066400000000000000000000000171460263104500230250ustar00rootroot00000000000000password admin jmk-foofus-medusa-dd62069/sample/users.txt000066400000000000000000000000361460263104500205710ustar00rootroot00000000000000admin user1 user2 user3 user4 jmk-foofus-medusa-dd62069/src/000077500000000000000000000000001460263104500161765ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/src/Makefile.am000066400000000000000000000007371460263104500202410ustar00rootroot00000000000000bin_PROGRAMS = medusa medusa_SOURCES = listModules.c medusa.c medusa-thread-pool.c medusa-thread-ssl.c medusa-net.c medusa-trace.c medusa-utils.c # set the include path found by configure AM_CPPFLAGS = -I$(top_srcdir)/src $(all_includes) # the library search path. #medusa_LDFLAGS = -rdynamic -ldl -lpthread -lssl noinst_HEADERS = medusa.h medusa-thread-pool.h medusa-thread-ssl.h medusa-net.h medusa-trace.h medusa-utils.h uthash.h #AM_CFLAGS = -DLIBOPENSSL SUBDIRS = modsrc jmk-foofus-medusa-dd62069/src/Makefile.in000066400000000000000000000521551460263104500202530ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ bin_PROGRAMS = medusa$(EXEEXT) subdir = src ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_medusa_OBJECTS = listModules.$(OBJEXT) medusa.$(OBJEXT) \ medusa-thread-pool.$(OBJEXT) medusa-thread-ssl.$(OBJEXT) \ medusa-net.$(OBJEXT) medusa-trace.$(OBJEXT) \ medusa-utils.$(OBJEXT) medusa_OBJECTS = $(am_medusa_OBJECTS) medusa_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__maybe_remake_depfiles = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(medusa_SOURCES) DIST_SOURCES = $(medusa_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir distdir-am am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APR_CONFIG = @APR_CONFIG@ APR_INCLUDE_DIR = @APR_INCLUDE_DIR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_MOD_PATH = @DEFAULT_MOD_PATH@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODULE_LIBS = @MODULE_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ medusa_SOURCES = listModules.c medusa.c medusa-thread-pool.c medusa-thread-ssl.c medusa-net.c medusa-trace.c medusa-utils.c # set the include path found by configure AM_CPPFLAGS = -I$(top_srcdir)/src $(all_includes) # the library search path. #medusa_LDFLAGS = -rdynamic -ldl -lpthread -lssl noinst_HEADERS = medusa.h medusa-thread-pool.h medusa-thread-ssl.h medusa-net.h medusa-trace.h medusa-utils.h uthash.h #AM_CFLAGS = -DLIBOPENSSL SUBDIRS = modsrc all: all-recursive .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu --ignore-deps src/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) medusa$(EXEEXT): $(medusa_OBJECTS) $(medusa_DEPENDENCIES) $(EXTRA_medusa_DEPENDENCIES) @rm -f medusa$(EXEEXT) $(AM_V_CCLD)$(LINK) $(medusa_OBJECTS) $(medusa_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c -o $@ $< .c.obj: $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(PROGRAMS) $(HEADERS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-binPROGRAMS clean-generic cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS .PRECIOUS: Makefile # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: jmk-foofus-medusa-dd62069/src/listModules.c000066400000000000000000000113261460263104500206510ustar00rootroot00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ /* ** listModules.c ** ** prints out a list of local modules, along with their ** brief descriptions. If no other directory is specified, ** (i.e., pszDir is NULL), we assume "." ** ** CHANGE LOG ** 02-17-2004 - Created by Foofus ** 02-18-2004 - Works with test module (Foofus). ** */ #include #include #include #include #include #include "modsrc/module.h" void listModules(char* arrPaths[], int nTerminateNow) { // If nTerminateNow > 0, the application will exit immediately struct dirent **pdeEntry; char *pszTarget; int iLength; void *pLibrary; int (*pSummary)(char**); char *pszUsage; char *pszLibName; char *pszDir; int i, j, k; /* Initialize variables */ pszTarget = NULL; iLength = 0; pLibrary = NULL; pSummary = NULL; pszUsage = NULL; pszLibName = NULL; /* Say hello */ for(i = 0; i < 3; i++) { /* Format the directory name */ pszDir = arrPaths[i]; if (pszDir == NULL) { continue; } else { pszTarget = strdup(pszDir); iLength = 0; } /* (was a directory specified?) */ writeVerbose(VB_NONE, " Available modules in \"%s\" :", pszTarget); /* Open the directory */ if ((k = scandir( pszTarget, &pdeEntry, 0, alphasort )) < 0) { if (nTerminateNow > 0) writeVerbose(VB_EXIT, "\tCouldn't open directory \"%s\"", pszTarget); else writeVerbose(VB_NONE, "\tCouldn't open directory \"%s\"", pszTarget); } else { /* For each file, is it a module? */ j = -1; while (++j < k) { iLength = strlen( pdeEntry[j]->d_name ); if (iLength > 4) { /* Check the file suffix */ if (strcmp( (char*)(pdeEntry[j]->d_name + strlen( pdeEntry[j]->d_name ) - 4), MODULE_EXTENSION ) == 0) { /* Build the complete filename */ iLength = strlen( pdeEntry[j]->d_name ) + strlen( pszTarget ) + 2; pszLibName = (char*)malloc( iLength ); memset( pszLibName, 0, iLength ); strcpy(pszLibName, pszTarget); strcat(pszLibName, "/"); strcat(pszLibName, pdeEntry[j]->d_name); /* Load this as a shared library */ pLibrary = dlopen( pszLibName, RTLD_NOW ); if (pLibrary == NULL) { writeVerbose(VB_NONE, " + %s : Couldn't load \"%s\" [%s]", pdeEntry[j]->d_name, pszLibName, dlerror()); } else { /* Get a pointer to the summary usage function */ pSummary = (int(*)(char**))dlsym( pLibrary, "summaryUsage" ); if (pSummary == NULL) { writeVerbose(VB_NONE, " + %s : Invalid module %s [no export of summaryUsage() : %s]", pdeEntry[j]->d_name, pszLibName, dlerror()); } else { pszUsage = NULL; pSummary((char**)&pszUsage); writeVerbose(VB_NONE, " + %s : %s", pdeEntry[j]->d_name, pszUsage); free( pszUsage ); } /* (could we get a pointer to the function?) */ /* Let go of the library */ dlclose( pLibrary ); } /* (could we load the library?) */ /* Don't need the library name any more */ free( pszLibName ); } /* (did the file have the proper extension?) */ } /* (is the name long enough to bother considering?) */ /* free finished entry */ free(pdeEntry[j]); } /* (while) */ writeVerbose(VB_NONE, ""); } /* (could we open the directory?) */ /* All done. */ free( pszTarget ); } if (nTerminateNow > 0) writeVerbose(VB_EXIT, ""); } /* (listModules) */ jmk-foofus-medusa-dd62069/src/medusa-net.c000066400000000000000000000661371460263104500204210ustar00rootroot00000000000000/*************************************************************************** * medusa-net.c * * Copyright (C) 2006 by fizzgig * * fizzgig@foofus.net * * * * Low level networking stuff used by all medusa modules. * * Based heavily on the original hydra networking code by * * VanHauser and the good folks at thc (vh@thc.org). * * * * * * CHANGE LOG * * 04/04/2005 -- Created by fizzgig (fizzgig@foofus.net) * * 04/12/2005 -- Final "alpha" implementation * * * * 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., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * ***************************************************************************/ #include "medusa.h" #include "medusa-trace.h" #include "medusa-net.h" #include "uthash.h" #include #include #ifdef HAVE_LIBSSL #include #include #endif #ifdef HAVE_LIBSSL /* Original code utilized global variables for SSL socket support. Unfortunately, this could potentially be an issue in cases where modules utilize both SSL and non-SSL within a session (e.g. FTPS). It's possible one thread could connect to a service in the clear while another requires SSL. The global variable obviously makes this impossible. Ideally, this data should be unique to thread and tracked there. However, I believe implementing this would require rewriting all send/receive calls. For now, we are utilizing a hash of socket id to SSL information structure for tracking which connections require SSL. */ struct SSLSOCKETINFO { int id; /* key --> socket id */ int nUseSSL; SSL *ssl; SSL_CTX *sslContext; UT_hash_handle hh; /* required for UThash */ }; struct SSLSOCKETINFO *psSSLSocketInfo = NULL; pthread_mutex_t ptmSSLMutex; #endif // Modules can call this function to set up the sConnectParams structure needed for connection functions. // It copies data from the login structure and overrides default values if the user specified command-line // parameters. The typical use of this function, then, is: // 1) Create a sConnectParams structure // 2) Zero all members of the structure // 3) Set individual members of the structure with default module values (like port) // 4) Call initConnectionParams void initConnectionParams(sLogin* pLogin, sConnectParams* pParams) { pParams->nHost = inet_addr(pLogin->psServer->pHostIP); if (pLogin->psServer->psHost->iPortOverride != 0) { // Override the port pParams->nPort = pLogin->psServer->psHost->iPortOverride; } pParams->nUseSSL = pLogin->psServer->psHost->iUseSSL; pParams->nTimeout = pLogin->psServer->psHost->iTimeout; pParams->nRetryWait = pLogin->psServer->psHost->iRetryWait; pParams->nRetries = pLogin->psServer->psHost->iRetries; if (pParams->nProtocol == 0) pParams->nProtocol = SOCK_STREAM; if (pParams->nType == 0) pParams->nType = 6; } int medusaConnectInternal(unsigned long nHost, int nPort, int nProtocol, int nType, int nWaitTime, int nRetries, int nRetryWait,unsigned long nProxyStringIP, int nProxyStringPort, char* szProxyAuthentication, int nSourcePort) { int s, ret = -1; int nFail = 0; struct sockaddr_in target, source; char *buf, *tmpptr = NULL; char out[16]; long flag; int nOpt; unsigned int nSize; fd_set myset; struct timeval tv; int nUseProxy = nProxyStringIP > 0 ? 1 : 0; s = socket(PF_INET, nProtocol, nType); if (s >= 0) { /* Handle a source port request from a module */ if ( nSourcePort != 0 ) { int bind_ok=0; source.sin_family = PF_INET; source.sin_port = htons(nSourcePort); source.sin_addr.s_addr = INADDR_ANY; /* We will try to find a free port down to 512 */ while (!bind_ok && nSourcePort >= 512) { if (bind(s, (struct sockaddr *)&source, sizeof(source))==-1) { if (errno == EADDRINUSE) { writeError(ERR_DEBUG, "Port %d in use trying next lower port.", nSourcePort); nSourcePort--; source.sin_port = htons(nSourcePort); } else { if (errno == EACCES && (getuid() > 0)) { writeError(ERR_ERROR, "Source port for this service requires root privileges."); return FAILURE; } } } else bind_ok=1; } } /* End of source port fun */ if (nUseProxy > 0) { target.sin_port = htons(nProxyStringPort); memcpy(&target.sin_addr.s_addr, &nProxyStringIP, sizeof(unsigned long)); } else { target.sin_port = htons(nPort); memcpy(&target.sin_addr.s_addr, &nHost, sizeof(unsigned long)); } target.sin_family = AF_INET; // Set non-blocking if((flag = fcntl(s, F_GETFL, NULL)) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_GETFL) (%s)", strerror(errno)); return -1; } flag |= O_NONBLOCK; if(fcntl(s, F_SETFL, flag) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_SETFL) (%s)", strerror(errno)); return -1; } nFail = 0; ret = connect(s, (struct sockaddr*)&target, sizeof(struct sockaddr_in)); if (errno == EINPROGRESS) { do { if (nFail > 0 && nFail <= nRetries) { writeError(ERR_ERROR, "Thread %X: Host: %s Cannot connect [unreachable], retrying (%d of %d retries)", (int)pthread_self(), inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out)), nFail, nRetries); sleep(nRetryWait); } else if (nFail > nRetries) return -1; tv.tv_sec = nWaitTime; tv.tv_usec = 0; FD_ZERO(&myset); FD_SET(s, &myset); ret = select(s + 1, NULL, &myset, NULL, &tv); if (ret < 0 && errno != EINTR) { writeError(ERR_ERROR, "Error connecting to host: %s", strerror(errno)); return -1; } else if (ret > 0) { nSize = sizeof(int); if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void*)(&nOpt), &nSize) < 0) { writeError(ERR_ERROR, "Error in getsockopt() %s", strerror(errno)); return -1; } if (nOpt != 0) { // Socket is not valid - connection failed writeVerbose(VB_GENERAL, "Unable to connect (invalid socket): unreachable destination - %s", inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out))); return -1; } // If we get here, the socket should be valid ret = 0; break; } else { nFail++; } } while (1); } if (ret != 0 || nFail > nRetries) { writeVerbose(VB_GENERAL, "Unable to connect: unreachable destination"); ret = -1; return ret; } // Set the socket to be blocking again if((flag = fcntl(s, F_GETFL, NULL)) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_GETFL) (%s)", strerror(errno)); return -1; } flag &= ~O_NONBLOCK; if(fcntl(s, F_SETFL, flag) < 0) { writeError(ERR_ERROR, "Error fcntl(..., F_SETFL) (%s)", strerror(errno)); return -1; } ret = s; /* // Possible issue with MTU/MSS values and our use of fixed buffer sizes. // Example: OWA/EWS HTTPS // We set a MTU of 616 (MSS of 576) in our SYN packet // Windows responds with a MSS value of 536 // Windows sends a non-fragmented packet of 955 bytes // Our buffer of 576 has issues... moving to a buffer of 1500 for now... int option = 576 + 40; int optlen = sizeof(option); // getsockopt call doesn't seem to work... use "ifconfig eth0 mtu 616" if (setsockopt(s, SOL_IP, IP_MTU, &option, optlen) < 0) writeError(ERR_ERROR, "Error setting MTU size."); option = 0; if (getsockopt(s, SOL_IP, IP_MTU, &option, &optlen) < 0) writeError(ERR_ERROR, "Error retrieving MTU size."); writeError(ERR_DEBUG, "MTU size: %d", option); #define TCP_MAXSEG 0x02 if (getsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &option, &optlen) < 0) writeError(ERR_ERROR, "Error retrieving TCP_MAXSEG size."); writeError(ERR_DEBUG, "MSS size: %d", option); */ writeError(ERR_DEBUG, "Connected (internal)"); if (nUseProxy > 0) { buf = malloc(4096); memset(buf, 0, 4096); memset(&target, 0, sizeof(struct sockaddr_in)); memcpy(&target.sin_addr.s_addr, &nHost, sizeof(unsigned long)); target.sin_family = AF_INET; if (szProxyAuthentication == NULL) snprintf(buf, 4095, "CONNECT %s:%d HTTP/1.0\r\n\r\n", inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out)), nPort); else snprintf(buf, 4095, "CONNECT %s:%d HTTP/1.0\r\nProxy-Authorization: Basic %s\r\n\r\n", inet_ntop(AF_INET, &target.sin_addr, out, sizeof(out)), nPort, szProxyAuthentication); send(s, buf, strlen(buf), 0); recv(s, buf, 4096, 0); if (strncmp("HTTP/", buf, strlen("HTTP/")) == 0 && (tmpptr = index(buf, ' ')) != NULL && *++tmpptr == '2') { writeError(ERR_DEBUG, "Connected (with proxy)"); } else { //writeError(ERR_DEBUG, "Unable to connect using SSL (Code: %c%c%c)", *tmpptr, *(tmpptr + 1), *(tmpptr + 2)); writeError(ERR_ERROR, "CONNECT call to proxy failed with code %c%c%c", *tmpptr, *(tmpptr + 1), *(tmpptr + 2)); close(s); ret = -1; free(buf); return ret; } free(buf); } nFail = 0; return ret; } return ret; } int medusaConnectSSLInternal(sConnectParams* pParams, int hSocket) { int err; struct SSLSOCKETINFO *s; SSL *ssl = NULL; SSL_CTX *sslContext = NULL; pthread_mutex_lock(&ptmSSLMutex); SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); /* OpenSSL 1.1.0 introduced TLS_client_method() and deprecated all version specific functions. */ sslContext = SSL_CTX_new(TLS_client_method()); if (sslContext == NULL) { err = ERR_get_error(); writeError(ERR_ERROR, "SSL: Error allocating context: %s", ERR_error_string(err, NULL)); pthread_mutex_unlock(&ptmSSLMutex); return -1; } // set the compatbility mode SSL_CTX_set_options(sslContext, SSL_OP_ALL); // we set the default verifiers and dont care for the results SSL_CTX_set_default_verify_paths(sslContext); SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL); if ((hSocket < 0) && ((hSocket = medusaConnect(pParams)) < 0)) { pthread_mutex_unlock(&ptmSSLMutex); return -1; } if ((ssl = SSL_new(sslContext)) == NULL) { err = ERR_get_error(); writeError(ERR_ERROR, "Error preparing an SSL context: %s", ERR_error_string(err, NULL)); pthread_mutex_unlock(&ptmSSLMutex); return -1; } SSL_set_fd(ssl, hSocket); if (SSL_connect(ssl) <= 0) { err = ERR_get_error(); writeError(ERR_ERROR, "Could not create an SSL session: %s", ERR_error_string(err, NULL)); pthread_mutex_unlock(&ptmSSLMutex); return -1; } writeError(ERR_DEBUG, "SSL negotiated cipher: %s", SSL_get_cipher(ssl)); s = malloc(sizeof(struct SSLSOCKETINFO)); memset(s, 0, sizeof(struct SSLSOCKETINFO)); s->id = hSocket; s->nUseSSL = 1; s->ssl = ssl; s->sslContext = sslContext; HASH_ADD_INT( psSSLSocketInfo, id, s ); pthread_mutex_unlock(&ptmSSLMutex); return hSocket; } int medusaReceiveInternal(int socket, unsigned char *buf, int length) { #ifdef HAVE_LIBSSL int err; int nRet; struct SSLSOCKETINFO *s; HASH_FIND_INT( psSSLSocketInfo, &socket, s ); if ((s != NULL) && (s->nUseSSL)) { do { nRet = SSL_read(s->ssl, buf, length); if (nRet <= 0) { err = SSL_get_error(s->ssl, nRet); switch(err) { case SSL_ERROR_ZERO_RETURN: writeError(ERR_DEBUG, "The TLS/SSL connection has been closed."); break; case SSL_ERROR_SSL: writeError(ERR_ERROR, "A failure in the SSL library occurred, usually a protocol error."); break; case SSL_ERROR_SYSCALL: writeError(ERR_DEBUG, "TLS/SSL I/O error occurered (%d - %s)", err, ERR_error_string(err, NULL)); break; default: writeError(ERR_ERROR, "Unknown TLS/SSL error occurred (%d - %s)", err, ERR_error_string(err, NULL)); } } } while (nRet == -1 && err == SSL_ERROR_SYSCALL && errno == EINTR); return nRet; } else #endif return recv(socket, buf, length, 0); } /* This is a more robust receive function that can optionally convert NULLS to spaces Callers should check the value of *nBufferSize on return - IT MAY HAVE BEEN CHANGED */ unsigned char* medusaReceiveDataInternal(int socket, int* nBufferSize, int nConvertNullsToSpaces, int nReceiveDelay1, int nReceiveDelay2) { /* When receiving UDP packets, we need to be mindful of packets exceeding our default buffer size. Since we configure our UDP socket as SOCK_DGRAM, any packets beyond the buffer size will be discarded following a recv() call. UDP messages, or datagrams, should have the entire message within a single packet. The actual maximum size of this packet is unknown, however, due to a number of variables (see reference below). For our purposes, we are going to use the value of 576. http://www.uic.rsu.ru/doc/inet/tcp_stevens/ip_inter.htm#3_2 Although it's possible to send a 65535-byte IP datagram, most link layers will fragment this. Furthermore, a host is not required to receive a datagram larger than 576 bytes. TCP divides the user's data into pieces, so this limit normally doesn't affect TCP. With UDP we'll encounter numerous applications in later chapters (RIP, TFTP, BOOTP, the DNS, and SNMP) that limit themselves to 512 bytes of user data, to stay below this 576-byte limit. Realistically, however, most implementations today (especially those that support the Network File System, NFS) allow for just over 8192-byte IP datagrams. As of 2013/07/25, we are increasing the buffer size from 576 to 1500. The reason for this change is to deal with a OWA/EWS servers sending non-fragment packets larger than 576 and having data missed. Attempts to negotiate a lower MTU/MSS value with the target Windows host has failed for an unknown reason. */ const int BUFFER_SIZE = 1500; unsigned char *szBufReceive, *szBufReceiveTmp; int nBufReceive = 0, nBufReceiveTmp = 0, BufReceiveIndex = 0; int bSocketStatus = 0; int nReceiveDelay1sec = 0, nReceiveDelay1usec = 0; int nReceiveDelay2sec = 0, nReceiveDelay2usec = 0; *nBufferSize = 0; szBufReceive = malloc(BUFFER_SIZE + 1); memset(szBufReceive, 0, BUFFER_SIZE + 1); nReceiveDelay1sec = nReceiveDelay1 / 1000000; nReceiveDelay1usec = nReceiveDelay1 % 1000000; nReceiveDelay2sec = nReceiveDelay2 / 1000000; nReceiveDelay2usec = nReceiveDelay2 % 1000000; bSocketStatus = medusaDataReadyTimed(socket, nReceiveDelay1sec, nReceiveDelay1usec); if (bSocketStatus > 0) { writeError(ERR_DEBUG, "Data receive: Data waiting."); nBufReceive = medusaReceive(socket, szBufReceive, BUFFER_SIZE); if (nBufReceive <= 0) { writeError(ERR_DEBUG, "Data receive: Socket indicated data present, but none found."); free(szBufReceive); return NULL; } } else if (bSocketStatus == 0) { writeError(ERR_DEBUG, "Data receive: No data."); free(szBufReceive); return NULL; } else { writeError(ERR_ERROR, "Data receive: Failed to read from network socket."); free(szBufReceive); return NULL; } /* check for any addition data which may have been sent */ while (medusaDataReadyTimed(socket, nReceiveDelay2sec, nReceiveDelay2usec) > 0) { szBufReceiveTmp = malloc(BUFFER_SIZE + 1); memset(szBufReceiveTmp, 0, BUFFER_SIZE + 1); nBufReceiveTmp = medusaReceive(socket, szBufReceiveTmp, BUFFER_SIZE); if (nBufReceiveTmp <= 0) { writeError(ERR_DEBUG, "Data receive: No additional data."); free(szBufReceiveTmp); break; } if (nBufReceive + nBufReceiveTmp > BUFFER_SIZE) { writeError(ERR_DEBUG, "Additional data received. Increasing receive buffer %d bytes to %d.", nBufReceiveTmp, nBufReceive + nBufReceiveTmp + 1); szBufReceive = realloc(szBufReceive, nBufReceive + nBufReceiveTmp + 1); } memcpy(szBufReceive + nBufReceive, szBufReceiveTmp, nBufReceiveTmp); nBufReceive += nBufReceiveTmp; nBufReceiveTmp = 0; free(szBufReceiveTmp); } szBufReceive[nBufReceive] = 0; /* explicit NULL termination */ /* convert NULLS to spaces */ if (nConvertNullsToSpaces != 0) for (BufReceiveIndex = 0; BufReceiveIndex < nBufReceive; BufReceiveIndex++) if (szBufReceive[BufReceiveIndex] == 0) szBufReceive[BufReceiveIndex] = 32; writeError(ERR_DEBUG, "Formatted data received (size %d): %s", nBufReceive, szBufReceive); *nBufferSize = nBufReceive; return szBufReceive; } int medusaSendInternal(int socket, unsigned char *buf, int size, int options) { #ifdef HAVE_LIBSSL struct SSLSOCKETINFO *s; HASH_FIND_INT( psSSLSocketInfo, &socket, s ); if ((s != NULL) && (s->nUseSSL)) { return SSL_write(s->ssl, buf, size); } else { #endif int nRet; //char *bufReceive = NULL; //int nReceiveBufferSize = 0; /* flush any extraneous data remaining on socket */ //while (medusaDataReadyTimed(socket, 0, 1) > 0) //{ // bufReceive = medusaReceiveRaw(socket, &nReceiveBufferSize); // writeError(ERR_DEBUG, "Purging extraneous data on socket from previous request (size %d): %s", nReceiveBufferSize, bufReceive); // if (bufReceive == NULL) { break; } //} nRet = send(socket, buf, size, options); if (nRet < 0) { writeError(ERR_ERROR, "Error in send() %s", strerror(errno)); } return nRet; #ifdef HAVE_LIBSSL } #endif } // ------------------ public functions ------------------ // Variants of medusaConnectInternal int medusaConnect(sConnectParams* pParams) { return medusaConnectInternal(pParams->nHost, pParams->nPort, pParams->nProtocol, pParams->nType, pParams->nTimeout, pParams->nRetries, pParams->nRetryWait, pParams->nProxyStringIP, pParams->nProxyStringPort, pParams->szProxyAuthentication, pParams->nSourcePort); } int medusaConnectSSL(sConnectParams* pParams) { #ifdef HAVE_LIBSSL int hSocket; hSocket = medusaConnectSSLInternal(pParams, -1); if (hSocket > 0) pParams->nUseSSL = 1; return hSocket; #else writeError(ERR_ERROR, "Trying to connect via SSL, but medusa was not compiled with OPENSSL support. Using non-SSL connection."); pParams->nUseSSL = 0; return (medusaConnect(pParams)); #endif } /* Requires medusaConnect() to already have been called and for the socket to passed as an argument. Used for protocols which switch from non-SSL to SSL mid-connection. */ int medusaConnectSocketSSL(sConnectParams* pParams, int hSocket) { #ifdef HAVE_LIBSSL if (hSocket > 0) { pParams->nUseSSL = 1; return (medusaConnectSSLInternal(pParams, hSocket)); } else { writeError(ERR_ERROR, "Invalid socket handle."); pParams->nUseSSL = 0; return FAILURE; } #else writeError(ERR_ERROR, "Trying to connect via SSL, but medusa was not compiled with OPENSSL support."); pParams->nUseSSL = 0; return FAILURE; #endif } int medusaConnectTCP(sConnectParams* pParams) { pParams->nProtocol = SOCK_STREAM; pParams->nType = 6; return (medusaConnect(pParams)); } int medusaConnectUDP(sConnectParams* pParams) { // Modify the sConnectParams structure to make certain UDP stuff is set pParams->nProtocol = SOCK_DGRAM; pParams->nType = 17; return (medusaConnect(pParams)); } int medusaDisconnect(int hSocket) { #ifdef HAVE_LIBSSL struct SSLSOCKETINFO *s; if (hSocket <= 0) return -1; pthread_mutex_lock(&ptmSSLMutex); /* Remove socket's SSL informational structure (if it exists) */ HASH_FIND_INT( psSSLSocketInfo, &hSocket, s ); if (s != NULL) { HASH_DEL( psSSLSocketInfo, s ); } close(hSocket); pthread_mutex_unlock(&ptmSSLMutex); writeError(ERR_DEBUG, "Disconnect successful"); return -1; #else close(hSocket); writeError(ERR_DEBUG, "Disconnect successful"); return -1; #endif } int medusaDataReadyWritingTimed(int socket, time_t sec, time_t usec) { fd_set fds; struct timeval tv; FD_ZERO(&fds); FD_SET(socket, &fds); tv.tv_sec = sec; tv.tv_usec = usec; return (select(socket + 1, &fds, NULL, NULL, &tv)); } int medusaDataReadyWriting(int socket) { return (medusaDataReadyWritingTimed(socket, 30, 0)); } int medusaDataReadyTimed(int socket, time_t sec, time_t usec) { fd_set fds; struct timeval tv; FD_ZERO(&fds); FD_SET(socket, &fds); tv.tv_sec = sec; tv.tv_usec = usec; return (select(socket + 1, &fds, NULL, NULL, &tv)); } int medusaDataReady(int socket) { return (medusaDataReadyTimed(socket, 0, 0)); } /* Check socket status. Return 1 if connection is still valid. */ int medusaCheckSocket(int socket, int usec) { writeError(ERR_DEBUG, "Socket Check - wait time: %d", usec); if (medusaDataReadyTimed(socket, 0, usec) == 0) return 1; else return 0; } int medusaReceive(int socket, unsigned char *buf, int length) { int ret; ret = medusaReceiveInternal(socket, buf, length); writeError(ERR_DEBUG, "Data received (%d): %s", ret, buf); return ret; } unsigned char* medusaReceiveRaw(int socket, int* nBufferSize) { return medusaReceiveDataInternal(socket, nBufferSize, 0, READ_WAIT_TIME, 0); } unsigned char* medusaReceiveRawDelay(int socket, int* nBufferSize, int nReceiveDelay1, int nReceiveDelay2) { return medusaReceiveDataInternal(socket, nBufferSize, 0, nReceiveDelay1, nReceiveDelay2); } unsigned char* medusaReceiveLine(int socket, int* nBufferSize) { return medusaReceiveDataInternal(socket, nBufferSize, 1, READ_WAIT_TIME, 0); } unsigned char* medusaReceiveLineDelay(int socket, int* nBufferSize, int nReceiveDelay1, int nReceiveDelay2) { return medusaReceiveDataInternal(socket, nBufferSize, 1, nReceiveDelay1, nReceiveDelay2); } /* Receive function which uses regular expressions to determine whether we read all the data we're intending to. The goal is to address the issue of varying network speeds of servers. We don't want to retrieve only the first few bytes of a response and then start responding before the remote end is finished. The function will recheck the socket 5 times before giving up finding a match. Each recheck uses a larger timeout value. */ int medusaReceiveRegex(int hSocket, unsigned char **szBufReceive, int* nBufReceive, const char* regex) { unsigned char *szBufReceiveTmp = NULL; int nBufReceiveTmp = 0; regex_t preg; int errcode = REG_NOMATCH; char errmsg[512]; int nAttempt = 1; const int BUFFER_SIZE = 1500; writeError(ERR_DEBUG, "Regular expression: \"%s\"", regex); errcode = regcomp(&preg, regex, REG_EXTENDED|REG_ICASE|REG_NOSUB); if (errcode) { memset(errmsg, 0, 512); regerror(errcode, &preg, errmsg, 512); writeError(ERR_ERROR, "Regex compilation failed: %s", errmsg); return FAILURE; } *szBufReceive = medusaReceiveDataInternal(hSocket, nBufReceive, 0, READ_WAIT_TIME, 0); if (*szBufReceive == NULL) return FAILURE; do { errcode = regexec(&preg, (char* const) *szBufReceive, 0, 0, 0); if (errcode == REG_NOMATCH) { writeError(ERR_DEBUG, "Failed to match regex. Checking for additional data."); /* there more be more data waiting for us... */ if (medusaDataReadyTimed(hSocket, 0, 20000 * nAttempt) > 0) { szBufReceiveTmp = malloc(BUFFER_SIZE + 1); memset(szBufReceiveTmp, 0, BUFFER_SIZE + 1); nBufReceiveTmp = medusaReceive(hSocket, szBufReceiveTmp, BUFFER_SIZE); if (nBufReceiveTmp <= 0) { writeError(ERR_DEBUG, "Data receive: No additional data."); free(szBufReceiveTmp); break; } if (*nBufReceive + nBufReceiveTmp > BUFFER_SIZE) { writeError(ERR_DEBUG, "Additional data received. Increasing receive buffer %d bytes to %d.", nBufReceiveTmp, *nBufReceive + nBufReceiveTmp + 1); *szBufReceive = realloc(*szBufReceive, *nBufReceive + nBufReceiveTmp + 1); } memcpy(*szBufReceive + *nBufReceive, szBufReceiveTmp, nBufReceiveTmp); *nBufReceive += nBufReceiveTmp; nBufReceiveTmp = 0; free(szBufReceiveTmp); } else { /* no additional data found... let's check it a few times */ writeError(ERR_DEBUG, "No additional data found (attempt %d/5)", nAttempt); nAttempt++; } } else { regfree(&preg); writeError(ERR_DEBUG, "Successfully matched regex."); return SUCCESS; } } while (nAttempt <= 5); regfree(&preg); writeError(ERR_ERROR, "Failed to match regex pattern within server's response."); return FAILURE; } int medusaSend(int socket, unsigned char *buf, int size, int options) { char debugbuf[size + 1]; int k; memset(debugbuf, 0, size + 1); for (k = 0; k < size; k++) if (buf[k] == 0) debugbuf[k] = 32; else debugbuf[k] = buf[k]; writeError(ERR_DEBUG, "Data sent: %s", debugbuf); return (medusaSendInternal(socket, buf, size, options)); } int makeToLower(char *buf) { if (buf == NULL) return 1; while (buf[0] != 0) { buf[0] = tolower(buf[0]); buf++; } return 1; } jmk-foofus-medusa-dd62069/src/medusa-net.h000066400000000000000000000057561460263104500204260ustar00rootroot00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSA_NET_H #define _MEDUSA_NET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "medusa.h" #define OPTION_SSL 1 #define MAX_CONNECT_RETRY 3 #define WAIT_BETWEEN_CONNECT_RETRY 3 #define DEFAULT_WAIT_TIME 3 // 3 second max wait on connects #define READ_WAIT_TIME 20 * 1000000 // Time to wait for a receive in microseconds typedef struct __sConnectParams { long nHost; int nPort; int nUseSSL; float nSSLVersion; int nProtocol; int nType; unsigned long nProxyStringIP; int nProxyStringPort; char* szProxyAuthentication; int nTimeout; int nRetries; int nRetryWait; int nSourcePort; } sConnectParams; extern int medusaConnect(sConnectParams* pParams); extern int medusaConnectSSL(sConnectParams* pParams); extern int medusaConnectSocketSSL(sConnectParams* pParams, int hSocket); extern int medusaConnectTCP(sConnectParams* pParams); extern int medusaConnectUDP(sConnectParams* pParams); extern int medusaDisconnect(int socket); extern int medusaDataReadyWritingTimed(int socket, time_t sec, time_t usec); extern int medusaDataReadyWriting(int socket); extern int medusaDataReadyTimed(int socket, time_t sec, time_t usec); extern int medusaDataReady(int socket); extern int medusaCheckSocket(int socket, int usec); extern int medusaReceive(int socket, unsigned char *buf, int length); extern unsigned char* medusaReceiveRaw(int socket, int* nBufferSize); extern unsigned char* medusaReceiveRawDelay(int socket, int* nBufferSize, int nReceiveDelay1, int nReceiveDelay2); extern unsigned char* medusaReceiveLine(int socket, int* nBufferSize); extern unsigned char* medusaReceiveLineDelay(int socket, int* nBufferSize, int nReceiveDelay, int nReceiveDelay2); extern int medusaReceiveRegex(int hSocket, unsigned char **szBufReceive, int* nBufReceive, const char* regex); extern int medusaSend(int socket, unsigned char *buf, int size, int options); extern int makeToLower(char *buf); #endif jmk-foofus-medusa-dd62069/src/medusa-thread-pool.c000066400000000000000000000302631460263104500220400ustar00rootroot00000000000000/* * * Thread Pool Implementation * Based on Sun Microsystems, Inc. "Multithreaded Programming Guide" * http://docs.sun.com/app/docs/doc/816-5137/ggedn?a=view * * See for interface declarations. */ #if !defined(_REENTRANT) #define _REENTRANT #endif //#include "medusa-thread-pool.h" #include "medusa.h" #include #include #include /* * FIFO queued job */ typedef struct job job_t; struct job { job_t *job_next; /* linked list of jobs */ void *(*job_func)(void *); /* function to call */ void *job_arg; /* its argument */ }; /* * List of active worker threads, linked through their stacks. */ typedef struct active active_t; struct active { active_t *active_next; /* linked list of threads */ pthread_t active_tid; /* active thread id */ }; /* * The thread pool, opaque to the clients. */ struct thr_pool { thr_pool_t *pool_forw; /* circular linked list */ thr_pool_t *pool_back; /* of all thread pools */ pthread_mutex_t pool_mutex; /* protects the pool data */ pthread_cond_t pool_busycv; /* synchronization in pool_queue */ pthread_cond_t pool_workcv; /* synchronization with workers */ pthread_cond_t pool_waitcv; /* synchronization in pool_wait() */ active_t *pool_active; /* list of threads performing work */ job_t *pool_head; /* head of FIFO job queue */ job_t *pool_tail; /* tail of FIFO job queue */ pthread_attr_t pool_attr; /* attributes of the workers */ int pool_flags; /* see below */ uint_t pool_linger; /* seconds before idle workers exit */ int pool_minimum; /* minimum number of worker threads */ int pool_maximum; /* maximum number of worker threads */ int pool_nthreads; /* current number of worker threads */ int pool_idle; /* number of idle workers */ }; /* pool_flags */ #define POOL_WAIT 0x01 /* waiting in thr_pool_wait() */ #define POOL_DESTROY 0x02 /* pool is being destroyed */ /* the list of all created and not yet destroyed thread pools */ static thr_pool_t *thr_pools = NULL; /* protects thr_pools */ static pthread_mutex_t thr_pool_lock = PTHREAD_MUTEX_INITIALIZER; /* set of all signals */ static sigset_t fillset; static void *worker_thread(void *); static int create_worker(thr_pool_t *pool) { sigset_t oset; int error; /* jmk - The original code passed NULL to pthread_create for thread ID. This appears to cause segfaults on Linux... */ pthread_t *ppthread; ppthread = malloc( sizeof(pthread_t) ); memset(ppthread, 0, sizeof(pthread_t)); (void) pthread_sigmask(SIG_SETMASK, &fillset, &oset); error = pthread_create(ppthread, &pool->pool_attr, worker_thread, pool); (void) pthread_sigmask(SIG_SETMASK, &oset, NULL); free(ppthread); return (error); } /* * Worker thread is terminating. Possible reasons: * - excess idle thread is terminating because there is no work. * - thread was cancelled (pool is being destroyed). * - the job function called pthread_exit(). * In the last case, create another worker thread * if necessary to keep the pool populated. */ static void worker_cleanup(thr_pool_t *pool) { --pool->pool_nthreads; if (pool->pool_flags & POOL_DESTROY) { if (pool->pool_nthreads == 0) (void) pthread_cond_broadcast(&pool->pool_busycv); } else if (pool->pool_head != NULL && pool->pool_nthreads < pool->pool_maximum && create_worker(pool) == 0) { pool->pool_nthreads++; } (void) pthread_mutex_unlock(&pool->pool_mutex); } static void notify_waiters(thr_pool_t *pool) { if (pool->pool_head == NULL && pool->pool_active == NULL) { pool->pool_flags &= ~POOL_WAIT; (void) pthread_cond_broadcast(&pool->pool_waitcv); } } /* * Called by a worker thread on return from a job. */ static void job_cleanup(thr_pool_t *pool) { pthread_t my_tid = pthread_self(); active_t *activep; active_t **activepp; (void) pthread_mutex_lock(&pool->pool_mutex); for (activepp = &pool->pool_active; (activep = *activepp) != NULL; activepp = &activep->active_next) { if (activep->active_tid == my_tid) { *activepp = activep->active_next; break; } } if (pool->pool_flags & POOL_WAIT) notify_waiters(pool); } static void * worker_thread(void *arg) { thr_pool_t *pool = (thr_pool_t *)arg; int timedout; job_t *job; void *(*func)(void *); active_t active; struct timespec ts; #ifndef HAVE_CLOCK_GETTIME struct timeval tv; #endif /* * This is the worker's main loop. It will only be left * if a timeout occurs or if the pool is being destroyed. */ (void) pthread_mutex_lock(&pool->pool_mutex); pthread_cleanup_push((void *)worker_cleanup, pool); active.active_tid = pthread_self(); for (;;) { /* * We don't know what this thread was doing during * its last job, so we reset its signal mask and * cancellation state back to the initial values. */ (void) pthread_sigmask(SIG_SETMASK, &fillset, NULL); (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); (void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); timedout = 0; pool->pool_idle++; if (pool->pool_flags & POOL_WAIT) notify_waiters(pool); while (pool->pool_head == NULL && !(pool->pool_flags & POOL_DESTROY)) { if (pool->pool_nthreads <= pool->pool_minimum) { (void) pthread_cond_wait(&pool->pool_workcv, &pool->pool_mutex); } else { #ifndef HAVE_CLOCK_GETTIME gettimeofday(&tv, NULL); ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; #else (void) clock_gettime(CLOCK_REALTIME, &ts); #endif ts.tv_sec += pool->pool_linger; if (pool->pool_linger == 0 || pthread_cond_timedwait(&pool->pool_workcv, &pool->pool_mutex, &ts) == ETIMEDOUT) { timedout = 1; break; } } } pool->pool_idle--; if (pool->pool_flags & POOL_DESTROY) break; if ((job = pool->pool_head) != NULL) { timedout = 0; func = job->job_func; arg = job->job_arg; pool->pool_head = job->job_next; if (job == pool->pool_tail) pool->pool_tail = NULL; active.active_next = pool->pool_active; pool->pool_active = &active; (void) pthread_mutex_unlock(&pool->pool_mutex); pthread_cleanup_push((void *)job_cleanup, pool); free(job); /* * Call the specified job function. */ (void) func(arg); /* * If the job function calls pthread_exit(), the thread * calls job_cleanup(pool) and worker_cleanup(pool); * the integrity of the pool is thereby maintained. */ pthread_cleanup_pop(1); /* job_cleanup(pool) */ } if (timedout && pool->pool_nthreads > pool->pool_minimum) { /* * We timed out and there is no work to be done * and the number of workers exceeds the minimum. * Exit now to reduce the size of the pool. */ break; } } pthread_cleanup_pop(1); /* worker_cleanup(pool) */ return (NULL); } static void clone_attributes(pthread_attr_t *new_attr, pthread_attr_t *old_attr) { struct sched_param param; void *addr; size_t size; int value; (void) pthread_attr_init(new_attr); if (old_attr != NULL) { (void) pthread_attr_getstack(old_attr, &addr, &size); /* don't allow a non-NULL thread stack address */ (void) pthread_attr_setstack(new_attr, NULL, size); (void) pthread_attr_getscope(old_attr, &value); (void) pthread_attr_setscope(new_attr, value); (void) pthread_attr_getinheritsched(old_attr, &value); (void) pthread_attr_setinheritsched(new_attr, value); (void) pthread_attr_getschedpolicy(old_attr, &value); (void) pthread_attr_setschedpolicy(new_attr, value); (void) pthread_attr_getschedparam(old_attr, ¶m); (void) pthread_attr_setschedparam(new_attr, ¶m); (void) pthread_attr_getguardsize(old_attr, &size); (void) pthread_attr_setguardsize(new_attr, size); } /* make all pool threads be detached threads */ (void) pthread_attr_setdetachstate(new_attr, PTHREAD_CREATE_DETACHED); } thr_pool_t * thr_pool_create(uint_t min_threads, uint_t max_threads, uint_t linger, pthread_attr_t *attr) { thr_pool_t *pool; (void) sigfillset(&fillset); if (min_threads > max_threads || max_threads < 1) { errno = EINVAL; return (NULL); } if ((pool = malloc(sizeof (*pool))) == NULL) { errno = ENOMEM; return (NULL); } (void) pthread_mutex_init(&pool->pool_mutex, NULL); (void) pthread_cond_init(&pool->pool_busycv, NULL); (void) pthread_cond_init(&pool->pool_workcv, NULL); (void) pthread_cond_init(&pool->pool_waitcv, NULL); pool->pool_active = NULL; pool->pool_head = NULL; pool->pool_tail = NULL; pool->pool_flags = 0; pool->pool_linger = linger; pool->pool_minimum = min_threads; pool->pool_maximum = max_threads; pool->pool_nthreads = 0; pool->pool_idle = 0; /* * We cannot just copy the attribute pointer. * We need to initialize a new pthread_attr_t structure using * the values from the caller-supplied attribute structure. * If the attribute pointer is NULL, we need to initialize * the new pthread_attr_t structure with default values. */ clone_attributes(&pool->pool_attr, attr); /* insert into the global list of all thread pools */ (void) pthread_mutex_lock(&thr_pool_lock); if (thr_pools == NULL) { pool->pool_forw = pool; pool->pool_back = pool; thr_pools = pool; } else { thr_pools->pool_back->pool_forw = pool; pool->pool_forw = thr_pools; pool->pool_back = thr_pools->pool_back; thr_pools->pool_back = pool; } (void) pthread_mutex_unlock(&thr_pool_lock); return (pool); } int thr_pool_queue(thr_pool_t *pool, void *func, void *arg) { job_t *job; if ((job = malloc(sizeof (*job))) == NULL) { errno = ENOMEM; return (-1); } job->job_next = NULL; job->job_func = func; job->job_arg = arg; (void) pthread_mutex_lock(&pool->pool_mutex); if (pool->pool_head == NULL) pool->pool_head = job; else pool->pool_tail->job_next = job; pool->pool_tail = job; if (pool->pool_idle > 0) (void) pthread_cond_signal(&pool->pool_workcv); else if (pool->pool_nthreads < pool->pool_maximum && create_worker(pool) == 0) pool->pool_nthreads++; (void) pthread_mutex_unlock(&pool->pool_mutex); return (0); } void thr_pool_wait(thr_pool_t *pool) { (void) pthread_mutex_lock(&pool->pool_mutex); pthread_cleanup_push((void *)pthread_mutex_unlock, &pool->pool_mutex); while (pool->pool_head != NULL || pool->pool_active != NULL) { pool->pool_flags |= POOL_WAIT; (void) pthread_cond_wait(&pool->pool_waitcv, &pool->pool_mutex); } pthread_cleanup_pop(1); /* pthread_mutex_unlock(&pool->pool_mutex); */ } void thr_pool_destroy(thr_pool_t *pool) { active_t *activep; job_t *job; (void) pthread_mutex_lock(&pool->pool_mutex); pthread_cleanup_push((void *)pthread_mutex_unlock, &pool->pool_mutex); /* mark the pool as being destroyed; wakeup idle workers */ pool->pool_flags |= POOL_DESTROY; (void) pthread_cond_broadcast(&pool->pool_workcv); /* cancel all active workers */ for (activep = pool->pool_active; activep != NULL; activep = activep->active_next) (void) pthread_cancel(activep->active_tid); /* wait for all active workers to finish */ while (pool->pool_active != NULL) { pool->pool_flags |= POOL_WAIT; (void) pthread_cond_wait(&pool->pool_waitcv, &pool->pool_mutex); } /* the last worker to terminate will wake us up */ while (pool->pool_nthreads != 0) (void) pthread_cond_wait(&pool->pool_busycv, &pool->pool_mutex); pthread_cleanup_pop(1); /* pthread_mutex_unlock(&pool->pool_mutex); */ /* * Unlink the pool from the global list of all pools. */ (void) pthread_mutex_lock(&thr_pool_lock); if (thr_pools == pool) thr_pools = pool->pool_forw; if (thr_pools == pool) thr_pools = NULL; else { pool->pool_back->pool_forw = pool->pool_forw; pool->pool_forw->pool_back = pool->pool_back; } (void) pthread_mutex_unlock(&thr_pool_lock); /* * There should be no pending jobs, but just in case... */ for (job = pool->pool_head; job != NULL; job = pool->pool_head) { pool->pool_head = job->job_next; free(job); } (void) pthread_attr_destroy(&pool->pool_attr); free(pool); } jmk-foofus-medusa-dd62069/src/medusa-thread-pool.h000066400000000000000000000040251460263104500220420ustar00rootroot00000000000000/* * * Thread Pool Implementation * Based on Sun Microsystems, Inc. "Multithreaded Programming Guide" * http://docs.sun.com/app/docs/doc/816-5137/ggedn?a=view * * Declarations for the clients of a thread pool. */ #include typedef unsigned int uint_t; /* * The thr_pool_t type is opaque to the client. * It is created by thr_pool_create() and must be passed * unmodified to the remainder of the interfaces. */ typedef struct thr_pool thr_pool_t; /* * Create a thread pool. * min_threads: the minimum number of threads kept in the pool, * always available to perform work requests. * max_threads: the maximum number of threads that can be * in the pool, performing work requests. * linger: the number of seconds excess idle worker threads * (greater than min_threads) linger before exiting. * attr: attributes of all worker threads (can be NULL); * can be destroyed after calling thr_pool_create(). * On error, thr_pool_create() returns NULL with errno set to the error code. */ extern thr_pool_t *thr_pool_create(uint_t min_threads, uint_t max_threads, uint_t linger, pthread_attr_t *attr); /* * Enqueue a work request to the thread pool job queue. * If there are idle worker threads, awaken one to perform the job. * Else if the maximum number of workers has not been reached, * create a new worker thread to perform the job. * Else just return after adding the job to the queue; * an existing worker thread will perform the job when * it finishes the job it is currently performing. * * The job is performed as if a new detached thread were created for it: * pthread_create(NULL, attr, void *(*func)(void *), void *arg); * * On error, thr_pool_queue() returns -1 with errno set to the error code. */ extern int thr_pool_queue(thr_pool_t *pool, void *func, void *arg); /* * Wait for all queued jobs to complete. */ extern void thr_pool_wait(thr_pool_t *pool); /* * Cancel all queued jobs and destroy the pool. */ extern void thr_pool_destroy(thr_pool_t *pool); jmk-foofus-medusa-dd62069/src/medusa-thread-ssl.c000066400000000000000000000042061460263104500216660ustar00rootroot00000000000000/* * * Functions to enable multi-threaded use of crypto libraries. * * OpenSSL -- http://www.openssl.org/docs/crypto/threads.html * Libgcrypt -- http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html * * This code is based on Curl 7.21.1 * * See for interface declarations. * */ #include "medusa.h" /* In OpenSSL <= 1.0.2, an application had to set locking callbacks to use OpenSSL in a multi-threaded environment. OpenSSL 1.1.0 now finds pthreads or Windows threads, so nothing special is necessary. */ #if defined(HAVE_LIBSSL) && (OPENSSL_VERSION_NUMBER < 0x10100005L) static pthread_mutex_t *lockarray; #include static void lock_callback(int mode, int type, char *file, int line) { (void)file; (void)line; if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&(lockarray[type])); } else { pthread_mutex_unlock(&(lockarray[type])); } } static unsigned long thread_id(void) { unsigned long ret; ret=(unsigned long)pthread_self(); return(ret); } void init_locks_openssl(void) { int i; lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); for (i=0; i #include GCRY_THREAD_OPTION_PTHREAD_IMPL; void init_locks_gnutls(void) { gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); gnutls_global_init(); } #endif void init_crypto_locks(void) { #if defined(HAVE_LIBSSL) && (OPENSSL_VERSION_NUMBER < 0x10100005L) init_locks_openssl(); #endif #ifdef HAVE_GNUTLS init_locks_gnutls(); #endif } void kill_crypto_locks(void) { #if defined(HAVE_LIBSSL) && (OPENSSL_VERSION_NUMBER < 0x10100005L) kill_locks_openssl(); #endif } jmk-foofus-medusa-dd62069/src/medusa-thread-ssl.h000066400000000000000000000004601460263104500216710ustar00rootroot00000000000000/* * * Functions to enable multi-threaded use of crypto libraries. * * OpenSSL -- http://www.openssl.org/docs/crypto/threads.html * Libgcrypt -- http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html * */ extern void init_crypto_locks(void); extern void kill_crypto_locks(void); jmk-foofus-medusa-dd62069/src/medusa-trace.c000066400000000000000000000133271460263104500207220ustar00rootroot00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #include #include #include #include #include "medusa.h" #include "medusa-trace.h" #include #include #include void writeVerbose(int iLevel, char *pMsg, ...) { va_list ap; char buf[512]; char bufOut[2049]; // 1 character is represented by 4 -- [01] char temp[6]; unsigned char cTemp; unsigned int i = 0; struct tm *tm_ptr; time_t the_time; char time_buf[256]; if (pMsg == NULL) { fprintf(stderr, "CRITICAL: writeDebug() called with NULL message.\n"); } else if (iLevel <= iVerboseLevel) { va_start(ap, pMsg); memset(bufOut, 0, sizeof(bufOut)); memset(buf, 0, sizeof(buf)); vsnprintf(buf, sizeof(buf) - 1, pMsg, ap); /* Convert specific non-printable characters to HEX Non-printable: < 32d or > 126d Ignore: \n, \r and TAB */ for (i = 0; i < sizeof(buf); i++) { memset(temp, 0, 6); cTemp = (unsigned char)buf[i]; if ((cTemp < 32 && cTemp > 0 && cTemp != 9 && cTemp != 10 && cTemp != 13) || cTemp > 126) { sprintf(temp, "[%02X]", cTemp); } else sprintf(temp, "%c", cTemp); strncat(bufOut, temp, 6); } (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); switch (iLevel) { case VB_FOUND: fprintf(stdout, "%s ACCOUNT FOUND: %s\n", time_buf, bufOut); if (pOutputFile != NULL) { pthread_mutex_lock(&ptmFileMutex); fprintf(pOutputFile, "%s ACCOUNT FOUND: %s\n", time_buf, buf); fflush(pOutputFile); pthread_mutex_unlock(&ptmFileMutex); } va_end(ap); break; case VB_CHECK: fprintf(stdout, "%s ACCOUNT CHECK: %s\n", time_buf, bufOut); va_end(ap); break; case VB_IMPORTANT: fprintf(stdout, "IMPORTANT: %s\n", bufOut); va_end(ap); break; case VB_GENERAL: fprintf(stdout, "GENERAL: %s\n", bufOut); va_end(ap); break; case VB_NONE: fprintf(stdout, "%s\n", bufOut); va_end(ap); break; case VB_NONE_FILE: if (pOutputFile != NULL) { pthread_mutex_lock(&ptmFileMutex); fprintf(pOutputFile, "%s", bufOut); fflush(pOutputFile); pthread_mutex_unlock(&ptmFileMutex); } va_end(ap); break; case VB_EXIT: fprintf(stdout, "%s\n", bufOut); va_end(ap); exit(EXIT_SUCCESS); break; default: fprintf(stdout, "UNKNOWN: %s\n", bufOut); va_end(ap); break; } } return; } void writeError(int iLevel, char *pMsg, ...) { va_list ap; char buf[4096]; char bufOut[16384]; char temp[6]; unsigned char cTemp; unsigned int i = 0, len; if (pMsg == NULL) { fprintf(stderr, "CRITICAL: writeError() called with NULL message.\n"); } else if (iLevel <= iErrorLevel) { va_start(ap, pMsg); memset(bufOut, 0, sizeof(bufOut)); memset(buf, 0, sizeof(buf)); len = vsnprintf(buf, sizeof(buf), pMsg, ap); // Convert any chars less than 32d or greater than 126d to hex for (i = 0; i < len; i++) { memset(temp, 0, 6); cTemp = (unsigned char)buf[i]; if ((cTemp < 32 && cTemp >= 0) || cTemp > 126) { snprintf(temp, 6, "[%02X]", cTemp); } else snprintf(temp, 6, "%c", cTemp); strncat(bufOut, temp, 6); } switch (iLevel) { case ERR_FATAL: fprintf(stderr, "FATAL: %s\n", bufOut); va_end(ap); exit(EXIT_FAILURE); break; case ERR_ALERT: fprintf(stderr, "ALERT: "); break; case ERR_CRITICAL: fprintf(stderr, "CRITICAL: "); break; case ERR_ERROR: fprintf(stderr, "ERROR: "); break; case ERR_WARNING: fprintf(stderr, "WARNING: "); break; case ERR_NOTICE: fprintf(stderr, "NOTICE: "); break; case ERR_INFO: fprintf(stderr, "INFO: "); break; case ERR_DEBUG: fprintf(stderr, "DEBUG [%X]: ", (int)pthread_self()); break; case ERR_DEBUG_AUDIT: fprintf(stderr, "DEBUG AUDIT [%X]: ", (int)pthread_self()); break; case ERR_DEBUG_SERVER: fprintf(stderr, "DEBUG SERVER [%X]: ", (int)pthread_self()); break; case ERR_DEBUG_MODULE: fprintf(stderr, "DEBUG MODULE [%X]: ", (int)pthread_self()); break; default: fprintf(stdout, "UNKNOWN ERROR [%X]: ", (int)pthread_self()); break; } fprintf(stderr, "%s\n", bufOut); va_end(ap); } return; } void writeErrorBin(int iLevel, char *pMsg, unsigned char *pData, int iLength) { int i; if (iLevel <= iErrorLevel) { fprintf(stderr, "DATA: %s ", pMsg); for(i=0; i> 2]; *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)]; *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)]; *p++ = tbl[s[2] & 0x3f]; s += 3; } /* Pad the result if necessary... */ if (i == length + 1) *(p - 1) = '='; else if (i == length + 2) *(p - 1) = *(p - 2) = '='; /* ...and zero-terminate it. */ *p = '\0'; return p - b64store; } #define IS_ASCII(c) (((c) & 0x80) == 0) #define IS_BASE64(c) ((IS_ASCII (c) && base64_char_to_value[c] >= 0) || c == '=') /* Get next character from the string, except that non-base64 characters are ignored, as mandated by rfc2045. */ #define NEXT_BASE64_CHAR(c, p) do { \ c = *p++; \ } while (c != '\0' && !IS_BASE64 (c)) /* Decode data from BASE64 (assumed to be encoded as base64) into memory pointed to by TO. TO should be large enough to accomodate the decoded data, which is guaranteed to be less than strlen(base64). Since TO is assumed to contain binary data, it is not NUL-terminated. The function returns the length of the data written to TO. -1 is returned in case of error caused by malformed base64 input. */ int base64_decode (const char *base64, char *to) { /* Table of base64 values for first 128 characters. Note that this assumes ASCII (but so does Wget in other places). */ static short base64_char_to_value[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */ -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */ 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */ -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */ 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */ 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */ }; const char *p = base64; char *q = to; while (1) { unsigned char c; unsigned long value; /* Process first byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) break; if (c == '=') return -1; /* illegal '=' while decoding base64 */ value = base64_char_to_value[c] << 18; /* Process scond byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c == '=') return -1; /* illegal `=' while decoding base64 */ value |= base64_char_to_value[c] << 12; *q++ = value >> 16; /* Process third byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c == '=') { NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c != '=') return -1; /* padding `=' expected but not found */ continue; } value |= base64_char_to_value[c] << 6; *q++ = 0xff & value >> 8; /* Process fourth byte of a quadruplet. */ NEXT_BASE64_CHAR (c, p); if (!c) return -1; /* premature EOF while decoding base64 */ if (c == '=') continue; value |= base64_char_to_value[c]; *q++ = 0xff & value; } return q - to; } /* Create the authentication header contents for the `Basic' scheme. This is done by encoding the string "USER:PASS" to base64 and prepending the string "Basic " in front of it. */ char *basic_authentication_encode(const char *user, const char *passwd) { char *t1, *t2; int len1 = strlen (user) + 1 + strlen (passwd); t1 = (char *)alloca (len1 + 1); sprintf (t1, "%s:%s", user, passwd); t2 = (char *)malloc (BASE64_LENGTH (len1) + 1); base64_encode (t1, len1, t2); return (t2); } /* End Wget Base64 Functions */ /* Solaris doesn't have a strcasestr */ #ifndef HAVE_STRCASESTR char *strcasestr(const char *a, const char *b) { size_t l; char f[3]; snprintf(f, sizeof(f), "%c%c", tolower(*b), toupper(*b)); for (l = strcspn(a, f); l != strlen(a); l += strcspn(a + l + 1, f) + 1) if (strncasecmp(a + l, b, strlen(b)) == 0) return((char *) a + l); return(NULL); } #endif /* Solaris (10x86, at least) does not appear to have asprintf/vasprintf functions Function code taken from ndoutils_sunos.c */ #ifndef HAVE_VASPRINTF #define CHUNKSIZE 512 int vasprintf(char **ret, const char *fmt, va_list ap) { int chunks; size_t buflen; char *buf; int len; chunks = ((strlen(fmt) + 1) / CHUNKSIZE) + 1; buflen = chunks * CHUNKSIZE; for (;;) { if ((buf = malloc(buflen)) == NULL) { *ret = NULL; return -1; } len = vsnprintf(buf, buflen, fmt, ap); if (len >= 0 && len < (buflen - 1)) { break; } free(buf); buflen = (++chunks) * CHUNKSIZE; /* * len >= 0 are required for vsnprintf implementation that * return -1 of buffer insufficient */ if (len >= 0 && len >= buflen) { buflen = len + 1; } } *ret = buf; return len; FILE *fp; *ret = NULL; } #endif #ifndef HAVE_ASPRINTF int asprintf(char **ret, const char *fmt, ...) { int len; va_list ap; va_start(ap, fmt); len = vasprintf(ret, fmt, ap); va_end(ap); return len; } #endif jmk-foofus-medusa-dd62069/src/medusa-utils.h000066400000000000000000000023561460263104500207710ustar00rootroot00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSA_UTILS_H #define _MEDUSA_UTILS_H /* How many bytes it will take to store LEN bytes in base64. */ #define BASE64_LENGTH(len) (4 * (((len) + 2) / 3)) extern int base64_encode(const char *str, int length, char *b64store); extern int base64_decode(const char *base64, char *to); extern char *basic_authentication_encode(const char *user, const char *passwd); /* solaris doesn't have a strcasestr */ #ifndef HAVE_STRCASESTR char *strcasestr(const char *, const char *); #endif #endif jmk-foofus-medusa-dd62069/src/medusa.c000066400000000000000000002110301460263104500176150ustar00rootroot00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * * Based on ideas from Hydra 3.1 by VanHauser [vh@thc.org] * Do only use for legal purposes. Illegal purposes cost $1 each. * */ #define VERSION_SVN "$Id: medusa.c 9217 2015-05-07 18:07:03Z jmk $" #include #include "medusa.h" #include "modsrc/module.h" char* szModuleName; char* szTempModuleParam; char* szModulePaths[3] = {"a", "b", "c"}; // will look at 3 different locations for modules if possible char** arrModuleParams; // the "argv" for the module int nModuleParamCount; // the "argc" for the module //int ctrlc = 0; sAudit *psAudit = NULL; int iVerboseLevel; int iErrorLevel; FILE *pOutputFile; pthread_mutex_t ptmFileMutex; void freeModuleParams() { int i; for (i = 0; i < nModuleParamCount; i++) { free(arrModuleParams[i]); } free(arrModuleParams); } /* Display appropriate usage information for application. */ void usage() { writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Syntax: %s [-h host|-H file] [-u username|-U file] [-p password|-P file] [-C file] -M module [OPT]", PROGRAM); writeVerbose(VB_NONE, " -h [TEXT] : Target hostname or IP address"); writeVerbose(VB_NONE, " -H [FILE] : File containing target hostnames or IP addresses"); writeVerbose(VB_NONE, " -u [TEXT] : Username to test"); writeVerbose(VB_NONE, " -U [FILE] : File containing usernames to test"); writeVerbose(VB_NONE, " -p [TEXT] : Password to test"); writeVerbose(VB_NONE, " -P [FILE] : File containing passwords to test"); writeVerbose(VB_NONE, " -C [FILE] : File containing combo entries. See README for more information."); writeVerbose(VB_NONE, " -O [FILE] : File to append log information to"); writeVerbose(VB_NONE, " -e [n/s/ns] : Additional password checks ([n] No Password, [s] Password = Username)"); writeVerbose(VB_NONE, " -M [TEXT] : Name of the module to execute (without the .mod extension)"); writeVerbose(VB_NONE, " -m [TEXT] : Parameter to pass to the module. This can be passed multiple times with a"); writeVerbose(VB_NONE, " different parameter each time and they will all be sent to the module (i.e."); writeVerbose(VB_NONE, " -m Param1 -m Param2, etc.)"); writeVerbose(VB_NONE, " -d : Dump all known modules"); writeVerbose(VB_NONE, " -n [NUM] : Use for non-default TCP port number"); writeVerbose(VB_NONE, " -s : Enable SSL"); writeVerbose(VB_NONE, " -g [NUM] : Give up after trying to connect for NUM seconds (default 3)"); writeVerbose(VB_NONE, " -r [NUM] : Sleep NUM seconds between retry attempts (default 3)"); writeVerbose(VB_NONE, " -R [NUM] : Attempt NUM retries before giving up. The total number of attempts will be NUM + 1."); writeVerbose(VB_NONE, " -c [NUM] : Time to wait in usec to verify socket is available (default 500 usec)."); writeVerbose(VB_NONE, " -t [NUM] : Total number of logins to be tested concurrently"); writeVerbose(VB_NONE, " -T [NUM] : Total number of hosts to be tested concurrently"); writeVerbose(VB_NONE, " -L : Parallelize logins using one username per thread. The default is to process "); writeVerbose(VB_NONE, " the entire username before proceeding."); writeVerbose(VB_NONE, " -f : Stop scanning host after first valid username/password found."); writeVerbose(VB_NONE, " -F : Stop audit after first valid username/password found on any host."); writeVerbose(VB_NONE, " -b : Suppress startup banner"); writeVerbose(VB_NONE, " -q : Display module's usage information"); writeVerbose(VB_NONE, " -v [NUM] : Verbose level [0 - 6 (more)]"); writeVerbose(VB_NONE, " -w [NUM] : Error debug level [0 - 10 (more)]"); writeVerbose(VB_NONE, " -V : Display version"); writeVerbose(VB_NONE, " -Z [TEXT] : Resume scan based on map of previous scan"); writeVerbose(VB_NONE, "\n"); return; } /* Read user options and check validity. */ int checkOptions(int argc, char **argv, sAudit *_psAudit) { int opt; extern char *optarg; extern int opterr; int ret = 0; int i = 0; int nIgnoreBanner = 0; /* initialize options */ _psAudit->iServerCnt = 1; _psAudit->iLoginCnt = 1; _psAudit->iParallelLoginFlag = PARALLEL_LOGINS_PASSWORD; _psAudit->iPortOverride = 0; /* Use default port */ _psAudit->iUseSSL = 0; /* No SSL */ _psAudit->iTimeout = DEFAULT_WAIT_TIME; /* Default wait of 3 seconds */ _psAudit->iRetryWait = WAIT_BETWEEN_CONNECT_RETRY; /* Default wait of 3 seconds */ _psAudit->iRetries = MAX_CONNECT_RETRY; /* Default of 2 retries (3 total attempts) */ _psAudit->iSocketWait = 500; /* Default wait of 500 usec */ _psAudit->iShowModuleHelp = 0; iVerboseLevel = 5; iErrorLevel = 5; for (i =0; i < argc; i++) { if (strstr(argv[i], "-b") != NULL) { nIgnoreBanner = 1; break; } } if (nIgnoreBanner == 0) writeVerbose(VB_NONE, "%s v%s [%s] (C) %s %s\n", PROGRAM, VERSION, WWW, AUTHOR, EMAIL); while ((opt = getopt(argc, argv, "h:H:u:U:p:P:C:O:e:M:m:g:r:R:c:t:T:n:bqdsLfFVv:w:Z:")) != EOF) { switch (opt) { case 'h': if (_psAudit->HostType) { writeError(ERR_ALERT, "Options 'h' and 'H' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pGlobalHost = strdup(optarg); _psAudit->HostType = L_SINGLE; } break; case 'H': if (_psAudit->HostType) { writeError(ERR_ALERT, "Options 'h' and 'H' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pOptHost = strdup(optarg); _psAudit->HostType = L_FILE; } break; case 'u': if (_psAudit->UserType) { writeError(ERR_ALERT, "Options 'u' and 'U' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pGlobalUser = strdup(optarg); _psAudit->UserType = L_SINGLE; _psAudit->iUserCnt = 1; } break; case 'U': if (_psAudit->UserType) { writeError(ERR_ALERT, "Options 'u' and 'U' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pOptUser = strdup(optarg); _psAudit->UserType = L_FILE; } break; case 'p': if (_psAudit->PassType) { writeError(ERR_ALERT, "Options 'p' and 'P' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pGlobalPass = malloc( strlen(optarg) + 2 ); memset(_psAudit->pGlobalPass, 0, strlen(optarg) + 2); strcpy(_psAudit->pGlobalPass, optarg); _psAudit->PassType = L_SINGLE; _psAudit->iPassCnt = 1; } break; case 'P': if (_psAudit->PassType) { writeError(ERR_ALERT, "Options 'p' and 'P' are mutually exclusive."); ret = EXIT_FAILURE; } else { _psAudit->pOptPass = strdup(optarg); _psAudit->PassType = L_FILE; } break; case 'C': _psAudit->pOptCombo = strdup(optarg); break; case 'O': _psAudit->pOptOutput = strdup(optarg); break; case 'e': if (strcmp(optarg, "n") == 0) { _psAudit->iPasswordBlankFlag = TRUE; _psAudit->iPasswordUsernameFlag = FALSE; } else if (strcmp(optarg, "s") == 0) { _psAudit->iPasswordBlankFlag = FALSE; _psAudit->iPasswordUsernameFlag = TRUE; } else if ((strcmp(optarg, "ns") == 0) || (strcmp(optarg, "sn") == 0)) { _psAudit->iPasswordBlankFlag = TRUE; _psAudit->iPasswordUsernameFlag = TRUE; } else { writeError(ERR_ALERT, "Option 'e' requires value of n, s, or ns."); ret = EXIT_FAILURE; } break; case 's': _psAudit->iUseSSL = 1; break; case 'L': _psAudit->iParallelLoginFlag = PARALLEL_LOGINS_USER; break; case 'f': _psAudit->iFoundPairExitFlag = FOUND_PAIR_EXIT_HOST; break; case 'F': _psAudit->iFoundPairExitFlag = FOUND_PAIR_EXIT_AUDIT; break; case 't': _psAudit->iLoginCnt = atoi(optarg); break; case 'T': _psAudit->iServerCnt = atoi(optarg); break; case 'n': _psAudit->iPortOverride = atoi(optarg); break; case 'v': iVerboseLevel = atoi(optarg); break; case 'w': iErrorLevel = atoi(optarg); break; case 'V': writeVerbose(VB_EXIT, ""); // Terminate now break; case 'M': szModuleName = strdup(optarg); _psAudit->pModuleName = szModuleName; break; case 'm': nModuleParamCount++; szTempModuleParam = strdup(optarg); arrModuleParams = realloc(arrModuleParams, nModuleParamCount * sizeof(char*)); arrModuleParams[nModuleParamCount - 1] = szTempModuleParam; break; case 'd': listModules(szModulePaths, 1); // End the program after this executes by passing a 1 as the second param break; case 'b': // Do nothing - supression of the startup banner is handled before the switch statement break; case 'q': _psAudit->iShowModuleHelp = 1; break; case 'g': _psAudit->iTimeout = atoi(optarg); break; case 'r': _psAudit->iRetryWait = atoi(optarg); break; case 'R': _psAudit->iRetries = atoi(optarg); break; case 'c': _psAudit->iSocketWait = atoi(optarg); break; case 'Z': _psAudit->pOptResume = strdup(optarg); break; default: writeError(ERR_CRITICAL, "Unknown error processing command-line options."); ret = EXIT_FAILURE; } } if (argc <= 1) { ret = EXIT_FAILURE; } if (_psAudit->iShowModuleHelp) { ret = invokeModule(_psAudit->pModuleName, NULL, 0, NULL); if (ret < 0) { writeError(ERR_CRITICAL, "invokeModule failed - see previous errors for an explanation"); } } else { if ( !((_psAudit->HostType) || (_psAudit->pOptCombo)) ) { writeError(ERR_ALERT, "Host information must be supplied."); ret = EXIT_FAILURE; } else if ( !((_psAudit->UserType) || (_psAudit->pOptCombo)) ) { writeError(ERR_ALERT, "User logon information must be supplied."); ret = EXIT_FAILURE; } else if ( !((_psAudit->PassType) || (_psAudit->pOptCombo) || (_psAudit->iPasswordBlankFlag) || ( _psAudit->iPasswordUsernameFlag)) ) { writeError(ERR_ALERT, "Password information must be supplied."); ret = EXIT_FAILURE; } } return ret; } int invokeModule(char* pModuleName, sLogin* pLogin, int argc, char* argv[]) { void *pLibrary; int iReturn; function_go pGo; function_showUsage pUsage; char* modPath; int nPathLength; int i; int nSuccess = 0; iReturn = -1; pLibrary = NULL; pGo = NULL; pUsage = NULL; if (NULL == pModuleName) { listModules(szModulePaths, 0); writeError(ERR_CRITICAL, "invokeModule called with no name"); return -1; } // Find the first available path to use for(i = 0; i < 3; i++) { if (szModulePaths[i] != NULL) { // Is the module available under here? writeError(ERR_DEBUG, "Trying module path of %s", szModulePaths[i]); nPathLength = strlen(szModulePaths[i]) + strlen(pModuleName) + strlen(MODULE_EXTENSION) + 2; // Going to add a slash too modPath = malloc(nPathLength); memset(modPath, 0, nPathLength); strcpy(modPath, szModulePaths[i]); strcat(modPath, "/"); strcat(modPath, pModuleName); strcat(modPath, MODULE_EXTENSION); // Now try the load writeError(ERR_DEBUG, "Attempting to load %s", modPath); pLibrary = dlopen(modPath, RTLD_NOW); if (pLibrary == NULL) { continue; } else if (!pLogin) { pUsage = (function_showUsage)dlsym(pLibrary, "showUsage"); writeError(ERR_DEBUG, "Attempting to display usage information for module: %s", modPath); if (pUsage == NULL) { writeError(ERR_ALERT, "Couldn't get a pointer to \"showUsage\" for module %s [%s]", modPath, dlerror()); return -1; } else { nSuccess = 1; pUsage(); } dlclose(pLibrary); exit(EXIT_SUCCESS); // TEMP FIX } else { pGo = (function_go)dlsym(pLibrary, "go"); if (pGo == NULL) { writeError(ERR_ALERT, "Couldn't get a pointer to \"go\" for module %s [%s]", modPath, dlerror()); return -1; } else { nSuccess = 1; iReturn = pGo(pLogin, argc, argv); break; } dlclose(pLibrary); } } } if (!nSuccess) { writeVerbose(VB_IMPORTANT, "Couldn't load \"%s\" [%s]. Place the module in the medusa directory, set the MEDUSA_MODULE_NAME environment variable or run the configure script again using --with-default-mod-path=[path].", pModuleName, dlerror()); iReturn = -1; } return iReturn; } /* Read the contents of a user supplied file. Store contents in memory and provide a count of the total file lines processed. */ void loadFile(char *pFile, char **pFileContent, int *iFileCnt) { FILE *pfFile; size_t stFileSize = 0; char tmp[MAX_BUF]; char *ptr; *iFileCnt = 0; if ((pfFile = fopen(pFile, "r")) == NULL) { writeError(ERR_FATAL, "Failed to open file %s - %s", pFile, strerror( errno ) ); } else { /* get file stats */ while (! feof(pfFile) ) { if ( fgets(tmp, MAX_BUF, pfFile) != NULL ) { if (tmp[0] != '\0') { stFileSize += strlen(tmp) + 1; (*iFileCnt)++; } } } rewind(pfFile); *pFileContent = malloc(stFileSize + 1); /* extra end NULL */ if (pFileContent == NULL) { writeError(ERR_FATAL, "Failed to allocate memory for file %s.", pFile); } memset(*pFileContent, 0, stFileSize + 1); ptr = *pFileContent; /* load file into mem */ while (! feof(pfFile) ) { if (fgets(tmp, MAX_BUF, pfFile) != NULL) { /* ignore blank lines */ if ((tmp[0] == '\n') || (tmp[0] == '\r')) { (*iFileCnt)--; writeError(ERR_DEBUG, "Ignoring blank line in file: %s. Resetting total count: %d.", pFile, (*iFileCnt)); } else if (tmp[0] != '\0') { if (tmp[strlen(tmp) - 1] == '\n') tmp[strlen(tmp) - 1] = '\0'; if (tmp[strlen(tmp) - 1] == '\r') tmp[strlen(tmp) - 1] = '\0'; memcpy(ptr, tmp, strlen(tmp) + 1); ptr += strlen(tmp) + 1; } } } *ptr = '\0'; /* extra NULL to identify end of list */ } if((*iFileCnt) == 0) { writeError(ERR_FATAL, "Error loading user supplied file (%s) -- file may be empty.", pFile); } free(pFile); return; } /* Examine the first row of the combo file to determine information provided. Combo files are colon separated and in the following format: host:user:password. If any of the three fields are left empty, the respective information should be provided either as a single global value or as a list in a file. The following combinations are possible in the combo file: 1. foo:bar:fud 2. foo:bar: 3. foo:: 4. :bar:fud 5. :bar: 6. ::fud 7. foo::fud Medusa also supports using PwDump files as a combo file. The format of these files should be user:id:lm:ntlm. We look for ':::' at the end of the first line to determine if the file contains PwDump output. In addition, a LM/NTLM hash pair can be supplied in lieu of a password (e.g. host:user:lm:ntlm). */ int processComboFile(sAudit **_psAudit) { int ret = 0, iColonCount = 0; char *pComboTmp; writeError(ERR_DEBUG, "[processComboFile] Processing user supplied combo file."); pComboTmp = (*_psAudit)->pGlobalCombo; /* PwDump file check */ /* USERNAME:ID:LM HASH:NTLM HASH::: */ writeError(ERR_DEBUG, "[processComboFile] PwDump file check."); while (*pComboTmp != '\0') { if (strcmp(pComboTmp, ":::") == 0) { iColonCount += 3; pComboTmp += 3; } else if (*pComboTmp == ':') { iColonCount++; pComboTmp++; } else { pComboTmp++; } if ((iColonCount == 6) && (*pComboTmp == '\0')) { writeError(ERR_DEBUG, "[processComboFile] Combo format scan detected PwDump file."); if (((*_psAudit)->HostType != L_SINGLE) && ((*_psAudit)->HostType != L_FILE)) { writeError(ERR_FATAL, "Combo format used requires host information via (-h/-H)."); } if (((*_psAudit)->UserType != L_SINGLE) && ((*_psAudit)->UserType != L_FILE)) { (*_psAudit)->UserType = L_PWDUMP; } (*_psAudit)->PassType = L_PWDUMP; return ret; } } if ( ! ((iColonCount == 2) || (iColonCount == 3)) ) { writeError(ERR_DEBUG, "[processComboFile] Number of colons detected in first entry: %d", iColonCount); writeError(ERR_FATAL, "Invalid combo file format."); } pComboTmp = (*_psAudit)->pGlobalCombo; if (*pComboTmp == ':') { /* no host specified */ writeError(ERR_DEBUG, "[processComboFile] No host combo field specified."); if (((*_psAudit)->HostType != L_SINGLE) && ((*_psAudit)->HostType != L_FILE)) { writeError(ERR_FATAL, "Combo format used requires host information via (-h/-H)."); } } else { writeError(ERR_DEBUG, "[processComboFile] Host combo field specified."); (*_psAudit)->HostType = L_COMBO; while (*pComboTmp != ':') { if (pComboTmp == NULL) { writeError(ERR_FATAL, "Failed to process combo file. Incorrect format."); } pComboTmp++; } } pComboTmp++; if (*pComboTmp == ':') { /* no user specified */ writeError(ERR_DEBUG, "[processComboFile] No user combo field specified."); if (((*_psAudit)->UserType != L_SINGLE) && ((*_psAudit)->UserType != L_FILE)) { writeError(ERR_FATAL, "Combo format used requires user information via (-u/-U)."); } } else { writeError(ERR_DEBUG, "[processComboFile] User combo field specified."); (*_psAudit)->UserType = L_COMBO; while (*pComboTmp != ':') { if (pComboTmp == NULL) { writeError(ERR_FATAL, "Failed to process combo file. Incorrect format."); } pComboTmp++; } } pComboTmp++; if (*pComboTmp == '\0') { /* no password specified */ writeError(ERR_DEBUG, "[processComboFile] No password combo field specified."); if (((*_psAudit)->PassType != L_SINGLE) && ((*_psAudit)->PassType != L_FILE) && ((*_psAudit)->iPasswordBlankFlag == FALSE) && ((*_psAudit)->iPasswordUsernameFlag == FALSE)) { writeError(ERR_FATAL, "Combo format used requires password information via (-p/-P)."); } } else { writeError(ERR_DEBUG, "[processComboFile] Password combo field specified."); (*_psAudit)->PassType = L_COMBO; } return ret; } /* Return next user-specified host during audit data table building process. This host information may be a single global entry, from a file containing a list of hosts, or from a combo file. */ char* findNextHost(sAudit *_psAudit, char *_pHost) { if (_psAudit->pGlobalCombo) { writeError(ERR_DEBUG, "[findNextHost] Process global combo file."); /* advance to next entry in combo list */ if ((_psAudit->iUserListFlag == LIST_COMPLETE) && (_psAudit->iHostListFlag == LIST_COMPLETE)) { writeError(ERR_DEBUG, "[findNextHost] Advance to next entry in combo list."); /* skip host */ while (*_psAudit->pGlobalCombo != '\0') _psAudit->pGlobalCombo++; _psAudit->pGlobalCombo++; /* skip user */ while (*_psAudit->pGlobalCombo != '\0') _psAudit->pGlobalCombo++; _psAudit->pGlobalCombo++; /* skip pass */ while (*_psAudit->pGlobalCombo != '\0') _psAudit->pGlobalCombo++; _psAudit->pGlobalCombo++; if (*_psAudit->pGlobalCombo == '\0') { _psAudit->iAuditFlag = AUDIT_COMPLETE; } else { _psAudit->iAuditFlag = AUDIT_IN_PROGRESS; } } /* convert ':' to '\0' in combo entries */ if ((_psAudit->pComboEntryTmp == NULL) || ((_psAudit->iUserListFlag == LIST_COMPLETE) && (_psAudit->iHostListFlag == LIST_COMPLETE))) { writeError(ERR_DEBUG, "[findNextHost] Convert ':' to '\\0' in combo entries."); _psAudit->pComboEntryTmp = _psAudit->pGlobalCombo; if (*_psAudit->pComboEntryTmp != '\0') { /* host:user ==> host\0user */ while (*_psAudit->pComboEntryTmp != ':') _psAudit->pComboEntryTmp++; memset(_psAudit->pComboEntryTmp, 0, 1); /* user:pass ==> user\0pass */ while (*_psAudit->pComboEntryTmp != ':') _psAudit->pComboEntryTmp++; memset(_psAudit->pComboEntryTmp, 0, 1); } } _psAudit->pComboEntryTmp = _psAudit->pGlobalCombo; } else { if ((_psAudit->iUserListFlag == LIST_COMPLETE) && (_psAudit->iHostListFlag == LIST_COMPLETE)) { _psAudit->iAuditFlag = AUDIT_COMPLETE; } } _psAudit->iHostListFlag = LIST_COMPLETE; if (_psAudit->iAuditFlag == AUDIT_COMPLETE) { _pHost = NULL; } else if (_psAudit->HostType == L_COMBO) { if (*_psAudit->pGlobalCombo == '\0') { _pHost = NULL; } else { _pHost = _psAudit->pGlobalCombo; } } else if (_psAudit->HostType == L_FILE) { if (*_psAudit->pGlobalHost != '\0') { _pHost = _psAudit->pGlobalHost; /* advancing host list */ while (*_psAudit->pGlobalHost != '\0') _psAudit->pGlobalHost++; _psAudit->pGlobalHost++; if (*_psAudit->pGlobalHost != '\0') { _psAudit->iHostListFlag = LIST_IN_PROGRESS; } else { /* resetting host list */ _psAudit->pGlobalHost = _psAudit->pHostFile; } } } else if (_psAudit->HostType == L_SINGLE) { _pHost = _psAudit->pGlobalHost; _psAudit->iAuditFlag = AUDIT_COMPLETE; } else { writeError(ERR_FATAL, "[findNextHost] HostType not properly defined."); } return _pHost; } /* Return next user-specified user during audit data table building process. This host information may be a single global entry, from a file containing a list of users, or from a combo file. */ char* findNextUser(sAudit *_psAudit, char *_pUser) { char* pComboTmp; _psAudit->iUserListFlag = LIST_COMPLETE; if (_psAudit->UserType == L_COMBO) { /* advance to username */ if (_psAudit->pGlobalCombo) { pComboTmp = _psAudit->pComboEntryTmp; while (*pComboTmp != '\0') pComboTmp++; pComboTmp++; } if (_pUser != NULL) _pUser = NULL; else _pUser = pComboTmp; writeError(ERR_DEBUG, "[findNextUser] Combo User: %s", _pUser); } else if (_psAudit->UserType == L_PWDUMP) { if (_pUser != NULL) _pUser = NULL; else _pUser = _psAudit->pComboEntryTmp; writeError(ERR_DEBUG, "[findNextUser] PwDump User: %s", _pUser); } else if (_psAudit->UserType == L_FILE) { _pUser = _psAudit->pGlobalUser; if (*_psAudit->pGlobalUser != '\0') { /* advance user list pointer */ while (*_psAudit->pGlobalUser != '\0') _psAudit->pGlobalUser++; _psAudit->pGlobalUser++; _psAudit->iUserListFlag = LIST_IN_PROGRESS; } else { /* reset list */ _psAudit->pGlobalUser = _psAudit->pUserFile; _pUser = NULL; } writeError(ERR_DEBUG, "[findNextUser] L_FILE User: %s", _pUser); } else if (_psAudit->UserType == L_SINGLE) { if (_pUser != NULL) _pUser = NULL; else _pUser = _psAudit->pGlobalUser; } else { writeError(ERR_FATAL, "[findNextUser] UserType (%d) not properly defined.", _psAudit->UserType); } return _pUser; } /* Return next user-specified password during audit data table building process. This password information is only from the combo file. */ char* findLocalPass(sAudit *_psAudit) { char *pPass; char *pComboTmp; if ((_psAudit->PassType == L_COMBO) || (_psAudit->PassType == L_PWDUMP)) { /* advance to password */ if (_psAudit->pGlobalCombo) { pComboTmp = _psAudit->pComboEntryTmp; while (*pComboTmp != '\0') pComboTmp++; pComboTmp++; while (*pComboTmp != '\0') pComboTmp++; pComboTmp++; } pPass = pComboTmp; writeError(ERR_DEBUG, "[findLocalPass] pPass: %s", pPass); } else { pPass = NULL; } return pPass; } int loadLoginInfo(sAudit *_psAudit) { sHost *psHost = NULL; sHost *psHostPrevTmp = NULL; char *pHost = NULL; sUser *psUser = NULL; char *pUser = NULL; sPass *psPass = NULL; char *pPass = NULL; /* initialize / reset */ _psAudit->iHostCnt = 0; _psAudit->iHostsDone = 0; while ((pHost = findNextHost(_psAudit, pHost))) { /* combo file: search list to see if host has already been added */ psHost = _psAudit->psHostRoot; while (psHost) { if ( strcmp(pHost,psHost->pHost) ) psHost = psHost->psHostNext; else break; } /* create new host table in list */ if (psHost == NULL) { _psAudit->iHostCnt++; psHost = malloc(sizeof(sHost)); memset(psHost, 0, sizeof(sHost)); /* set root pointer if this is the first host */ if (_psAudit->psHostRoot == NULL) { _psAudit->psHostRoot = psHost; psHostPrevTmp = _psAudit->psHostRoot; } else { psHostPrevTmp->psHostNext = psHost; psHostPrevTmp = psHost; } psHost->pHost = strdup(pHost); psHost->iPortOverride = _psAudit->iPortOverride; psHost->iUseSSL = _psAudit->iUseSSL; psHost->iTimeout = _psAudit->iTimeout; psHost->iRetryWait = _psAudit->iRetryWait; psHost->iRetries = _psAudit->iRetries; psHost->iUserCnt = 0; psHost->iId = _psAudit->iHostCnt; } while ((pUser = findNextUser(_psAudit, pUser))) { /* combo file: search list to see if user has already been added */ psUser = psHost->psUser; while (psUser) { if ( strcmp(pUser,psUser->pUser) ) psUser = psUser->psUserNext; else break; } /* create new user table in list */ if (psUser == NULL) { psHost->iUserCnt++; psUser = malloc(sizeof(sUser)); memset(psUser, 0, sizeof(sUser)); if (psHost->psUserPrevTmp) { /* setting host next user pointer */ psHost->psUserPrevTmp->psUserNext = psUser; } else { /* setting host root user pointer */ psHost->psUser = psUser; } psHost->psUserPrevTmp = psUser; psUser->pUser = strdup(pUser); psUser->iPassCnt = _psAudit->iPassCnt; psUser->iPassStatus = PL_UNSET; psUser->iId = psHost->iUserCnt; psHost->iUserPassCnt += _psAudit->iPassCnt; if (_psAudit->iPasswordUsernameFlag) { psHost->iUserPassCnt++; psUser->iPassCnt++; } if (_psAudit->iPasswordBlankFlag) { psHost->iUserPassCnt++; psUser->iPassCnt++; } } pPass = findLocalPass(_psAudit); if (pPass) { psPass = malloc(sizeof(sPass)); memset(psPass, 0, sizeof(sPass)); psPass->pPass = strdup(pPass); psUser->iPassCnt++; psHost->iUserPassCnt++; if (psUser->psPassPrevTmp) { /* setting user next pass pointer */ psUser->psPassPrevTmp->psPassNext = psPass; } else { /* setting user root pass pointer */ psUser->psPass = psPass; psUser->psPassCurrent = psPass; } psUser->psPassPrevTmp = psPass; } } } return SUCCESS; } /* Grab the next password for a particular user */ char* getNextPass(sLogin *_psLogin) { sAudit *_psAudit = _psLogin->psServer->psAudit; sUser *_psUser = _psLogin->psUser; char *pPass = NULL; /* is this user's password list complete? */ if ((_psUser->iPassStatus != PL_DONE) && (_psUser->iPassStatus != PASS_AUDIT_COMPLETE)) { /* is this the user's first password request? */ if (_psUser->iPassStatus == PL_UNSET) _psUser->iPassStatus = PL_NULL; /* process blank password or password matching username */ if ((_psUser->iPassStatus == PL_NULL) || (_psUser->iPassStatus == PL_USERNAME)) { if ((_psUser->iPassStatus == PL_NULL) && (_psAudit->iPasswordBlankFlag)) { pPass = ""; _psUser->iPassStatus = PL_USERNAME; } else if (_psAudit->iPasswordUsernameFlag) { pPass = _psUser->pUser; _psUser->iPassStatus = PL_LOCAL; } else { _psUser->iPassStatus = PL_LOCAL; } } if (pPass == NULL ) { /* process local passwords - i.e. passwords specified within combo file for user */ if ((_psUser->iPassStatus == PL_LOCAL) && (_psUser->psPassCurrent)) { pPass = _psUser->psPassCurrent->pPass; _psUser->psPassCurrent = _psUser->psPassCurrent->psPassNext; } /* process global passwords - i.e. passwords specified via "-p" or "-P" options */ else if (_psAudit->pGlobalPass) { _psUser->iPassStatus = PL_GLOBAL; if (_psUser->pPass) { while (*_psUser->pPass != '\0') _psUser->pPass++; _psUser->pPass++; if (*_psUser->pPass != '\0') { pPass = _psUser->pPass; } else { /* password auditing of host is complete */ _psUser->iPassStatus = PL_DONE; _psLogin->psServer->psHost->iUsersDone++; } } else { _psUser->pPass = _psAudit->pGlobalPass; pPass = _psUser->pPass; } } else { /* password auditing of host is complete */ _psUser->iPassStatus = PL_DONE; _psLogin->psServer->psHost->iUsersDone++; } } } return pPass; } /* Generates the next credential set for login module to test. The module is responsible for allocating and releasing memory used for the credential set. */ int getNextNormalCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { int nUserListChecked = FALSE; _psCredSet->iStatus = CREDENTIAL_SAME_USER; /* is this the first user for a login thread? */ if (_psLogin->psUser == NULL) { writeError(ERR_DEBUG, "[getNextNormalCred] Initial credential set request for login module."); _psLogin->psServer->psHost->iUserStatus = UL_NORMAL; _psCredSet->iStatus = CREDENTIAL_NEW_USER; /* multiple login threads of same user */ if (_psLogin->psServer->psAudit->iParallelLoginFlag == PARALLEL_LOGINS_PASSWORD) { if (_psLogin->psServer->psHost->psUserCurrent == NULL) _psLogin->psServer->psHost->psUserCurrent = _psLogin->psServer->psHost->psUser; _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent; if (_psLogin->psUser) writeError(ERR_DEBUG, "[getNextNormalCred] (PARALLEL_LOGINS_PASSWORD) setting user: %s", _psLogin->psUser->pUser); } /* multiple login threads of one unique user per thread */ else { /* only increment user pointer if this is not the first module */ if (_psLogin->psServer->psHost->psUserCurrent == NULL) { writeError(ERR_DEBUG, "[getNextNormalCred] Assigning initial user for host being tested."); _psLogin->psServer->psHost->psUserCurrent = _psLogin->psServer->psHost->psUser; _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent; //_psLogin->psServer->psHost->iUserStatus = UL_NORMAL; } else { writeError(ERR_DEBUG, "[getNextNormalCred] Assigning next available user for host being tested."); _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent->psUserNext; _psLogin->psServer->psHost->psUserCurrent = _psLogin->psUser; } if (_psLogin->psUser) writeError(ERR_DEBUG, "[getNextNormalCred] (PARALLEL_LOGINS_USER) setting NEW user: %s", _psLogin->psUser->pUser); } } /* find next available password - if password list is exhausted for user, move on to the next user */ while ((_psLogin->psUser) && ((_psCredSet->pPass = getNextPass(_psLogin)) == NULL)) { /* is password testing for user complete */ if ((_psLogin->psUser->iPassStatus == PL_DONE) || (_psLogin->psUser->iPassStatus == PASS_AUDIT_COMPLETE)) { writeError(ERR_INFO, "Login Module: %d - Current user password list is complete, selecting next user.", _psLogin->iId); if (_psLogin->psServer->psHost->psUserCurrent == NULL) { _psLogin->psUser = NULL; } /* if another thread has already selected the next user, process that user */ else if ((_psLogin->psServer->psHost->psUserCurrent->iPassStatus != PL_DONE) && (_psLogin->psServer->psHost->psUserCurrent->iPassStatus != PASS_AUDIT_COMPLETE)) { _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent; } else { _psLogin->psUser = _psLogin->psServer->psHost->psUserCurrent->psUserNext; _psLogin->psServer->psHost->psUserCurrent = _psLogin->psUser; } if (_psLogin->psUser == NULL) { /* end of list - check entire list for unfinished credentials */ if (nUserListChecked == FALSE) { writeError(ERR_INFO, "Login Module: %d - Current user password list is complete, rescanning userlist for unfinished credentials.", _psLogin->iId); _psLogin->psUser = _psLogin->psServer->psHost->psUser; _psLogin->psServer->psHost->psUserCurrent = _psLogin->psUser; nUserListChecked = TRUE; } else { writeError(ERR_INFO, "Login Module: %d - No more user accounts available for testing.", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } } else { writeError(ERR_INFO, "Login Module: %d - Selecting next password for user: %s", _psLogin->iId, _psLogin->psUser->pUser); _psCredSet->iStatus = CREDENTIAL_NEW_USER; } } } if ((_psLogin->psUser == NULL) || (_psCredSet->pPass == NULL)) { //writeError(ERR_INFO, "Login Module: %d - No more available users/passwords, setting credential status to CREDENTIAL_DONE.", _psLogin->iId); writeError(ERR_INFO, "Login Module: %d - No more users/passwords available in the normal queue.", _psLogin->iId); //_psCredSet->iStatus = CREDENTIAL_DONE; _psLogin->psServer->psHost->iUserStatus = UL_MISSED; } _psCredSet->psUser = _psLogin->psUser; return SUCCESS; } /* In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. The addMissedCredSet() function creates a linked list of credentials which were not tested for a given host. This function retrieves the next credential set from that list for testing. */ int getNextMissedCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { sCredentialSet *psCredSetMissed = NULL; writeError(ERR_DEBUG, "Retrieving the next available credential set from list of previously missed sets."); /* skip credential if user testing is complete (e.g. password found, account locked) */ psCredSetMissed = _psLogin->psServer->psCredentialSetMissedCurrent; while ((psCredSetMissed) && (psCredSetMissed->psUser->iPassStatus == PASS_AUDIT_COMPLETE)) { psCredSetMissed = _psLogin->psServer->psCredentialSetMissedCurrent->psCredentialSetNext; _psLogin->psServer->psCredentialSetMissedCurrent = psCredSetMissed; } /* located next credential set that was not previously tested */ if (psCredSetMissed) { _psCredSet->psUser = psCredSetMissed->psUser; _psCredSet->pPass = psCredSetMissed->pPass; _psLogin->psServer->psCredentialSetMissedCurrent = psCredSetMissed->psCredentialSetNext; if (_psLogin->psUser == _psCredSet->psUser) _psCredSet->iStatus = CREDENTIAL_SAME_USER; else _psCredSet->iStatus = CREDENTIAL_NEW_USER; _psLogin->psServer->iCredentialsMissed--; writeError(ERR_DEBUG, "Login Module: %d - Selected next credential set from list of previously missed sets (%s/%s).", _psLogin->iId, _psCredSet->psUser->pUser, _psCredSet->pPass); } else { writeError(ERR_INFO, "Login Module: %d - No additional missed users/passwords, setting credential status to CREDENTIAL_DONE.", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; _psLogin->psServer->psHost->iUserStatus = UL_DONE; } _psLogin->psUser = _psCredSet->psUser; return SUCCESS; } /* Function returns next available username and password to module for testing. The normal host's list of users and their respective passwords (local, global, etc) are tested first. If any credential sets were not successfully tested (module instance died for some reason) they re-checked after all normal tests are done. */ int getNextCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { if (_psCredSet == NULL) writeError(ERR_FATAL, "getNextCredSet() called, but not supplied allocated memory for _psCredSet"); memset(_psCredSet, 0, sizeof(sCredentialSet)); pthread_mutex_lock(&_psLogin->psServer->ptmMutex); /* terminate all login threads */ if (_psLogin->psServer->psAudit->iStatus == AUDIT_ABORT) { writeError(ERR_INFO, "Audit aborting... notifying login module: %d", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } /* valid credential set found -- exit host flag set */ else if ((_psLogin->psServer->iValidPairFound) && (_psLogin->psServer->psAudit->iFoundPairExitFlag == FOUND_PAIR_EXIT_HOST)) { writeError(ERR_INFO, "Exiting Login Module: %d [Stop Host Scan After Valid Pair Found Enabled]", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } /* valid credential set found -- exit audit flag set */ else if ((_psLogin->psServer->psAudit->iValidPairFound) && (_psLogin->psServer->psAudit->iFoundPairExitFlag == FOUND_PAIR_EXIT_AUDIT)) { writeError(ERR_INFO, "Exiting Login Module: %d [Stop Audit Scans After Valid Pair Found Enabled]", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; } else { switch (_psLogin->psServer->psHost->iUserStatus) { case UL_UNSET: case UL_NORMAL: /* check for next available login to perform */ if (getNextNormalCredSet(_psLogin, _psCredSet) != SUCCESS) writeError(ERR_FATAL, "getNextNormalCredSet() function call failed."); /* the normal queue is exhausted - check the missed credentials queue */ if (_psLogin->psServer->psHost->iUserStatus == UL_MISSED) if (getNextMissedCredSet(_psLogin, _psCredSet) != SUCCESS) writeError(ERR_FATAL, "getNextMissedCredSet() function call failed."); break; case UL_MISSED: /* check for next available login missed during normal testing */ if (getNextMissedCredSet(_psLogin, _psCredSet) != SUCCESS) writeError(ERR_FATAL, "getNextMissedCredSet() function call failed."); break; case UL_DONE: writeError(ERR_INFO, "Login Module: %d - No additional users/passwords, setting credential status to CREDENTIAL_DONE.", _psLogin->iId); _psCredSet->iStatus = CREDENTIAL_DONE; break; default: writeError(ERR_DEBUG, "Login Module: %d - Entered undefined state (%d) within getNextCredSet()", _psLogin->iId, _psLogin->psServer->psHost->iUserStatus); break; } } pthread_mutex_unlock(&_psLogin->psServer->ptmMutex); return SUCCESS; } /* Process password result from login module */ void setPassResult(sLogin *_psLogin, char *_pPass) { pthread_mutex_lock(&_psLogin->psServer->ptmMutex); writeVerbose(VB_CHECK, "[%s] Host: %s (%d of %d, %d complete) User: %s (%d of %d, %d complete) Password: %s (%d of %d complete)", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psServer->psHost->iId, _psLogin->psServer->psAudit->iHostCnt, _psLogin->psServer->psAudit->iHostsDone, _psLogin->psUser->pUser, _psLogin->psUser->iId, _psLogin->psServer->psHost->iUserCnt, _psLogin->psServer->psHost->iUsersDone, _pPass, _psLogin->psUser->iLoginsDone + 1, _psLogin->psUser->iPassCnt ); _psLogin->iLoginsDone++; _psLogin->psUser->iLoginsDone++, _psLogin->psServer->iLoginsDone++; switch (_psLogin->iResult) { case LOGIN_RESULT_SUCCESS: if (_psLogin->pErrorMsg) { writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [SUCCESS (%s)]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass, _psLogin->pErrorMsg); free(_psLogin->pErrorMsg); _psLogin->pErrorMsg = NULL; } else writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [SUCCESS]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass); _psLogin->psServer->psAudit->iValidPairFound = TRUE; _psLogin->psServer->iValidPairFound = TRUE; _psLogin->psUser->iPassStatus = PASS_AUDIT_COMPLETE; _psLogin->psServer->psHost->iUsersDone++; break; case LOGIN_RESULT_FAIL: if (_psLogin->pErrorMsg) { writeError(ERR_INFO, "[%s] Host: %s User: %s [FAILED (%s)]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _psLogin->pErrorMsg); free(_psLogin->pErrorMsg); _psLogin->pErrorMsg = NULL; } else writeError(ERR_INFO, "[%s] Host: %s User: %s [FAILED]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser); break; case LOGIN_RESULT_ERROR: if (_psLogin->pErrorMsg) { writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [ERROR (%s)]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass, _psLogin->pErrorMsg); free(_psLogin->pErrorMsg); _psLogin->pErrorMsg = NULL; } else writeVerbose(VB_FOUND, "[%s] Host: %s User: %s Password: %s [ERROR]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _pPass); _psLogin->psUser->iPassStatus = PASS_AUDIT_COMPLETE; _psLogin->psServer->psHost->iUsersDone++; break; default: writeError(ERR_INFO, "[%s] Host: %s User: %s [UNKNOWN %d]", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->psUser->pUser, _psLogin->iResult); break; } pthread_mutex_unlock(&_psLogin->psServer->ptmMutex); } /* In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. This function creates a list of those credentials so that they can be tested by the remaining threads at the end of their current run. */ int addMissedCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet) { sCredentialSet *psCredSetMissed = NULL; pthread_mutex_lock(&_psLogin->psServer->ptmMutex); writeError(ERR_NOTICE, "[%s] Host: %s - Login thread (%d) prematurely ended. The current number of parallel login threads may exceed what this service can reasonably handle. The total number of threads for this host will be decreased.", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psLogin->iId ); if (_psLogin->psServer->iLoginCnt > 1) _psLogin->psServer->iLoginCnt--; writeError(ERR_NOTICE, "[%s] Host: %s User: %s Password: %s - The noted credentials have been added to the end of the queue for testing.", _psLogin->psServer->psAudit->pModuleName, _psLogin->psServer->psHost->pHost, _psCredSet->psUser->pUser, _psCredSet->pPass ); /* build structure for missed credential set */ psCredSetMissed = malloc(sizeof(sCredentialSet)); memset(psCredSetMissed, 0, sizeof(sCredentialSet)); psCredSetMissed->psUser = _psCredSet->psUser; psCredSetMissed->pPass = strdup(_psCredSet->pPass); /* append structure to host's list of missed credentials */ if (_psLogin->psServer->psCredentialSetMissed == NULL) /* first missed credential set */ { _psLogin->psServer->psCredentialSetMissed = psCredSetMissed; _psLogin->psServer->psCredentialSetMissedCurrent = psCredSetMissed; } else _psLogin->psServer->psCredentialSetMissedTail->psCredentialSetNext = psCredSetMissed; _psLogin->psServer->psCredentialSetMissedTail = psCredSetMissed; _psLogin->psServer->iCredentialsMissed++; pthread_mutex_unlock(&_psLogin->psServer->ptmMutex); return SUCCESS; } void startModule(void* pParams) { int64_t nRet = 0; sModuleStart* modParams = (sModuleStart*)pParams; if (NULL == modParams) { writeError(ERR_FATAL, "Bad pointer passed to invokeModule"); return; } writeError(ERR_DEBUG, "startModule iId: %d pLogin: %X modParams->argv: %X modParams: %X", modParams->pLogin->iId, modParams->pLogin, modParams->argv, modParams); nRet = invokeModule(modParams->szModuleName, modParams->pLogin, modParams->argc, modParams->argv); if (nRet < 0) writeVerbose(VB_EXIT, "invokeModule failed - see previous errors for an explanation"); return; } /* Initiate and manage host-specific thread pool for logins. Each target host has a single thread for this purpose. The thread spawns multiple child threads which each initiate the selected module to perform the actual logons. */ void startLoginThreadPool(void *arg) { sServer *_psServer = (sServer *)arg; thr_pool_t *login_pool = NULL; sLogin psLogin[_psServer->psAudit->iLoginCnt]; sModuleStart modParams[_psServer->psAudit->iLoginCnt]; int iLoginId = 0; int iLoginCnt = _psServer->psAudit->iLoginCnt; struct addrinfo hints, *res; int errcode; void *ptr; writeError(ERR_DEBUG_SERVER, "Server ID: %d Host: %s iUserPassCnt: %d iLoginCnt: %d", _psServer->iId, _psServer->psHost->pHost, _psServer->psHost->iUserPassCnt, iLoginCnt); /* create thread pool - min threads, max threads, linger time, attributes */ if (iLoginCnt > _psServer->psHost->iUserPassCnt) iLoginCnt = _psServer->psHost->iUserPassCnt; if ((login_pool = thr_pool_create(0, iLoginCnt, POOL_THREAD_LINGER, NULL)) == NULL) { writeError(ERR_FATAL, "Failed to create root login thread pool for host: %s", _psServer->psHost->pHost); } /* resolve host name */ _psServer->pHostIP = malloc(100); memset(_psServer->pHostIP, 0, 100); memset(&hints, 0, sizeof (hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags |= AI_CANONNAME; errcode = getaddrinfo(_psServer->psHost->pHost, NULL, &hints, &res); if (errcode != 0) { writeError(ERR_CRITICAL, "Failed to resolve hostname: %s - %s", _psServer->psHost->pHost, gai_strerror(errcode)); return; } if (res->ai_next != NULL) writeError(ERR_ERROR, "Hostname resolved to multiple addresses. Selecting first address for testing."); inet_ntop (res->ai_family, res->ai_addr->sa_data, _psServer->pHostIP, 100); switch (res->ai_family) { case AF_INET: ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; break; case AF_INET6: ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; break; } inet_ntop (res->ai_family, ptr, _psServer->pHostIP, 100); writeError(ERR_DEBUG_SERVER, "Set IPv%d address: %s (%s)",res->ai_family == PF_INET6 ? 6 : 4, _psServer->pHostIP, res->ai_canonname); freeaddrinfo(res); /* add login tasks to pool queue */ for (iLoginId = 0; iLoginId < iLoginCnt; iLoginId++) { writeError(ERR_DEBUG_SERVER, "Adding new login task (%d) to server queue (%d)", iLoginId, _psServer->iId); psLogin[iLoginId].iId = iLoginId; psLogin[iLoginId].psServer = _psServer; psLogin[iLoginId].iResult = LOGIN_RESULT_UNKNOWN; psLogin[iLoginId].pErrorMsg = NULL; psLogin[iLoginId].iLoginsDone = 0; psLogin[iLoginId].psUser = NULL; modParams[iLoginId].szModuleName = szModuleName; modParams[iLoginId].pLogin = &(psLogin[iLoginId]); //psLogin + (iLoginId * sizeof(sLogin)); modParams[iLoginId].argc = nModuleParamCount; modParams[iLoginId].argv = (char**)arrModuleParams; if ( thr_pool_queue(login_pool, startModule, (void *) &modParams[iLoginId]) < 0 ) { writeError(ERR_CRITICAL, "Failed to add module launch task to login thread pool for server queue: %d.", _psServer->iId); return; } } /* wait for login thread pool to finish */ writeError(ERR_DEBUG_SERVER, "waiting for server %d login pool to end", _psServer->iId); thr_pool_wait(login_pool); /* In certain situations we need to scale back the number of concurrent login threads targetting a specific service. For example, MSDE's workload governor limits the service to no more than 5 concurrent connections. If the user kicked-off 10 parallel login threads, 5 of those are going to fail and terminate. The challenge is that each of those threads was already assigned a credential set to test. When these threads failed, we pushed the missed credentials into a queue assigned to the target host. This queue may already have been taken care of by running threads when they finished their normal tasks. However, if the missed logons were pushed to the queue by exiting threads after the other threads had terminated, they are still sitting there. To deal with this problem, we kick off a single thread to run through these. */ iLoginId = 0; if ((_psServer->psAudit->iStatus != AUDIT_ABORT) && (_psServer->iCredentialsMissed > 0)) { writeError(ERR_DEBUG_SERVER, "Adding new clean-up login task to server queue (%d) for %d missed logins", _psServer->iId, _psServer->iCredentialsMissed); _psServer->psHost->iUserStatus = UL_MISSED; psLogin[iLoginId].iResult = LOGIN_RESULT_UNKNOWN; psLogin[iLoginId].pErrorMsg = NULL; psLogin[iLoginId].psUser = NULL; if ( thr_pool_queue(login_pool, startModule, (void *) &modParams[iLoginId]) < 0 ) { writeError(ERR_CRITICAL, "Failed to add module launch task to login thread pool for server queue: %d.", _psServer->iId); return; } /* wait for login thread pool to finish */ writeError(ERR_DEBUG_SERVER, "waiting for server %d login pool to end", _psServer->iId); thr_pool_wait(login_pool); } writeError(ERR_DEBUG_SERVER, "destroying server %d login pool", _psServer->iId); thr_pool_destroy(login_pool); /* track the number of hosts which have been completed */ pthread_mutex_lock(&_psServer->psAudit->ptmMutex); _psServer->psAudit->iHostsDone++; pthread_mutex_unlock(&_psServer->psAudit->ptmMutex); /* The logon modules for server have all terminated, however, the server's userlist is not marked as completed. This may be due to the module exiting prematurely (e.g. the service being tested became unavailable). We mark the host as UL_ERROR to avoid having it added to the resume list. */ if ((_psServer->psAudit->iStatus != AUDIT_ABORT) && ((_psServer->psHost->iUserStatus == UL_NORMAL) || (_psServer->psHost->iUserStatus == UL_MISSED))) { writeError(ERR_DEBUG_SERVER, "Server thread exiting and server's userlist testing was marked as in progress. Was this host prematurely aborted?"); _psServer->psHost->iUserStatus = UL_ERROR; } writeError(ERR_DEBUG_SERVER, "exiting server: %d", _psServer->iId); free(_psServer->pHostIP); return; } /* Initiate and manage thread pool for target systems. Each target host will have a single parent thread, which manages all childs login threads specific to that individual machine. */ int startServerThreadPool(sAudit *_psAudit) { sServer psServer[_psAudit->iHostCnt]; sHost *psHost; int iServerId; sUser *psUser; char *szResumeMap = NULL; char *szUserMap = NULL; int nAddHost; int nUserMapSize; int nFirstNewHostFound; int nFirstNewUserFound; char szTmp[11]; char szTmp1[11]; char szTmp2[11]; writeVerbose(VB_GENERAL, "Parallel Hosts: %d Parallel Logins: %d", _psAudit->iServerCnt, _psAudit->iLoginCnt); writeVerbose(VB_GENERAL, "Total Hosts: %d ", _psAudit->iHostCnt); if (_psAudit->iUserCnt == 0) writeVerbose(VB_GENERAL, "Total Users: [combo]"); else writeVerbose(VB_GENERAL, "Total Users: %d", _psAudit->iUserCnt); if (_psAudit->iPassCnt == 0) writeVerbose(VB_GENERAL, "Total Passwords: [combo]"); else writeVerbose(VB_GENERAL, "Total Passwords: %d", _psAudit->iPassCnt); /* create thread pool - min threads, max threads, linger time, attributes */ if (_psAudit->iServerCnt > _psAudit->iHostCnt) _psAudit->iServerCnt = _psAudit->iHostCnt; /* initialize global crypto (OpenSSL, Libgcrypt) variables */ init_crypto_locks(); if ((_psAudit->server_pool = thr_pool_create(0, _psAudit->iServerCnt, POOL_THREAD_LINGER, NULL)) == NULL) { writeError(ERR_ERROR, "Failed to create root server thread pool."); return FAILURE; } /* initialize servers */ memset(psServer, 0, sizeof(sServer) * _psAudit->iHostCnt); psHost = _psAudit->psHostRoot; nFirstNewHostFound = FALSE; /* add server tasks to pool queue (one task per host to be tested) */ for (iServerId = 0; iServerId < _psAudit->iHostCnt; iServerId++) { /* resume map was supplied by user - skip hosts and users which were previously completed */ nAddHost = TRUE; if (_psAudit->pOptResume) { memset(szTmp, 0, 11); memset(szTmp1, 0, 11); snprintf(szTmp, 10, "h%d.", psHost->iId); snprintf(szTmp1, 10, "h%du", psHost->iId); if (nFirstNewHostFound == TRUE) { writeError(ERR_DEBUG_SERVER, "[Host Resume] Adding host: %d (we've passed the point of the previous run)", psHost->iId); } else if ((szResumeMap = strstr(_psAudit->pOptResume, szTmp1))) { writeError(ERR_DEBUG_SERVER, "[Host Resume] Adding host: %d (host was located in resume map)", psHost->iId); /* extract host's user resume map */ if (index(szResumeMap + 1, 0x68)) nUserMapSize = index(szResumeMap + 1, 0x68) - szResumeMap; /* calculate length of host resume map from start to the next "h" */ else if (index(szResumeMap + 1, 0x2e)) nUserMapSize = index(szResumeMap + 1, 0x2e) - szResumeMap; /* calculate length of host resume map from start to the terminating "." */ else nUserMapSize = strlen(szResumeMap); /* single, or last, host resume */ if (nUserMapSize < 4) writeError(ERR_FATAL, "Error extacting user resume map for host: %d", psHost->iId); szUserMap = malloc(nUserMapSize + 1); memset(szUserMap, 0, nUserMapSize + 1); strncpy(szUserMap, szResumeMap, nUserMapSize); writeError(ERR_DEBUG_SERVER, "[Host Resume] Host: %d - Processing host's user resume map: %s", psHost->iId, szUserMap); /* examine each user for the host and mark previously tested accounts as completed */ nFirstNewUserFound = FALSE; psUser = psHost->psUser; while (psUser) { memset(szTmp, 0, 11); memset(szTmp1, 0, 11); snprintf(szTmp, 10, "u%du", psUser->iId); snprintf(szTmp1, 10, "u%dh", psUser->iId); snprintf(szTmp2, 10, "u%d.", psUser->iId); if (nFirstNewUserFound == TRUE) { writeError(ERR_DEBUG_SERVER, "[User Resume] Adding user: %d (we've passed the point of the previous run)", psUser->iId); } else if (strstr(szResumeMap, szTmp)) { writeError(ERR_DEBUG_SERVER, "[User Resume] Adding user: %d (user was located in resume map)", psUser->iId); } else if ((strstr(szResumeMap, szTmp1)) || (strstr(szResumeMap, szTmp2))) { writeError(ERR_DEBUG_SERVER, "[User Resume] Adding user: %d (user was located in resume map and identified as first untouched account)", psUser->iId); nFirstNewUserFound = TRUE; } else { writeError(ERR_DEBUG_SERVER, "[User Resume] Skipping user: %d (user has already been tested)", psUser->iId); psUser->iPassStatus = PL_DONE; } psUser = psUser->psUserNext; } } else if (strstr(_psAudit->pOptResume, szTmp)) { writeError(ERR_DEBUG_SERVER, "[Host Resume] Adding host: %d (host was located in resume map and identified as first untouched system)", psHost->iId); nFirstNewHostFound = TRUE; } else { writeError(ERR_DEBUG_SERVER, "[Host Resume] Skipping host: %d (host has already been tested)", psHost->iId); nAddHost = FALSE; psHost->iUserStatus = UL_DONE; } } if (nAddHost) { writeError(ERR_DEBUG_AUDIT, "adding new server (%d) to queue", iServerId); if (pthread_mutex_init(&(psServer[iServerId].ptmMutex), NULL) != 0) writeError(ERR_FATAL, "Server (%d) mutex initialization failed - %s\n", iServerId, strerror( errno ) ); psServer[iServerId].psAudit = _psAudit; psServer[iServerId].iId = iServerId; psServer[iServerId].psHost = psHost; psServer[iServerId].iLoginCnt = _psAudit->iLoginCnt; psServer[iServerId].iLoginsDone = 0; psServer[iServerId].iCredentialsMissed = 0; if ( thr_pool_queue(_psAudit->server_pool, startLoginThreadPool, (void *) &psServer[iServerId]) < 0 ) { writeError(ERR_ERROR, "Failed to add host task to server thread pool."); return FAILURE; } } psHost = psHost->psHostNext; } /* wait for thread pool to finish */ writeError(ERR_DEBUG_AUDIT, "waiting for server pool to end"); thr_pool_wait(_psAudit->server_pool); writeError(ERR_DEBUG_AUDIT, "destroying server pool"); thr_pool_destroy(_psAudit->server_pool); /* destroy and clean-up server objects */ for (iServerId = 0; iServerId < _psAudit->iHostCnt; iServerId++) { if (pthread_mutex_init(&(psServer[iServerId].ptmMutex), NULL) != 0) writeError(ERR_FATAL, "Server (%d) mutex destroy call failed - %s\n", iServerId, strerror( errno ) ); } kill_crypto_locks(); return SUCCESS; } /* Function called on SIGINT. We process the host and user tables and generate a map representing their current state. This map can then be supplied to Medusa to essentially resume the run. It should be noted, however, that users which were partially tested will be resumed from the start of their password list. */ void sigint_handler(int sig __attribute__((unused))) { sHost *psHost; sUser *psUser; char szTmp[10+1]; // we can only resume h + 7 + . + \0, so 7 digits... 9,999,999 (should be enough) hosts char *szResumeMap = NULL; int nResumeMapSize = 0; int nItemByteSize = 0; struct sigaction sig_action; /* SIGINT is blocked by default within the handler. We explicitly unblock it here. This allows us to hit CTRL-C a second time and really quit the application without waiting for the threads to complete their work. */ sig_action.sa_flags = 0; sigemptyset(&sig_action.sa_mask); sigaddset(&sig_action.sa_mask, SIGINT); sig_action.sa_handler = SIG_DFL; sigaction(SIGINT, &sig_action, 0); sigprocmask(SIG_UNBLOCK, &sig_action.sa_mask, 0); /* notify threads that they should be exiting and then wait for them to finish */ writeError(ERR_ALERT, "Medusa received SIGINT - Sending notification to login threads that we are aborting."); psAudit->iStatus = AUDIT_ABORT; writeError(ERR_INFO, "Waiting for login threads to terminate..."); thr_pool_wait(psAudit->server_pool); /* We note each partially finished host and the first new host for which testing has not started. We do the same for each partially completed host's user list. The number of partially completed hosts likely matches the number of parallel hosts being tested (T). The number of partially completed users for a given host likely matches the number of parallel logins being performed (t). This results in us reporting T(t + 1) + 1 items. Let's assume each item will require X bytes to report, which leads us to X(Tt + T + 1) bytes needed. Example: h6u1u2h7u3u4h8. +---------------- First host which was not 100% completed +-------------- First user for host which was not 100% completed +------------ First user for host which was not started +---- First host which was not started */ /* base our byte count on the largest number we may need to record - ex: h1236\0 */ if (psAudit->iHostCnt > psAudit->iUserCnt) nItemByteSize = 1 + (int)log10(psAudit->iHostCnt) + 1; else nItemByteSize = 1 + (int)log10(psAudit->iUserCnt) + 1; nResumeMapSize = nItemByteSize * (psAudit->iServerCnt * psAudit->iLoginCnt + psAudit->iServerCnt + 1) + 1; /* include terminating "." */ szResumeMap = malloc(nResumeMapSize + 1); memset(szResumeMap, 0, nResumeMapSize + 1); memset(szTmp, 0, 10 + 1); psHost = psAudit->psHostRoot; while ((psHost) && (psHost->iUserStatus != UL_UNSET)) { /* identify the hosts which are not 100% complete */ if ((psHost->iUserStatus != UL_DONE) && (psHost->iUserStatus != UL_ERROR)) { writeError(ERR_DEBUG, "Incomplete Host: %d", psHost->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 10, "h%d", psHost->iId); strncat(szResumeMap, szTmp, 10); /* identify the users which are not 100% complete for specific host */ psUser = psHost->psUser; while ((psUser) && (psUser->iPassStatus != PL_UNSET)) { if ((psUser->iPassStatus == PL_DONE) || (psUser->iPassStatus == PASS_AUDIT_COMPLETE)) writeError(ERR_DEBUG, "Complete User: %d", psUser->iId); else { writeError(ERR_DEBUG, "Incomplete User: %d", psUser->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 10, "u%d", psUser->iId); strncat(szResumeMap, szTmp, 10); } psUser = psUser->psUserNext; } /* identify the first untouched user */ if ((psUser) && (psUser->iPassStatus == PL_UNSET)) { writeError(ERR_DEBUG, "First New User: %d", psUser->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 10, "u%d", psUser->iId); strncat(szResumeMap, szTmp, 10); } } else { writeError(ERR_DEBUG, "Complete Host: %d", psHost->iId); } psHost = psHost->psHostNext; } /* identify the first untouched host */ if ((psHost) && (psHost->iUserStatus == UL_UNSET)) { writeError(ERR_DEBUG, "First New Host: %d", psHost->iId); memset(szTmp, 0, 10 + 1); snprintf(szTmp, 8, "h%d", psHost->iId); strncat(szResumeMap, szTmp, 8); } /* terminate resume map */ strcat(szResumeMap, "."); writeError(ERR_ALERT, "To resume scan, add the following to your original command: \"-Z %s\"", szResumeMap); free(szResumeMap); exit(0); } int main(int argc, char **argv, char *envp[] __attribute__((unused))) { struct sigaction sig_action; int iExitStatus = EXIT_SUCCESS; int i; struct tm *tm_ptr; time_t the_time; char time_buf[256]; /* set signal handling for SIGINT */ sig_action.sa_flags = 0; sigemptyset(&sig_action.sa_mask); sigaddset(&sig_action.sa_mask, SIGINT); sig_action.sa_handler = sigint_handler; sigaction(SIGINT, &sig_action, 0); /* initial module settings and parameters Don't worry if there are NULL or blank values here (they will be checked when loading the module) */ szModuleName = NULL; szModulePaths[0] = getenv("MEDUSA_MODULE_PATH"); szModulePaths[1] = "."; #ifdef DEFAULT_MOD_PATH szModulePaths[2] = DEFAULT_MOD_PATH; #else szModulePaths[2] = "/usr/lib/medusa/modules"; #endif szTempModuleParam = NULL; arrModuleParams = malloc(sizeof(char*)); memset(arrModuleParams, 0, sizeof(char*)); nModuleParamCount = 0; /* initialized audit structure */ psAudit = malloc(sizeof(sAudit)); memset(psAudit, 0, sizeof(sAudit)); if (pthread_mutex_init(&(psAudit->ptmMutex), NULL) != 0) writeError(ERR_FATAL, "Audit mutex initialization failed - %s\n", strerror( errno ) ); /* parse user-supplied parameters - populate module parameters */ if (checkOptions(argc, argv, psAudit)) { usage(); exit(EXIT_FAILURE); } for (i = 0; i < nModuleParamCount; i++) { writeVerbose(VB_GENERAL, "Module parameter: %s", arrModuleParams[i]); } if (szModuleName == NULL) { writeVerbose(VB_EXIT, "You must specify a module to execute using -M MODULE_NAME"); freeModuleParams(); exit(EXIT_FAILURE); } if (psAudit->HostType == L_FILE) { loadFile(psAudit->pOptHost, &psAudit->pHostFile, &psAudit->iHostCnt); psAudit->pGlobalHost = psAudit->pHostFile; } if (psAudit->UserType == L_FILE) { loadFile(psAudit->pOptUser, &psAudit->pUserFile, &psAudit->iUserCnt); psAudit->pGlobalUser = psAudit->pUserFile; } if (psAudit->PassType == L_FILE) { loadFile(psAudit->pOptPass, &psAudit->pPassFile, &psAudit->iPassCnt); psAudit->pGlobalPass = psAudit->pPassFile; } if (psAudit->pOptCombo != NULL) { loadFile(psAudit->pOptCombo, &psAudit->pComboFile, &psAudit->iComboCnt); psAudit->pGlobalCombo = psAudit->pComboFile; if (processComboFile(&psAudit)) { exit(iExitStatus); } } if ( loadLoginInfo(psAudit) == SUCCESS ) writeError(ERR_DEBUG, "Successfully loaded login information."); else writeError(ERR_FATAL, "Failed to load login information."); if (psAudit->pOptCombo != NULL) free(psAudit->pComboFile); if (psAudit->pHostFile != NULL) free(psAudit->pHostFile); if (psAudit->pUserFile != NULL) free(psAudit->pUserFile); if (psAudit->pOptOutput != NULL) { if ((pOutputFile = fopen(psAudit->pOptOutput, "a+")) == NULL) { writeError(ERR_FATAL, "Failed to open output file %s - %s", psAudit->pOptOutput, strerror( errno ) ); } else { if (pthread_mutex_init((&ptmFileMutex), NULL) != 0) writeError(ERR_FATAL, "File mutex initialization failed - %s\n", strerror( errno ) ); /* write start time and user options to log */ (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); writeVerbose(VB_NONE_FILE, "# Medusa v.%s (%s)\n", VERSION, time_buf); writeVerbose(VB_NONE_FILE, "# "); for (i =0; i < argc; i++) { writeVerbose(VB_NONE_FILE, "%s ", argv[i]); } writeVerbose(VB_NONE_FILE, "\n"); } } /* launch actually password auditing threads */ if ( startServerThreadPool(psAudit) == SUCCESS ) { /* stop time */ (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); writeVerbose(VB_NONE_FILE, "# Medusa has finished (%s).\n", time_buf); writeVerbose(VB_GENERAL, "Medusa has finished."); iExitStatus = EXIT_SUCCESS; } else { /* stop time */ (void) time(&the_time); tm_ptr = localtime(&the_time); strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr); writeVerbose(VB_NONE_FILE, "# Medusa failed (%s).\n", time_buf); writeError(ERR_CRITICAL, "Medusa failed."); iExitStatus = EXIT_FAILURE; } /* general memory clean-up */ if ((psAudit->pOptOutput != NULL) && (pthread_mutex_destroy(&ptmFileMutex) != 0)) writeError(ERR_FATAL, "File mutex destroy call failed - %s\n", strerror( errno ) ); if (pthread_mutex_destroy(&(psAudit->ptmMutex)) != 0) writeError(ERR_FATAL, "Audit mutex destroy call failed - %s\n", strerror( errno ) ); free(psAudit->pPassFile); free(psAudit); if (szModuleName != NULL) free(szModuleName); freeModuleParams(); exit(iExitStatus); } jmk-foofus-medusa-dd62069/src/medusa.h000066400000000000000000000176661460263104500176450ustar00rootroot00000000000000/* * Medusa Parallel Login Auditor * * Copyright (C) 2006 Joe Mondloch * JoMo-Kun / jmk@foofus.net * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation * * 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. * * http://www.gnu.org/licenses/gpl.txt * * This program is released under the GPL with the additional exemption * that compiling, linking, and/or using OpenSSL is allowed. * */ #ifndef _MEDUSA_H #define _MEDUSA_H #include #include #include #include #include #include #include #include #include #include #include #include "medusa-trace.h" #include "medusa-net.h" #include "medusa-thread-pool.h" #include "medusa-thread-ssl.h" #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_LIBSSL #include #endif #define PROGRAM "Medusa" #ifndef VERSION #define VERSION "1.0" #endif #define AUTHOR "JoMo-Kun / Foofus Networks" #define EMAIL "" #define WWW "http://www.foofus.net" #define SUCCESS 0 #define FAILURE -1 #define FALSE 0 #define TRUE 1 /* GLOBAL VARIABLES */ extern FILE *pOutputFile; extern pthread_mutex_t ptmFileMutex; extern int iVerboseLevel; // Global control over general message verbosity extern int iErrorLevel; // Global control over error debugging verbosity //#define MAX_BUF (16 * 1024) #define MAX_BUF 16384 /* Older Solaris doesn't seem to define INADDR_NONE */ #ifndef INADDR_NONE #define INADDR_NONE ((unsigned long) -1 #endif /* Cygwin doesn't seem to define INET_ADDRSTRLEN */ #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif // Number of seconds that idle threads can linger before exiting, when no tasks // come in. The idle threads can only exit if they are extra threads, above the // number of minimum threads. #define POOL_THREAD_LINGER 1 #define FREE(x) \ if (x != NULL) { \ free(x); \ x = NULL; \ } #define L_UNSET 0 #define L_SINGLE 1 #define L_FILE 2 #define L_COMBO 3 #define L_PWDUMP 4 typedef struct __sPass { struct __sPass *psPassNext; char *pPass; } sPass; /* Used in __sUser to define progress of an individual username audit */ #define PL_UNSET 0 #define PL_NULL 1 #define PL_USERNAME 2 #define PL_LOCAL 3 #define PL_GLOBAL 4 #define PL_DONE 5 #define PASS_AUDIT_COMPLETE 6 typedef struct __sUser { struct __sUser *psUserNext; char *pUser; struct __sPass *psPass; struct __sPass *psPassCurrent; struct __sPass *psPassPrevTmp; char *pPass; int iPassCnt; int iLoginsDone; int iPassStatus; int iId; } sUser; /* Used in __sHost to define progress of the audit of the host's users */ #define UL_UNSET 0 #define UL_NORMAL 1 #define UL_MISSED 2 #define UL_DONE 3 #define UL_ERROR 4 typedef struct __sHost { struct __sHost *psHostNext; char *pHost; int iUseSSL; // use SSL int iPortOverride; // use this port instead of the module's default port int iTimeout; // Number of seconds to wait before a connection times out int iRetryWait; // Number of seconds to wait between retries int iRetries; // Number of retries to attempt sUser *psUser; sUser *psUserCurrent; sUser *psUserPrevTmp; int iUserCnt; int iUserPassCnt; int iUsersDone; // number of users tested int iUserStatus; int iId; } sHost; /* Used in __sCredentialSet to relay information to module regarding user */ #define CREDENTIAL_SAME_USER 1 #define CREDENTIAL_NEW_USER 2 #define CREDENTIAL_DONE 3 typedef struct __sCredentialSet { struct __sCredentialSet *psCredentialSetNext; struct __sUser *psUser; char *pPass; int iStatus; } sCredentialSet; typedef struct __sServer { struct __sAudit *psAudit; struct __sHost *psHost; char *pHostIP; int iValidPairFound; int iId; int iLoginCnt; // total number of logins performed concurrently against specific server int iLoginsDone; // number of logins performed by all threads under this server sCredentialSet *psCredentialSetMissed; sCredentialSet *psCredentialSetMissedCurrent; sCredentialSet *psCredentialSetMissedTail; int iCredentialsMissed; pthread_mutex_t ptmMutex; } sServer; #define LOGIN_RESULT_UNKNOWN 1 #define LOGIN_RESULT_SUCCESS 2 #define LOGIN_RESULT_FAIL 3 #define LOGIN_RESULT_ERROR 4 typedef struct __sLogin { struct __sServer *psServer; struct __sUser *psUser; int iResult; char *pErrorMsg; int iId; int iLoginsDone; // number of logins performed by this thread } sLogin; #define AUDIT_IN_PROGRESS 0 #define AUDIT_COMPLETE 1 #define LIST_IN_PROGRESS 0 #define LIST_COMPLETE 1 #define FOUND_PAIR_EXIT_HOST 1 #define FOUND_PAIR_EXIT_AUDIT 2 #define PARALLEL_LOGINS_USER 1 #define PARALLEL_LOGINS_PASSWORD 2 #define AUDIT_ABORT 1 typedef struct __sAudit { char *pOptHost; // user specified host or host file char *pOptUser; // user specified username or username file char *pOptPass; // user specified password or password file char *pOptCombo; // user specified combo host/username/password file char *pOptOutput; // user specified output file char *pOptResume; // user specified resume command char *pModuleName; // current module name char *pGlobalHost; char *pGlobalUser; char *pGlobalPass; char *pGlobalCombo; char *pHostFile; char *pUserFile; char *pPassFile; char *pComboFile; int iHostCnt; // total number of hosts supplied for testing int iUserCnt; // total number of users supplied for testing int iPassCnt; // total number of passwords supplied for testing int iComboCnt; // total number of entries in combo file int iServerCnt; // total number of hosts scanned concurrently int iLoginCnt; // total number of logins performed concurrently int iHostsDone; // number of hosts tested int iPortOverride; // use this port instead of the module's default port int iUseSSL; // enable SSL int iTimeout; // Number of seconds to wait before a connection times out int iRetryWait; // Number of seconds to wait between retries int iRetries; // Number of retries to attempt int iSocketWait; // Number of usec to wait when module calls medusaCheckSocket function int HostType; int UserType; int PassType; int iShowModuleHelp; // Flag used to show individual module help char *pComboEntryTmp; // used to managed processing of user supplied files int iHostListFlag; int iUserListFlag; int iAuditFlag; /* Tracks loading of user supplied information */ int iPasswordBlankFlag; /* Submit a blank password for each user account */ int iPasswordUsernameFlag; /* Submit a password matching the username for each user account */ int iFoundPairExitFlag; /* When a valid login pair is found, end scan of host or of complete audit */ int iParallelLoginFlag; /* Parallel logins by user or password */ int iValidPairFound; int iStatus; /* Flag to indicate to threads that audit is aborting */ sHost *psHostRoot; thr_pool_t *server_pool; pthread_mutex_t ptmMutex; } sAudit; typedef struct __sModuleStart { char* szModuleName; sLogin* pLogin; int argc; char** argv; } sModuleStart; void listModules(char* arrPaths[], int nTerminateNow); int invokeModule(char* pModuleName, sLogin* pLogin, int argc, char* argv[]); int getNextCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet); void setPassResult(sLogin *_psLogin, char *_pPass); int addMissedCredSet(sLogin *_psLogin, sCredentialSet *_psCredSet); #endif jmk-foofus-medusa-dd62069/src/modsrc/000077500000000000000000000000001460263104500174655ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/src/modsrc/Makefile.am000066400000000000000000000103011460263104500215140ustar00rootroot00000000000000 modulesdir = $(libdir)/medusa/modules EXTRA_PROGRAMS = afp.mod cvs.mod ftp.mod http.mod imap.mod mssql.mod mysql.mod ncp.mod nntp.mod pcanywhere.mod \ pop3.mod postgres.mod rdp.mod rexec.mod rlogin.mod rsh.mod smbnt.mod smtp.mod smtp-vrfy.mod \ snmp.mod ssh.mod svn.mod telnet.mod vmauthd.mod vnc.mod web-form.mod wrapper.mod modules_PROGRAMS = if BUILD_MODULE_AFP modules_PROGRAMS += afp.mod endif if BUILD_MODULE_CVS modules_PROGRAMS += cvs.mod endif if BUILD_MODULE_FTP modules_PROGRAMS += ftp.mod endif if BUILD_MODULE_HTTP modules_PROGRAMS += http.mod endif if BUILD_MODULE_IMAP modules_PROGRAMS += imap.mod endif if BUILD_MODULE_MSSQL modules_PROGRAMS += mssql.mod endif if BUILD_MODULE_MYSQL modules_PROGRAMS += mysql.mod endif if BUILD_MODULE_NCP modules_PROGRAMS += ncp.mod endif if BUILD_MODULE_NNTP modules_PROGRAMS += nntp.mod endif if BUILD_MODULE_PCANYWHERE modules_PROGRAMS += pcanywhere.mod endif if BUILD_MODULE_POP3 modules_PROGRAMS += pop3.mod endif if BUILD_MODULE_POSTGRES modules_PROGRAMS += postgres.mod endif if BUILD_MODULE_RDP modules_PROGRAMS += rdp.mod endif if BUILD_MODULE_REXEC modules_PROGRAMS += rexec.mod endif if BUILD_MODULE_RLOGIN modules_PROGRAMS += rlogin.mod endif if BUILD_MODULE_RSH modules_PROGRAMS += rsh.mod endif if BUILD_MODULE_SMBNT modules_PROGRAMS += smbnt.mod endif if BUILD_MODULE_SMTP modules_PROGRAMS += smtp.mod endif if BUILD_MODULE_SMTP_VRFY modules_PROGRAMS += smtp-vrfy.mod endif if BUILD_MODULE_SNMP modules_PROGRAMS += snmp.mod endif if BUILD_MODULE_SSH modules_PROGRAMS += ssh.mod endif if BUILD_MODULE_SVN modules_PROGRAMS += svn.mod endif if BUILD_MODULE_TELNET modules_PROGRAMS += telnet.mod endif if BUILD_MODULE_VMAUTHD modules_PROGRAMS += vmauthd.mod endif if BUILD_MODULE_VNC modules_PROGRAMS += vnc.mod endif if BUILD_MODULE_WEB_FORM modules_PROGRAMS += web-form.mod endif if BUILD_MODULE_WRAPPER modules_PROGRAMS += wrapper.mod endif afp_mod_SOURCES = afp.c ../medusa-trace.c cvs_mod_SOURCES = cvs.c ../medusa-trace.c ftp_mod_SOURCES = ftp.c ../medusa-trace.c http_mod_SOURCES = http.c ntlm.c http-digest.c ../medusa-trace.c imap_mod_SOURCES = imap.c ntlm.c ../medusa-trace.c mssql_mod_SOURCES = mssql.c ../medusa-trace.c mysql_mod_SOURCES = mysql.c ../medusa-trace.c sha1.c ncp_mod_SOURCES = ncp.c ../medusa-trace.c nntp_mod_SOURCES = nntp.c ../medusa-trace.c pcanywhere_mod_SOURCES = pcanywhere.c ../medusa-trace.c pop3_mod_SOURCES = pop3.c ntlm.c ../medusa-trace.c postgres_mod_SOURCES = postgres.c ../medusa-trace.c rdp_mod_SOURCES = rdp.c ../medusa-trace.c rexec_mod_SOURCES = rexec.c ../medusa-trace.c rlogin_mod_SOURCES = rlogin.c ../medusa-trace.c rsh_mod_SOURCES = rsh.c ../medusa-trace.c smbnt_mod_SOURCES = smbnt.c smbnt-smb1.c smbnt-smb2.c hmacmd5.c ../medusa-trace.c smtp_mod_SOURCES = smtp.c ntlm.c ../medusa-trace.c smtp_vrfy_mod_SOURCES = smtp-vrfy.c ../medusa-trace.c snmp_mod_SOURCES = snmp.c ../medusa-trace.c ssh_mod_SOURCES = ssh.c ../medusa-trace.c svn_mod_SOURCES = svn.c ../medusa-trace.c telnet_mod_SOURCES = telnet.c ../medusa-trace.c vmauthd_mod_SOURCES = vmauthd.c ../medusa-trace.c vnc_mod_SOURCES = vnc.c d3des.c ../medusa-trace.c web_form_mod_SOURCES = web-form.c ../medusa-trace.c wrapper_mod_SOURCES = wrapper.c ../medusa-trace.c AM_CPPFLAGS = -I$(top_srcdir)/src $(all_includes) afp_mod_LDFLAGS = -fPIC cvs_mod_LDFLAGS = -fPIC ftp_mod_LDFLAGS = -fPIC http_mod_LDFLAGS = -fPIC imap_mod_LDFLAGS = -fPIC mssql_mod_LDFLAGS = -fPIC mysql_mod_LDFLAGS = -fPIC ncp_mod_LDFLAGS = -fPIC nntp_mod_LDFLAGS = -fPIC pcanywhere_mod_LDFLAGS = -fPIC pop3_mod_LDFLAGS = -fPIC postgres_mod_LDFLAGS = -fPIC rdp_mod_LDFLAGS = -fPIC rexec_mod_LDFLAGS = -fPIC rlogin_mod_LDFLAGS = -fPIC rsh_mod_LDFLAGS = -fPIC smbnt_mod_LDFLAGS = -fPIC smtp_mod_LDFLAGS = -fPIC smtp_vrfy_mod_LDFLAGS = -fPIC snmp_mod_LDFLAGS = -fPIC ssh_mod_LDFLAGS = -fPIC svn_mod_LDFLAGS = -fPIC telnet_mod_LDFLAGS = -fPIC vmauthd_mod_LDFLAGS = -fPIC vnc_mod_LDFLAGS = -fPIC web_form_mod_LDFLAGS = -fPIC wrapper_mod_LDFLAGS = -fPIC LDADD = @MODULE_LIBS@ noinst_HEADERS = module.h d3des.h sha1.h hmacmd5.h http-digest.h ntlm.h smbnt.h EXTRA_DIST_WRAPPER != ls $(srcdir)/wrapper/*.pl EXTRA_DIST = $(EXTRA_DIST_WRAPPER) jmk-foofus-medusa-dd62069/src/modsrc/Makefile.in000066400000000000000000001074361460263104500215450ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ EXTRA_PROGRAMS = afp.mod$(EXEEXT) cvs.mod$(EXEEXT) ftp.mod$(EXEEXT) \ http.mod$(EXEEXT) imap.mod$(EXEEXT) mssql.mod$(EXEEXT) \ mysql.mod$(EXEEXT) ncp.mod$(EXEEXT) nntp.mod$(EXEEXT) \ pcanywhere.mod$(EXEEXT) pop3.mod$(EXEEXT) \ postgres.mod$(EXEEXT) rdp.mod$(EXEEXT) rexec.mod$(EXEEXT) \ rlogin.mod$(EXEEXT) rsh.mod$(EXEEXT) smbnt.mod$(EXEEXT) \ smtp.mod$(EXEEXT) smtp-vrfy.mod$(EXEEXT) snmp.mod$(EXEEXT) \ ssh.mod$(EXEEXT) svn.mod$(EXEEXT) telnet.mod$(EXEEXT) \ vmauthd.mod$(EXEEXT) vnc.mod$(EXEEXT) web-form.mod$(EXEEXT) \ wrapper.mod$(EXEEXT) modules_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ $(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \ $(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \ $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) \ $(am__EXEEXT_16) $(am__EXEEXT_17) $(am__EXEEXT_18) \ $(am__EXEEXT_19) $(am__EXEEXT_20) $(am__EXEEXT_21) \ $(am__EXEEXT_22) $(am__EXEEXT_23) $(am__EXEEXT_24) \ $(am__EXEEXT_25) $(am__EXEEXT_26) $(am__EXEEXT_27) @BUILD_MODULE_AFP_TRUE@am__append_1 = afp.mod @BUILD_MODULE_CVS_TRUE@am__append_2 = cvs.mod @BUILD_MODULE_FTP_TRUE@am__append_3 = ftp.mod @BUILD_MODULE_HTTP_TRUE@am__append_4 = http.mod @BUILD_MODULE_IMAP_TRUE@am__append_5 = imap.mod @BUILD_MODULE_MSSQL_TRUE@am__append_6 = mssql.mod @BUILD_MODULE_MYSQL_TRUE@am__append_7 = mysql.mod @BUILD_MODULE_NCP_TRUE@am__append_8 = ncp.mod @BUILD_MODULE_NNTP_TRUE@am__append_9 = nntp.mod @BUILD_MODULE_PCANYWHERE_TRUE@am__append_10 = pcanywhere.mod @BUILD_MODULE_POP3_TRUE@am__append_11 = pop3.mod @BUILD_MODULE_POSTGRES_TRUE@am__append_12 = postgres.mod @BUILD_MODULE_RDP_TRUE@am__append_13 = rdp.mod @BUILD_MODULE_REXEC_TRUE@am__append_14 = rexec.mod @BUILD_MODULE_RLOGIN_TRUE@am__append_15 = rlogin.mod @BUILD_MODULE_RSH_TRUE@am__append_16 = rsh.mod @BUILD_MODULE_SMBNT_TRUE@am__append_17 = smbnt.mod @BUILD_MODULE_SMTP_TRUE@am__append_18 = smtp.mod @BUILD_MODULE_SMTP_VRFY_TRUE@am__append_19 = smtp-vrfy.mod @BUILD_MODULE_SNMP_TRUE@am__append_20 = snmp.mod @BUILD_MODULE_SSH_TRUE@am__append_21 = ssh.mod @BUILD_MODULE_SVN_TRUE@am__append_22 = svn.mod @BUILD_MODULE_TELNET_TRUE@am__append_23 = telnet.mod @BUILD_MODULE_VMAUTHD_TRUE@am__append_24 = vmauthd.mod @BUILD_MODULE_VNC_TRUE@am__append_25 = vnc.mod @BUILD_MODULE_WEB_FORM_TRUE@am__append_26 = web-form.mod @BUILD_MODULE_WRAPPER_TRUE@am__append_27 = wrapper.mod subdir = src/modsrc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @BUILD_MODULE_AFP_TRUE@am__EXEEXT_1 = afp.mod$(EXEEXT) @BUILD_MODULE_CVS_TRUE@am__EXEEXT_2 = cvs.mod$(EXEEXT) @BUILD_MODULE_FTP_TRUE@am__EXEEXT_3 = ftp.mod$(EXEEXT) @BUILD_MODULE_HTTP_TRUE@am__EXEEXT_4 = http.mod$(EXEEXT) @BUILD_MODULE_IMAP_TRUE@am__EXEEXT_5 = imap.mod$(EXEEXT) @BUILD_MODULE_MSSQL_TRUE@am__EXEEXT_6 = mssql.mod$(EXEEXT) @BUILD_MODULE_MYSQL_TRUE@am__EXEEXT_7 = mysql.mod$(EXEEXT) @BUILD_MODULE_NCP_TRUE@am__EXEEXT_8 = ncp.mod$(EXEEXT) @BUILD_MODULE_NNTP_TRUE@am__EXEEXT_9 = nntp.mod$(EXEEXT) @BUILD_MODULE_PCANYWHERE_TRUE@am__EXEEXT_10 = pcanywhere.mod$(EXEEXT) @BUILD_MODULE_POP3_TRUE@am__EXEEXT_11 = pop3.mod$(EXEEXT) @BUILD_MODULE_POSTGRES_TRUE@am__EXEEXT_12 = postgres.mod$(EXEEXT) @BUILD_MODULE_RDP_TRUE@am__EXEEXT_13 = rdp.mod$(EXEEXT) @BUILD_MODULE_REXEC_TRUE@am__EXEEXT_14 = rexec.mod$(EXEEXT) @BUILD_MODULE_RLOGIN_TRUE@am__EXEEXT_15 = rlogin.mod$(EXEEXT) @BUILD_MODULE_RSH_TRUE@am__EXEEXT_16 = rsh.mod$(EXEEXT) @BUILD_MODULE_SMBNT_TRUE@am__EXEEXT_17 = smbnt.mod$(EXEEXT) @BUILD_MODULE_SMTP_TRUE@am__EXEEXT_18 = smtp.mod$(EXEEXT) @BUILD_MODULE_SMTP_VRFY_TRUE@am__EXEEXT_19 = smtp-vrfy.mod$(EXEEXT) @BUILD_MODULE_SNMP_TRUE@am__EXEEXT_20 = snmp.mod$(EXEEXT) @BUILD_MODULE_SSH_TRUE@am__EXEEXT_21 = ssh.mod$(EXEEXT) @BUILD_MODULE_SVN_TRUE@am__EXEEXT_22 = svn.mod$(EXEEXT) @BUILD_MODULE_TELNET_TRUE@am__EXEEXT_23 = telnet.mod$(EXEEXT) @BUILD_MODULE_VMAUTHD_TRUE@am__EXEEXT_24 = vmauthd.mod$(EXEEXT) @BUILD_MODULE_VNC_TRUE@am__EXEEXT_25 = vnc.mod$(EXEEXT) @BUILD_MODULE_WEB_FORM_TRUE@am__EXEEXT_26 = web-form.mod$(EXEEXT) @BUILD_MODULE_WRAPPER_TRUE@am__EXEEXT_27 = wrapper.mod$(EXEEXT) am__installdirs = "$(DESTDIR)$(modulesdir)" PROGRAMS = $(modules_PROGRAMS) am__dirstamp = $(am__leading_dot)dirstamp am_afp_mod_OBJECTS = afp.$(OBJEXT) ../medusa-trace.$(OBJEXT) afp_mod_OBJECTS = $(am_afp_mod_OBJECTS) afp_mod_LDADD = $(LDADD) afp_mod_DEPENDENCIES = afp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(afp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_cvs_mod_OBJECTS = cvs.$(OBJEXT) ../medusa-trace.$(OBJEXT) cvs_mod_OBJECTS = $(am_cvs_mod_OBJECTS) cvs_mod_LDADD = $(LDADD) cvs_mod_DEPENDENCIES = cvs_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(cvs_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_ftp_mod_OBJECTS = ftp.$(OBJEXT) ../medusa-trace.$(OBJEXT) ftp_mod_OBJECTS = $(am_ftp_mod_OBJECTS) ftp_mod_LDADD = $(LDADD) ftp_mod_DEPENDENCIES = ftp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ftp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_http_mod_OBJECTS = http.$(OBJEXT) ntlm.$(OBJEXT) \ http-digest.$(OBJEXT) ../medusa-trace.$(OBJEXT) http_mod_OBJECTS = $(am_http_mod_OBJECTS) http_mod_LDADD = $(LDADD) http_mod_DEPENDENCIES = http_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(http_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_imap_mod_OBJECTS = imap.$(OBJEXT) ntlm.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) imap_mod_OBJECTS = $(am_imap_mod_OBJECTS) imap_mod_LDADD = $(LDADD) imap_mod_DEPENDENCIES = imap_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(imap_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_mssql_mod_OBJECTS = mssql.$(OBJEXT) ../medusa-trace.$(OBJEXT) mssql_mod_OBJECTS = $(am_mssql_mod_OBJECTS) mssql_mod_LDADD = $(LDADD) mssql_mod_DEPENDENCIES = mssql_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(mssql_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_mysql_mod_OBJECTS = mysql.$(OBJEXT) ../medusa-trace.$(OBJEXT) \ sha1.$(OBJEXT) mysql_mod_OBJECTS = $(am_mysql_mod_OBJECTS) mysql_mod_LDADD = $(LDADD) mysql_mod_DEPENDENCIES = mysql_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(mysql_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_ncp_mod_OBJECTS = ncp.$(OBJEXT) ../medusa-trace.$(OBJEXT) ncp_mod_OBJECTS = $(am_ncp_mod_OBJECTS) ncp_mod_LDADD = $(LDADD) ncp_mod_DEPENDENCIES = ncp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ncp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_nntp_mod_OBJECTS = nntp.$(OBJEXT) ../medusa-trace.$(OBJEXT) nntp_mod_OBJECTS = $(am_nntp_mod_OBJECTS) nntp_mod_LDADD = $(LDADD) nntp_mod_DEPENDENCIES = nntp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(nntp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_pcanywhere_mod_OBJECTS = pcanywhere.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) pcanywhere_mod_OBJECTS = $(am_pcanywhere_mod_OBJECTS) pcanywhere_mod_LDADD = $(LDADD) pcanywhere_mod_DEPENDENCIES = pcanywhere_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pcanywhere_mod_LDFLAGS) $(LDFLAGS) -o $@ am_pop3_mod_OBJECTS = pop3.$(OBJEXT) ntlm.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) pop3_mod_OBJECTS = $(am_pop3_mod_OBJECTS) pop3_mod_LDADD = $(LDADD) pop3_mod_DEPENDENCIES = pop3_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(pop3_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_postgres_mod_OBJECTS = postgres.$(OBJEXT) ../medusa-trace.$(OBJEXT) postgres_mod_OBJECTS = $(am_postgres_mod_OBJECTS) postgres_mod_LDADD = $(LDADD) postgres_mod_DEPENDENCIES = postgres_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(postgres_mod_LDFLAGS) $(LDFLAGS) -o $@ am_rdp_mod_OBJECTS = rdp.$(OBJEXT) ../medusa-trace.$(OBJEXT) rdp_mod_OBJECTS = $(am_rdp_mod_OBJECTS) rdp_mod_LDADD = $(LDADD) rdp_mod_DEPENDENCIES = rdp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rdp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_rexec_mod_OBJECTS = rexec.$(OBJEXT) ../medusa-trace.$(OBJEXT) rexec_mod_OBJECTS = $(am_rexec_mod_OBJECTS) rexec_mod_LDADD = $(LDADD) rexec_mod_DEPENDENCIES = rexec_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rexec_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_rlogin_mod_OBJECTS = rlogin.$(OBJEXT) ../medusa-trace.$(OBJEXT) rlogin_mod_OBJECTS = $(am_rlogin_mod_OBJECTS) rlogin_mod_LDADD = $(LDADD) rlogin_mod_DEPENDENCIES = rlogin_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rlogin_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_rsh_mod_OBJECTS = rsh.$(OBJEXT) ../medusa-trace.$(OBJEXT) rsh_mod_OBJECTS = $(am_rsh_mod_OBJECTS) rsh_mod_LDADD = $(LDADD) rsh_mod_DEPENDENCIES = rsh_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(rsh_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_smbnt_mod_OBJECTS = smbnt.$(OBJEXT) smbnt-smb1.$(OBJEXT) \ smbnt-smb2.$(OBJEXT) hmacmd5.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) smbnt_mod_OBJECTS = $(am_smbnt_mod_OBJECTS) smbnt_mod_LDADD = $(LDADD) smbnt_mod_DEPENDENCIES = smbnt_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(smbnt_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_smtp_vrfy_mod_OBJECTS = smtp-vrfy.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) smtp_vrfy_mod_OBJECTS = $(am_smtp_vrfy_mod_OBJECTS) smtp_vrfy_mod_LDADD = $(LDADD) smtp_vrfy_mod_DEPENDENCIES = smtp_vrfy_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(smtp_vrfy_mod_LDFLAGS) $(LDFLAGS) -o $@ am_smtp_mod_OBJECTS = smtp.$(OBJEXT) ntlm.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) smtp_mod_OBJECTS = $(am_smtp_mod_OBJECTS) smtp_mod_LDADD = $(LDADD) smtp_mod_DEPENDENCIES = smtp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(smtp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_snmp_mod_OBJECTS = snmp.$(OBJEXT) ../medusa-trace.$(OBJEXT) snmp_mod_OBJECTS = $(am_snmp_mod_OBJECTS) snmp_mod_LDADD = $(LDADD) snmp_mod_DEPENDENCIES = snmp_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(snmp_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_ssh_mod_OBJECTS = ssh.$(OBJEXT) ../medusa-trace.$(OBJEXT) ssh_mod_OBJECTS = $(am_ssh_mod_OBJECTS) ssh_mod_LDADD = $(LDADD) ssh_mod_DEPENDENCIES = ssh_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ssh_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_svn_mod_OBJECTS = svn.$(OBJEXT) ../medusa-trace.$(OBJEXT) svn_mod_OBJECTS = $(am_svn_mod_OBJECTS) svn_mod_LDADD = $(LDADD) svn_mod_DEPENDENCIES = svn_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(svn_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_telnet_mod_OBJECTS = telnet.$(OBJEXT) ../medusa-trace.$(OBJEXT) telnet_mod_OBJECTS = $(am_telnet_mod_OBJECTS) telnet_mod_LDADD = $(LDADD) telnet_mod_DEPENDENCIES = telnet_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(telnet_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_vmauthd_mod_OBJECTS = vmauthd.$(OBJEXT) ../medusa-trace.$(OBJEXT) vmauthd_mod_OBJECTS = $(am_vmauthd_mod_OBJECTS) vmauthd_mod_LDADD = $(LDADD) vmauthd_mod_DEPENDENCIES = vmauthd_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(vmauthd_mod_LDFLAGS) $(LDFLAGS) -o $@ am_vnc_mod_OBJECTS = vnc.$(OBJEXT) d3des.$(OBJEXT) \ ../medusa-trace.$(OBJEXT) vnc_mod_OBJECTS = $(am_vnc_mod_OBJECTS) vnc_mod_LDADD = $(LDADD) vnc_mod_DEPENDENCIES = vnc_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(vnc_mod_LDFLAGS) \ $(LDFLAGS) -o $@ am_web_form_mod_OBJECTS = web-form.$(OBJEXT) ../medusa-trace.$(OBJEXT) web_form_mod_OBJECTS = $(am_web_form_mod_OBJECTS) web_form_mod_LDADD = $(LDADD) web_form_mod_DEPENDENCIES = web_form_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(web_form_mod_LDFLAGS) $(LDFLAGS) -o $@ am_wrapper_mod_OBJECTS = wrapper.$(OBJEXT) ../medusa-trace.$(OBJEXT) wrapper_mod_OBJECTS = $(am_wrapper_mod_OBJECTS) wrapper_mod_LDADD = $(LDADD) wrapper_mod_DEPENDENCIES = wrapper_mod_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(wrapper_mod_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__maybe_remake_depfiles = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(afp_mod_SOURCES) $(cvs_mod_SOURCES) $(ftp_mod_SOURCES) \ $(http_mod_SOURCES) $(imap_mod_SOURCES) $(mssql_mod_SOURCES) \ $(mysql_mod_SOURCES) $(ncp_mod_SOURCES) $(nntp_mod_SOURCES) \ $(pcanywhere_mod_SOURCES) $(pop3_mod_SOURCES) \ $(postgres_mod_SOURCES) $(rdp_mod_SOURCES) \ $(rexec_mod_SOURCES) $(rlogin_mod_SOURCES) $(rsh_mod_SOURCES) \ $(smbnt_mod_SOURCES) $(smtp_vrfy_mod_SOURCES) \ $(smtp_mod_SOURCES) $(snmp_mod_SOURCES) $(ssh_mod_SOURCES) \ $(svn_mod_SOURCES) $(telnet_mod_SOURCES) \ $(vmauthd_mod_SOURCES) $(vnc_mod_SOURCES) \ $(web_form_mod_SOURCES) $(wrapper_mod_SOURCES) DIST_SOURCES = $(afp_mod_SOURCES) $(cvs_mod_SOURCES) \ $(ftp_mod_SOURCES) $(http_mod_SOURCES) $(imap_mod_SOURCES) \ $(mssql_mod_SOURCES) $(mysql_mod_SOURCES) $(ncp_mod_SOURCES) \ $(nntp_mod_SOURCES) $(pcanywhere_mod_SOURCES) \ $(pop3_mod_SOURCES) $(postgres_mod_SOURCES) $(rdp_mod_SOURCES) \ $(rexec_mod_SOURCES) $(rlogin_mod_SOURCES) $(rsh_mod_SOURCES) \ $(smbnt_mod_SOURCES) $(smtp_vrfy_mod_SOURCES) \ $(smtp_mod_SOURCES) $(snmp_mod_SOURCES) $(ssh_mod_SOURCES) \ $(svn_mod_SOURCES) $(telnet_mod_SOURCES) \ $(vmauthd_mod_SOURCES) $(vnc_mod_SOURCES) \ $(web_form_mod_SOURCES) $(wrapper_mod_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac HEADERS = $(noinst_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APR_CONFIG = @APR_CONFIG@ APR_INCLUDE_DIR = @APR_INCLUDE_DIR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFAULT_MOD_PATH = @DEFAULT_MOD_PATH@ DEFS = @DEFS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MODULE_LIBS = @MODULE_LIBS@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__leading_dot = @am__leading_dot@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ modulesdir = $(libdir)/medusa/modules afp_mod_SOURCES = afp.c ../medusa-trace.c cvs_mod_SOURCES = cvs.c ../medusa-trace.c ftp_mod_SOURCES = ftp.c ../medusa-trace.c http_mod_SOURCES = http.c ntlm.c http-digest.c ../medusa-trace.c imap_mod_SOURCES = imap.c ntlm.c ../medusa-trace.c mssql_mod_SOURCES = mssql.c ../medusa-trace.c mysql_mod_SOURCES = mysql.c ../medusa-trace.c sha1.c ncp_mod_SOURCES = ncp.c ../medusa-trace.c nntp_mod_SOURCES = nntp.c ../medusa-trace.c pcanywhere_mod_SOURCES = pcanywhere.c ../medusa-trace.c pop3_mod_SOURCES = pop3.c ntlm.c ../medusa-trace.c postgres_mod_SOURCES = postgres.c ../medusa-trace.c rdp_mod_SOURCES = rdp.c ../medusa-trace.c rexec_mod_SOURCES = rexec.c ../medusa-trace.c rlogin_mod_SOURCES = rlogin.c ../medusa-trace.c rsh_mod_SOURCES = rsh.c ../medusa-trace.c smbnt_mod_SOURCES = smbnt.c smbnt-smb1.c smbnt-smb2.c hmacmd5.c ../medusa-trace.c smtp_mod_SOURCES = smtp.c ntlm.c ../medusa-trace.c smtp_vrfy_mod_SOURCES = smtp-vrfy.c ../medusa-trace.c snmp_mod_SOURCES = snmp.c ../medusa-trace.c ssh_mod_SOURCES = ssh.c ../medusa-trace.c svn_mod_SOURCES = svn.c ../medusa-trace.c telnet_mod_SOURCES = telnet.c ../medusa-trace.c vmauthd_mod_SOURCES = vmauthd.c ../medusa-trace.c vnc_mod_SOURCES = vnc.c d3des.c ../medusa-trace.c web_form_mod_SOURCES = web-form.c ../medusa-trace.c wrapper_mod_SOURCES = wrapper.c ../medusa-trace.c AM_CPPFLAGS = -I$(top_srcdir)/src $(all_includes) afp_mod_LDFLAGS = -fPIC cvs_mod_LDFLAGS = -fPIC ftp_mod_LDFLAGS = -fPIC http_mod_LDFLAGS = -fPIC imap_mod_LDFLAGS = -fPIC mssql_mod_LDFLAGS = -fPIC mysql_mod_LDFLAGS = -fPIC ncp_mod_LDFLAGS = -fPIC nntp_mod_LDFLAGS = -fPIC pcanywhere_mod_LDFLAGS = -fPIC pop3_mod_LDFLAGS = -fPIC postgres_mod_LDFLAGS = -fPIC rdp_mod_LDFLAGS = -fPIC rexec_mod_LDFLAGS = -fPIC rlogin_mod_LDFLAGS = -fPIC rsh_mod_LDFLAGS = -fPIC smbnt_mod_LDFLAGS = -fPIC smtp_mod_LDFLAGS = -fPIC smtp_vrfy_mod_LDFLAGS = -fPIC snmp_mod_LDFLAGS = -fPIC ssh_mod_LDFLAGS = -fPIC svn_mod_LDFLAGS = -fPIC telnet_mod_LDFLAGS = -fPIC vmauthd_mod_LDFLAGS = -fPIC vnc_mod_LDFLAGS = -fPIC web_form_mod_LDFLAGS = -fPIC wrapper_mod_LDFLAGS = -fPIC LDADD = @MODULE_LIBS@ noinst_HEADERS = module.h d3des.h sha1.h hmacmd5.h http-digest.h ntlm.h smbnt.h EXTRA_DIST = $(EXTRA_DIST_WRAPPER) all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps src/modsrc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu --ignore-deps src/modsrc/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-modulesPROGRAMS: $(modules_PROGRAMS) @$(NORMAL_INSTALL) @list='$(modules_PROGRAMS)'; test -n "$(modulesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(modulesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(modulesdir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(modulesdir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(modulesdir)$$dir" || exit $$?; \ } \ ; done uninstall-modulesPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(modules_PROGRAMS)'; test -n "$(modulesdir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(modulesdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(modulesdir)" && rm -f $$files clean-modulesPROGRAMS: -test -z "$(modules_PROGRAMS)" || rm -f $(modules_PROGRAMS) ../$(am__dirstamp): @$(MKDIR_P) .. @: > ../$(am__dirstamp) ../medusa-trace.$(OBJEXT): ../$(am__dirstamp) afp.mod$(EXEEXT): $(afp_mod_OBJECTS) $(afp_mod_DEPENDENCIES) $(EXTRA_afp_mod_DEPENDENCIES) @rm -f afp.mod$(EXEEXT) $(AM_V_CCLD)$(afp_mod_LINK) $(afp_mod_OBJECTS) $(afp_mod_LDADD) $(LIBS) cvs.mod$(EXEEXT): $(cvs_mod_OBJECTS) $(cvs_mod_DEPENDENCIES) $(EXTRA_cvs_mod_DEPENDENCIES) @rm -f cvs.mod$(EXEEXT) $(AM_V_CCLD)$(cvs_mod_LINK) $(cvs_mod_OBJECTS) $(cvs_mod_LDADD) $(LIBS) ftp.mod$(EXEEXT): $(ftp_mod_OBJECTS) $(ftp_mod_DEPENDENCIES) $(EXTRA_ftp_mod_DEPENDENCIES) @rm -f ftp.mod$(EXEEXT) $(AM_V_CCLD)$(ftp_mod_LINK) $(ftp_mod_OBJECTS) $(ftp_mod_LDADD) $(LIBS) http.mod$(EXEEXT): $(http_mod_OBJECTS) $(http_mod_DEPENDENCIES) $(EXTRA_http_mod_DEPENDENCIES) @rm -f http.mod$(EXEEXT) $(AM_V_CCLD)$(http_mod_LINK) $(http_mod_OBJECTS) $(http_mod_LDADD) $(LIBS) imap.mod$(EXEEXT): $(imap_mod_OBJECTS) $(imap_mod_DEPENDENCIES) $(EXTRA_imap_mod_DEPENDENCIES) @rm -f imap.mod$(EXEEXT) $(AM_V_CCLD)$(imap_mod_LINK) $(imap_mod_OBJECTS) $(imap_mod_LDADD) $(LIBS) mssql.mod$(EXEEXT): $(mssql_mod_OBJECTS) $(mssql_mod_DEPENDENCIES) $(EXTRA_mssql_mod_DEPENDENCIES) @rm -f mssql.mod$(EXEEXT) $(AM_V_CCLD)$(mssql_mod_LINK) $(mssql_mod_OBJECTS) $(mssql_mod_LDADD) $(LIBS) mysql.mod$(EXEEXT): $(mysql_mod_OBJECTS) $(mysql_mod_DEPENDENCIES) $(EXTRA_mysql_mod_DEPENDENCIES) @rm -f mysql.mod$(EXEEXT) $(AM_V_CCLD)$(mysql_mod_LINK) $(mysql_mod_OBJECTS) $(mysql_mod_LDADD) $(LIBS) ncp.mod$(EXEEXT): $(ncp_mod_OBJECTS) $(ncp_mod_DEPENDENCIES) $(EXTRA_ncp_mod_DEPENDENCIES) @rm -f ncp.mod$(EXEEXT) $(AM_V_CCLD)$(ncp_mod_LINK) $(ncp_mod_OBJECTS) $(ncp_mod_LDADD) $(LIBS) nntp.mod$(EXEEXT): $(nntp_mod_OBJECTS) $(nntp_mod_DEPENDENCIES) $(EXTRA_nntp_mod_DEPENDENCIES) @rm -f nntp.mod$(EXEEXT) $(AM_V_CCLD)$(nntp_mod_LINK) $(nntp_mod_OBJECTS) $(nntp_mod_LDADD) $(LIBS) pcanywhere.mod$(EXEEXT): $(pcanywhere_mod_OBJECTS) $(pcanywhere_mod_DEPENDENCIES) $(EXTRA_pcanywhere_mod_DEPENDENCIES) @rm -f pcanywhere.mod$(EXEEXT) $(AM_V_CCLD)$(pcanywhere_mod_LINK) $(pcanywhere_mod_OBJECTS) $(pcanywhere_mod_LDADD) $(LIBS) pop3.mod$(EXEEXT): $(pop3_mod_OBJECTS) $(pop3_mod_DEPENDENCIES) $(EXTRA_pop3_mod_DEPENDENCIES) @rm -f pop3.mod$(EXEEXT) $(AM_V_CCLD)$(pop3_mod_LINK) $(pop3_mod_OBJECTS) $(pop3_mod_LDADD) $(LIBS) postgres.mod$(EXEEXT): $(postgres_mod_OBJECTS) $(postgres_mod_DEPENDENCIES) $(EXTRA_postgres_mod_DEPENDENCIES) @rm -f postgres.mod$(EXEEXT) $(AM_V_CCLD)$(postgres_mod_LINK) $(postgres_mod_OBJECTS) $(postgres_mod_LDADD) $(LIBS) rdp.mod$(EXEEXT): $(rdp_mod_OBJECTS) $(rdp_mod_DEPENDENCIES) $(EXTRA_rdp_mod_DEPENDENCIES) @rm -f rdp.mod$(EXEEXT) $(AM_V_CCLD)$(rdp_mod_LINK) $(rdp_mod_OBJECTS) $(rdp_mod_LDADD) $(LIBS) rexec.mod$(EXEEXT): $(rexec_mod_OBJECTS) $(rexec_mod_DEPENDENCIES) $(EXTRA_rexec_mod_DEPENDENCIES) @rm -f rexec.mod$(EXEEXT) $(AM_V_CCLD)$(rexec_mod_LINK) $(rexec_mod_OBJECTS) $(rexec_mod_LDADD) $(LIBS) rlogin.mod$(EXEEXT): $(rlogin_mod_OBJECTS) $(rlogin_mod_DEPENDENCIES) $(EXTRA_rlogin_mod_DEPENDENCIES) @rm -f rlogin.mod$(EXEEXT) $(AM_V_CCLD)$(rlogin_mod_LINK) $(rlogin_mod_OBJECTS) $(rlogin_mod_LDADD) $(LIBS) rsh.mod$(EXEEXT): $(rsh_mod_OBJECTS) $(rsh_mod_DEPENDENCIES) $(EXTRA_rsh_mod_DEPENDENCIES) @rm -f rsh.mod$(EXEEXT) $(AM_V_CCLD)$(rsh_mod_LINK) $(rsh_mod_OBJECTS) $(rsh_mod_LDADD) $(LIBS) smbnt.mod$(EXEEXT): $(smbnt_mod_OBJECTS) $(smbnt_mod_DEPENDENCIES) $(EXTRA_smbnt_mod_DEPENDENCIES) @rm -f smbnt.mod$(EXEEXT) $(AM_V_CCLD)$(smbnt_mod_LINK) $(smbnt_mod_OBJECTS) $(smbnt_mod_LDADD) $(LIBS) smtp-vrfy.mod$(EXEEXT): $(smtp_vrfy_mod_OBJECTS) $(smtp_vrfy_mod_DEPENDENCIES) $(EXTRA_smtp_vrfy_mod_DEPENDENCIES) @rm -f smtp-vrfy.mod$(EXEEXT) $(AM_V_CCLD)$(smtp_vrfy_mod_LINK) $(smtp_vrfy_mod_OBJECTS) $(smtp_vrfy_mod_LDADD) $(LIBS) smtp.mod$(EXEEXT): $(smtp_mod_OBJECTS) $(smtp_mod_DEPENDENCIES) $(EXTRA_smtp_mod_DEPENDENCIES) @rm -f smtp.mod$(EXEEXT) $(AM_V_CCLD)$(smtp_mod_LINK) $(smtp_mod_OBJECTS) $(smtp_mod_LDADD) $(LIBS) snmp.mod$(EXEEXT): $(snmp_mod_OBJECTS) $(snmp_mod_DEPENDENCIES) $(EXTRA_snmp_mod_DEPENDENCIES) @rm -f snmp.mod$(EXEEXT) $(AM_V_CCLD)$(snmp_mod_LINK) $(snmp_mod_OBJECTS) $(snmp_mod_LDADD) $(LIBS) ssh.mod$(EXEEXT): $(ssh_mod_OBJECTS) $(ssh_mod_DEPENDENCIES) $(EXTRA_ssh_mod_DEPENDENCIES) @rm -f ssh.mod$(EXEEXT) $(AM_V_CCLD)$(ssh_mod_LINK) $(ssh_mod_OBJECTS) $(ssh_mod_LDADD) $(LIBS) svn.mod$(EXEEXT): $(svn_mod_OBJECTS) $(svn_mod_DEPENDENCIES) $(EXTRA_svn_mod_DEPENDENCIES) @rm -f svn.mod$(EXEEXT) $(AM_V_CCLD)$(svn_mod_LINK) $(svn_mod_OBJECTS) $(svn_mod_LDADD) $(LIBS) telnet.mod$(EXEEXT): $(telnet_mod_OBJECTS) $(telnet_mod_DEPENDENCIES) $(EXTRA_telnet_mod_DEPENDENCIES) @rm -f telnet.mod$(EXEEXT) $(AM_V_CCLD)$(telnet_mod_LINK) $(telnet_mod_OBJECTS) $(telnet_mod_LDADD) $(LIBS) vmauthd.mod$(EXEEXT): $(vmauthd_mod_OBJECTS) $(vmauthd_mod_DEPENDENCIES) $(EXTRA_vmauthd_mod_DEPENDENCIES) @rm -f vmauthd.mod$(EXEEXT) $(AM_V_CCLD)$(vmauthd_mod_LINK) $(vmauthd_mod_OBJECTS) $(vmauthd_mod_LDADD) $(LIBS) vnc.mod$(EXEEXT): $(vnc_mod_OBJECTS) $(vnc_mod_DEPENDENCIES) $(EXTRA_vnc_mod_DEPENDENCIES) @rm -f vnc.mod$(EXEEXT) $(AM_V_CCLD)$(vnc_mod_LINK) $(vnc_mod_OBJECTS) $(vnc_mod_LDADD) $(LIBS) web-form.mod$(EXEEXT): $(web_form_mod_OBJECTS) $(web_form_mod_DEPENDENCIES) $(EXTRA_web_form_mod_DEPENDENCIES) @rm -f web-form.mod$(EXEEXT) $(AM_V_CCLD)$(web_form_mod_LINK) $(web_form_mod_OBJECTS) $(web_form_mod_LDADD) $(LIBS) wrapper.mod$(EXEEXT): $(wrapper_mod_OBJECTS) $(wrapper_mod_DEPENDENCIES) $(EXTRA_wrapper_mod_DEPENDENCIES) @rm -f wrapper.mod$(EXEEXT) $(AM_V_CCLD)$(wrapper_mod_LINK) $(wrapper_mod_OBJECTS) $(wrapper_mod_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../*.$(OBJEXT) distclean-compile: -rm -f *.tab.c .c.o: $(AM_V_CC)$(COMPILE) -c -o $@ $< .c.obj: $(AM_V_CC)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(modulesdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f ../$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-modulesPROGRAMS mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-modulesPROGRAMS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-modulesPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-modulesPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man \ install-modulesPROGRAMS install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-modulesPROGRAMS .PRECIOUS: Makefile EXTRA_DIST_WRAPPER != ls $(srcdir)/wrapper/*.pl # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: jmk-foofus-medusa-dd62069/src/modsrc/afp.c000066400000000000000000000267041460263104500204100ustar00rootroot00000000000000/* ** Apple Filing Protocol AFP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Module designed using afpfs-ng 0.8.1 ** AFPFS-NG: http://alexthepuffin.googlepages.com/home ** ** The following steps needed to be performed: ** copy afpfs-ng-0.8.1/include to /usr/include/afpfs-ng ** ** NOTE: autoconf is currently hard-coded to use /usr/lib/libafpclient.so.0. ** This may need to be tweaked if afpfs-ng is installed to some other ** location. ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "afp.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for AFP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: afp.c 9240 2015-05-22 17:42:18Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBAFP_WARNING "No usable LIBAFPFS. Module disabled." #ifdef HAVE_LIBAFPFS #include #include #define PORT_AFP 548 typedef struct __MODULE_DATA { } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if (argc != 0) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; ipsUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_AFP; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(&psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ static int server_subconnect(struct afp_url url) { struct afp_connection_request *conn_req; struct afp_server * server = NULL; conn_req = malloc( sizeof(struct afp_connection_request) ); server = malloc( sizeof(struct afp_server) ); memset(conn_req, 0, sizeof(struct afp_connection_request)); conn_req->url=url; conn_req->url.requested_version=31; writeError(ERR_DEBUG_MODULE, "[%s] AFP connection - username: %s password: %s server: %s", MODULE_NAME, url.username, url.password, url.servername); if (strlen(url.uamname) > 0) { if ((conn_req->uam_mask = find_uam_by_name(url.uamname)) == 0) { writeError(ERR_ERROR, "[%s] Unknown UAM: %s", MODULE_NAME, url.uamname); FREE(conn_req); FREE(server); return FAILURE; } } else { conn_req->uam_mask=default_uams_mask(); } writeError(ERR_DEBUG_MODULE, "[%s] Initiating connection attempt.", MODULE_NAME); if ((server = afp_server_full_connect(NULL, conn_req)) == NULL) { FREE(conn_req); FREE(server); return FAILURE; } writeError(ERR_DEBUG_MODULE, "[%s] Connected to server: %s via UAM: %s", MODULE_NAME, server->server_name_printable, uam_bitmap_to_string(server->using_uam)); FREE(conn_req); FREE(server); return SUCCESS; } /* This is to replace the afp library log callback function with a more medusa friendly one */ void stdout_log_for_medusa(void * priv __attribute__((unused)), enum loglevels loglevel __attribute__((unused)), int logtype __attribute__((unused)), const char *message) { writeError(ERR_DEBUG_MODULE, "[%s] libafpclient message: %s", MODULE_NAME, message); } static struct libafpclient afpclient = { .unmount_volume = NULL, .log_for_client = stdout_log_for_medusa, .forced_ending_hook = NULL, .scan_extra_fds = NULL, .loop_started = NULL , }; int tryLogin(sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; struct afp_url tmpurl; /* Build AFP authentication request */ libafpclient_register(&afpclient); afp_main_quick_startup(NULL); init_uams(); afp_default_url(&tmpurl); memcpy(&tmpurl.servername, (*psLogin)->psServer->pHostIP, AFP_SERVER_NAME_LEN); memcpy(&tmpurl.username, szLogin, AFP_MAX_USERNAME_LEN); memcpy(&tmpurl.password, szPassword, AFP_MAX_PASSWORD_LEN); if ( server_subconnect(tmpurl) == SUCCESS ) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBAFP_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBAFP_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the afpfs-ng headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the afpfs-ng headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/cvs.c000066400000000000000000000266271460263104500204410ustar00rootroot00000000000000/* ** CVS pserver Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Hydra 5.2 [van Hauser ] ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "cvs.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for CVS sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: cvs.c 9207 2015-04-16 19:19:33Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_CVS 2401 typedef struct __CVS_DATA { char *szDir; } _CVS_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _CVS_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _CVS_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DIR:? "); writeVerbose(VB_NONE, " Sets target directory name. If left unset, the default is \"/root\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M cvs -m DIR:/some_project\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _CVS_DATA *psSessionData; psSessionData = malloc(sizeof(_CVS_DATA)); memset(psSessionData, 0, sizeof(_CVS_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDir = strdup(pOpt); } else writeError(ERR_WARNING, "Method DIR requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return 0; } int initModule(sLogin* psLogin, _CVS_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_CVS; initConnectionParams(psLogin, ¶ms); /* set directory name, if not specified by user */ if (_psSessionData->szDir == NULL) { _psSessionData->szDir = malloc(6); memset(_psSessionData->szDir, 0, 6); sprintf(_psSessionData->szDir, "/root"); } writeError(ERR_DEBUG_MODULE, "[%s] Set directory name: %s", MODULE_NAME, _psSessionData->szDir); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, _CVS_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet, nSendBufferSize, nReceiveBufferSize; unsigned int i; unsigned char* bufReceive; char *szAuth, *szPassTmp; /* evil cvs encryption sheme... 0 111 P 125 p 58 ! 120 1 52 A 57 Q 55 a 121 q 113 " 53 2 75 B 83 R 54 b 117 r 32 3 119 C 43 S 66 c 104 s 90 4 49 D 46 T 124 d 101 t 44 % 109 5 34 E 102 U 126 e 100 u 98 & 72 6 82 F 40 V 59 f 69 v 60 ' 108 7 81 G 89 W 47 g 73 w 51 ( 70 8 95 H 38 X 92 h 99 x 33 ) 64 9 65 I 103 Y 71 i 63 y 97 * 76 : 112 J 45 Z 115 j 94 z 62 + 67 ; 86 K 50 k 93 , 116 < 118 L 42 l 39 - 74 = 110 M 123 m 37 . 68 > 122 N 91 n 61 / 87 ? 105 O 35 _ 56 o 48 */ char key[] = { 0, 120, 53, 0, 0, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87, 111, 52, 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105, 0, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 42, 123, 91, 35, 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 0, 0, 0, 0, 56, 0, 121, 117, 104, 101, 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62 }; /* 92 characters */ if (strlen(szPassword) > 92) { writeError(ERR_ERROR, "[%s] Password must be limited to 92 or less characters.", MODULE_NAME); return FAILURE; } szPassTmp = strdup(szPassword); for (i = 0; i < strlen(szPassTmp); i++) szPassTmp[i] = key[szPassTmp[i] - 0x20]; nSendBufferSize = strlen(_psSessionData->szDir) + strlen(szLogin) + strlen(szPassTmp) + 56; szAuth = malloc(nSendBufferSize + 1); memset(szAuth, 0, nSendBufferSize + 1); sprintf(szAuth, "BEGIN VERIFICATION REQUEST\n%s\n%s\nA%s\nEND VERIFICATION REQUEST\n", _psSessionData->szDir, szLogin, szPassTmp); if (medusaSend(hSocket, (unsigned char*)szAuth, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; if (strstr((char*)bufReceive, "I LOVE YOU\n")) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "E PAM start error: Critical error - immediate abort\n")) { writeError(ERR_ERROR, "[%s] User (%s) does not exist.", MODULE_NAME, szLogin); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "I HATE YOU\n")) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_ERROR, "[%s] Unknown Error Message: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPassword); free(szPassTmp); free(szAuth); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/d3des.c000066400000000000000000000372471460263104500206500ustar00rootroot00000000000000 /* 2001 van Hauser for Hydra: commented out KnR Kn3 and Df_Key to remove compiler warnings for unused definitions. */ /* * This is D3DES (V5.09) by Richard Outerbridge with the double and * triple-length support removed for use in VNC. Also the bytebit[] array * has been reversed so that the most significant bit in each byte of the * key is ignored, not the least significant. * * These changes are: * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * * This software 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. */ /* D3DES (V5.09) - * * A portable, public domain, version of the Data Encryption Standard. * * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, * for humouring me on. * * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. */ #include "d3des.h" static void scrunch(unsigned char *, unsigned long *); static void unscrun(unsigned long *, unsigned char *); static void desfunc(unsigned long *, unsigned long *); static void cookey(unsigned long *); static unsigned long KnL[32] = { 0L }; /* not needed ... static unsigned long KnR[32] = { 0L }; static unsigned long Kn3[32] = { 0L }; static unsigned char Df_Key[24] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; */ static unsigned short bytebit[8] = { 01, 02, 04, 010, 020, 040, 0100, 0200 }; static unsigned long bigbyte[24] = { 0x800000L, 0x400000L, 0x200000L, 0x100000L, 0x80000L, 0x40000L, 0x20000L, 0x10000L, 0x8000L, 0x4000L, 0x2000L, 0x1000L, 0x800L, 0x400L, 0x200L, 0x100L, 0x80L, 0x40L, 0x20L, 0x10L, 0x8L, 0x4L, 0x2L, 0x1L }; /* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ static unsigned char pc1[56] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; static unsigned char totrot[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; static unsigned char pc2[48] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; void deskey(key, edf) /* Thanks to James Gillogly & Phil Karn! */ unsigned char *key; int edf; { register int i, j, l, m, n; unsigned char pc1m[56], pcr[56]; unsigned long kn[32]; for (j = 0; j < 56; j++) { l = pc1[j]; m = l & 07; pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; } for (i = 0; i < 16; i++) { if (edf == DE1) m = (15 - i) << 1; else m = i << 1; n = m + 1; kn[m] = kn[n] = 0L; for (j = 0; j < 28; j++) { l = j + totrot[i]; if (l < 28) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l - 28]; } for (j = 28; j < 56; j++) { l = j + totrot[i]; if (l < 56) pcr[j] = pc1m[l]; else pcr[j] = pc1m[l - 28]; } for (j = 0; j < 24; j++) { if (pcr[pc2[j]]) kn[m] |= bigbyte[j]; if (pcr[pc2[j + 24]]) kn[n] |= bigbyte[j]; } } cookey(kn); return; } static void cookey(raw1) register unsigned long *raw1; { register unsigned long *cook, *raw0; unsigned long dough[32]; register int i; cook = dough; for (i = 0; i < 16; i++, raw1++) { raw0 = raw1++; *cook = (*raw0 & 0x00fc0000L) << 6; *cook |= (*raw0 & 0x00000fc0L) << 10; *cook |= (*raw1 & 0x00fc0000L) >> 10; *cook++ |= (*raw1 & 0x00000fc0L) >> 6; *cook = (*raw0 & 0x0003f000L) << 12; *cook |= (*raw0 & 0x0000003fL) << 16; *cook |= (*raw1 & 0x0003f000L) >> 4; *cook++ |= (*raw1 & 0x0000003fL); } usekey(dough); return; } void cpkey(into) register unsigned long *into; { register unsigned long *from, *endp; from = KnL, endp = &KnL[32]; while (from < endp) *into++ = *from++; return; } void usekey(from) register unsigned long *from; { register unsigned long *to, *endp; to = KnL, endp = &KnL[32]; while (to < endp) *to++ = *from++; return; } void des(inblock, outblock) unsigned char *inblock, *outblock; { unsigned long work[2]; scrunch(inblock, work); desfunc(work, KnL); unscrun(work, outblock); return; } static void scrunch(outof, into) register unsigned char *outof; register unsigned long *into; { *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into++ |= (*outof++ & 0xffL); *into = (*outof++ & 0xffL) << 24; *into |= (*outof++ & 0xffL) << 16; *into |= (*outof++ & 0xffL) << 8; *into |= (*outof & 0xffL); return; } static void unscrun(outof, into) register unsigned long *outof; register unsigned char *into; { *into++ = (*outof >> 24) & 0xffL; *into++ = (*outof >> 16) & 0xffL; *into++ = (*outof >> 8) & 0xffL; *into++ = *outof++ & 0xffL; *into++ = (*outof >> 24) & 0xffL; *into++ = (*outof >> 16) & 0xffL; *into++ = (*outof >> 8) & 0xffL; *into = *outof & 0xffL; return; } static unsigned long SP1[64] = { 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; static unsigned long SP2[64] = { 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; static unsigned long SP3[64] = { 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; static unsigned long SP4[64] = { 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; static unsigned long SP5[64] = { 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; static unsigned long SP6[64] = { 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; static unsigned long SP7[64] = { 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; static unsigned long SP8[64] = { 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; static void desfunc(block, keys) register unsigned long *block, *keys; { register unsigned long fval, work, right, leftt; register int round; leftt = block[0]; right = block[1]; work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; right ^= work; leftt ^= (work << 4); work = ((leftt >> 16) ^ right) & 0x0000ffffL; right ^= work; leftt ^= (work << 16); work = ((right >> 2) ^ leftt) & 0x33333333L; leftt ^= work; right ^= (work << 2); work = ((right >> 8) ^ leftt) & 0x00ff00ffL; leftt ^= work; right ^= (work << 8); right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; for (round = 0; round < 8; round++) { work = (right << 28) | (right >> 4); work ^= *keys++; fval = SP7[work & 0x3fL]; fval |= SP5[(work >> 8) & 0x3fL]; fval |= SP3[(work >> 16) & 0x3fL]; fval |= SP1[(work >> 24) & 0x3fL]; work = right ^ *keys++; fval |= SP8[work & 0x3fL]; fval |= SP6[(work >> 8) & 0x3fL]; fval |= SP4[(work >> 16) & 0x3fL]; fval |= SP2[(work >> 24) & 0x3fL]; leftt ^= fval; work = (leftt << 28) | (leftt >> 4); work ^= *keys++; fval = SP7[work & 0x3fL]; fval |= SP5[(work >> 8) & 0x3fL]; fval |= SP3[(work >> 16) & 0x3fL]; fval |= SP1[(work >> 24) & 0x3fL]; work = leftt ^ *keys++; fval |= SP8[work & 0x3fL]; fval |= SP6[(work >> 8) & 0x3fL]; fval |= SP4[(work >> 16) & 0x3fL]; fval |= SP2[(work >> 24) & 0x3fL]; right ^= fval; } right = (right << 31) | (right >> 1); work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = (leftt << 31) | (leftt >> 1); work = ((leftt >> 8) ^ right) & 0x00ff00ffL; right ^= work; leftt ^= (work << 8); work = ((leftt >> 2) ^ right) & 0x33333333L; right ^= work; leftt ^= (work << 2); work = ((right >> 16) ^ leftt) & 0x0000ffffL; leftt ^= work; right ^= (work << 16); work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; leftt ^= work; right ^= (work << 4); *block++ = right; *block = leftt; return; } /* Validation sets: * * Single-length key, single-length plaintext - * Key : 0123 4567 89ab cdef * Plain : 0123 4567 89ab cde7 * Cipher : c957 4425 6a5e d31d * * Double-length key, single-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cde7 * Cipher : 7f1d 0a77 826b 8aff * * Double-length key, double-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 * * Triple-length key, single-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cde7 * Cipher : de0b 7c06 ae5e 0ed5 * * Triple-length key, double-length plaintext - * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 * * d3des V5.0a rwo 9208.07 18:44 Graven Imagery **********************************************************************/ jmk-foofus-medusa-dd62069/src/modsrc/d3des.h000066400000000000000000000031631460263104500206430ustar00rootroot00000000000000 /* * This is D3DES (V5.09) by Richard Outerbridge with the double and * triple-length support removed for use in VNC. * * These changes are: * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. * * This software 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. */ /* d3des.h - * * Headers and defines for d3des.c * Graven Imagery, 1992. * * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge * (GEnie : OUTER; CIS : [71755,204]) */ #define EN0 0 /* MODE == encrypt */ #define DE1 1 /* MODE == decrypt */ extern void deskey(unsigned char *, int); /* hexkey[8] MODE * Sets the internal key register according to the hexadecimal * key contained in the 8 bytes of hexkey, according to the DES, * for encryption or decryption according to MODE. */ extern void usekey(unsigned long *); /* cookedkey[32] * Loads the internal key register with the data in cookedkey. */ extern void cpkey(unsigned long *); /* cookedkey[32] * Copies the contents of the internal key register into the storage * located at &cookedkey[0]. */ extern void des(unsigned char *, unsigned char *); /* from[8] to[8] * Encrypts/Decrypts (according to the key currently loaded in the * internal key register) one block of eight bytes at address 'from' * into the block at address 'to'. They can be the same. */ /* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery ********************************************************************/ jmk-foofus-medusa-dd62069/src/modsrc/ftp.c000066400000000000000000000455551460263104500204400ustar00rootroot00000000000000/* ** FTP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** CHANGE LOG ** 09/2007 - FTPS Support Added by JoMo-Kun ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "ftp.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for FTP/FTPS sessions" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: ftp.c 1876 2014-03-03 22:16:20Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_FTP 21 #define PORT_FTPS 990 #define AUTH_NORMAL 0 #define AUTH_EXPLICIT 1 #define AUTH_IMPLICIT 2 typedef struct __MODULE_DATA { sConnectParams *params; int nAuthType; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initAuthSSL(int hSocket, _MODULE_DATA* _psSessionData); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA* _psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, "MODE:? (NORMAL*, EXPLICIT, IMPLICIT)"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " EXPLICIT: AUTH TLS Mode as defined in RFC 4217"); writeVerbose(VB_NONE, " Explicit FTPS (FTP/SSL) connects to a FTP service in the clear. Prior to"); writeVerbose(VB_NONE, " sending any credentials, however, an \"AUTH TLS\" command is issued and a"); writeVerbose(VB_NONE, " SSL session is negotiated."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " IMPLICIT: FTP over SSL (990/tcp)"); writeVerbose(VB_NONE, " Implicit FTPS requires a SSL handshake to be performed before any FTP"); writeVerbose(VB_NONE, " commands are sent. This service typically resides on tcp/990. If the user"); writeVerbose(VB_NONE, " specifies this option or uses the \"-n\" (SSL) option, the module will"); writeVerbose(VB_NONE, " default to this mode and tcp/990."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " NORMAL"); writeVerbose(VB_NONE, " The default behaviour if no MODE is specified. Authentication is attempted"); writeVerbose(VB_NONE, " in the clear. If the server requests encryption for the given user,"); writeVerbose(VB_NONE, " Explicit FTPS is utilized."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example Usage:"); writeVerbose(VB_NONE, " medusa -M ftp -h host -u username -p password"); writeVerbose(VB_NONE, " medusa -M ftp -s -h host -u username -p password"); writeVerbose(VB_NONE, " medusa -M ftp -m MODE:EXPLICIT -h host -u username -p password"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "(*) Default value"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inAuthType = AUTH_EXPLICIT; else if (strcmp(pOpt, "IMPLICIT") == 0) psSessionData->nAuthType = AUTH_IMPLICIT; else if (strcmp(pOpt, "NORMAL") == 0) psSessionData->nAuthType = AUTH_NORMAL; else writeError(ERR_WARNING, "Invalid value for method MODE."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; unsigned char* bufReceive; int nReceiveBufferSize = 0; sCredentialSet *psCredSet = NULL; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } _psSessionData->params = malloc( sizeof(sConnectParams) ); memset(_psSessionData->params, 0, sizeof(sConnectParams)); if (_psSessionData->nAuthType == AUTH_IMPLICIT) { psLogin->psServer->psHost->iUseSSL = 1; _psSessionData->params->nPort = PORT_FTPS; } else { _psSessionData->params->nPort = PORT_FTP; } if (psLogin->psServer->psAudit->iPortOverride > 0) _psSessionData->params->nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) _psSessionData->params->nPort = PORT_FTPS; initConnectionParams(psLogin, _psSessionData->params); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(_psSessionData->params); else hSocket = medusaConnect(_psSessionData->params); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, _psSessionData->params->nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* establish initial connection */ /* http://www.faqs.org/rfcs/rfc959.html Thus the format for multi-line replies is that the first line will begin with the exact required reply code, followed immediately by a Hyphen, "-" (also known as Minus), followed by text. The last line will begin with the same code, followed immediately by Space , optionally some text, and the Telnet end-of-line code. */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving FTP banner.", MODULE_NAME); bufReceive = NULL; nReceiveBufferSize = 0; /* Grab entire banner and verify format */ if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server sent unknown response. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } if (strncmp((char*)bufReceive, "220", 3) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Server sent 220 response.", MODULE_NAME); FREE(bufReceive); } else if (strncmp((char*)bufReceive, "421", 3) == 0) { writeError(ERR_ERROR, "[%s] Server sent 421 response (too many connections).", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "[%s] Server sent unknown response code: %c%c%c", MODULE_NAME, bufReceive[0], bufReceive[1], bufReceive[2]); FREE(bufReceive); return FAILURE; } /* Establish Explicit FTPS mode authentication if requested */ if (_psSessionData->nAuthType == AUTH_EXPLICIT) { if (initAuthSSL(hSocket, _psSessionData) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; } } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: /* The FTP service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. At that point the connection should be reestablished. */ if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initAuthSSL(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive = NULL; int nReceiveBufferSize; writeError(ERR_NOTICE, "[%s] Establishing Explicit FTPS (FTP/SSL) session.", MODULE_NAME); memset(bufSend, 0, BUF_SIZE); sprintf((char*)bufSend, "AUTH TLS\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server sent unknown or no response. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* 234 Proceed with negotiation. */ if (strncmp((char*)bufReceive, "234 ", 4) == 0) { FREE(bufReceive); if (medusaConnectSocketSSL(_psSessionData->params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSL connection.", MODULE_NAME); return FAILURE; } } else { writeError(ERR_ERROR, "[%s] Failed to establish SSL connection. Server sent response: %c%c%c", MODULE_NAME, bufReceive[0], bufReceive[1], bufReceive[2]); return FAILURE; } return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; /* send username */ memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server sent unknown or no response. Server may have dropped connection due to lack of encryption or due to anti-bruteforce measures. Enabling EXPLICIT mode may help with the former cause and increasing the socket check delay (e.g. -c 1000) may help with the later.", MODULE_NAME); return FAILURE; } /* FTP service may be configured to require protected authentication for specific users */ if ( (strstr((char*)bufReceive, "530 Non-anonymous sessions must use encryption.") != NULL) || (strstr((char*)bufReceive, "331 Non-anonymous sessions must use encryption.") != NULL) || (strstr((char*)bufReceive, "331 Rejected--secure connection required") != NULL) ) { writeError(ERR_NOTICE, "[%s] FTP server (%s) appears to require SSL for specified user.", MODULE_NAME, (*psLogin)->psServer->pHostIP); FREE(bufReceive); if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) ) { writeError(ERR_DEBUG_MODULE, "[%s] Checking socket status: OK", MODULE_NAME); if (initAuthSSL(hSocket, _psSessionData) == FAILURE) return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "[%s] Checking socket status: FAIL - restart connection", MODULE_NAME); _psSessionData->nAuthType = AUTH_EXPLICIT; return MSTATE_NEW; } /* re-send username */ memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server sent unknown or no response. Exiting...", MODULE_NAME); return FAILURE; } } /* Standard FTP [PR85] specifies a 530 response to the USER command when the username is rejected. "Not logged in." */ if (strncmp((char*)bufReceive, "530 ", 4) == 0) { writeError(ERR_ERROR, "[%s] Server sent 530 response (rejected username).", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* 421 There are too many connections from your internet address. */ else if (strncmp((char*)bufReceive, "421 ", 4) == 0) { writeError(ERR_ERROR, "[%s] Server sent 421 response (too many connections).", MODULE_NAME); FREE(bufReceive); return MSTATE_EXITING; } /* Expect: "331 Please specify the password." */ else if (strncmp((char*)bufReceive, "331 ", 4) != 0) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with a '331'.", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* send password */ memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "PASS %.250s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}-.*\r\n[0-9]{3,3} .*\r\n|^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } if (bufReceive[0] == '2') { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; /* Restarting session for now as it's currently faster when dealing with anti-bruteforce services */ iRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/hmacmd5.c000066400000000000000000000050501460263104500211470ustar00rootroot00000000000000/* ** ------------------------------------------------------------------------ ** Copyright (C) 2024 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** ** Based on: https://wiki.openssl.org/index.php/EVP_Signing_and_Verifying ** */ #include #include #include "module.h" int hmac_md5(const unsigned char *msg, size_t mlen, unsigned char **val, size_t *vlen, unsigned char *key, size_t key_len) { int result = 0; EVP_MD_CTX* ctx = NULL; size_t req = 0; int rc; EVP_PKEY *pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, key, key_len); if(!msg || !mlen || !val || !pkey) return 0; *val = NULL; *vlen = 0; ctx = EVP_MD_CTX_new(); if (ctx == NULL) { writeError(ERR_ERROR, "[HMAC-MD5] EVP_MD_CTX_create failed, error 0x%lx", ERR_get_error()); goto err; } rc = EVP_DigestSignInit(ctx, NULL, EVP_md5(), NULL, pkey); if (rc != 1) { writeError(ERR_ERROR, "[HMAC-MD5] EVP_DigestSignInit failed, error 0x%lx", ERR_get_error()); goto err; } rc = EVP_DigestSignUpdate(ctx, msg, mlen); if (rc != 1) { writeError(ERR_ERROR, "[HMAC-MD5] EVP_DigestSignUpdate failed, error 0x%lx", ERR_get_error()); goto err; } rc = EVP_DigestSignFinal(ctx, NULL, &req); if (rc != 1) { writeError(ERR_ERROR, "[HMAC-MD5] EVP_DigestSignFinal failed (1), error 0x%lx", ERR_get_error()); goto err; } *val = OPENSSL_malloc(req); if (*val == NULL) { writeError(ERR_ERROR, "[HMAC-MD5] OPENSSL_malloc failed, error 0x%lx", ERR_get_error()); goto err; } *vlen = req; rc = EVP_DigestSignFinal(ctx, *val, vlen); if (rc != 1) { writeError(ERR_ERROR, "[HMAC-MD5] EVP_DigestSignFinal failed (3), return code %d, error 0x%lx", ERR_get_error()); goto err; } result = 1; err: EVP_MD_CTX_free(ctx); if (!result) { OPENSSL_free(*val); *val = NULL; } return result; } jmk-foofus-medusa-dd62069/src/modsrc/hmacmd5.h000066400000000000000000000020431460263104500211530ustar00rootroot00000000000000/* ** ------------------------------------------------------------------------ ** Copyright (C) 2024 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ */ #ifndef _HMAC_MD5_H int hmac_md5(const unsigned char *msg, size_t mlen, unsigned char **val, size_t *vlen, unsigned char *key, size_t key_len); #endif /* _HMAC_MD5_H */ jmk-foofus-medusa-dd62069/src/modsrc/http-digest.c000066400000000000000000000120271460263104500220670ustar00rootroot00000000000000/* TAKEN from rcf2617.txt */ /* Modified calculation of HA1 for MD5-sess. The sample code does not convert the result of MD5(username:realm:password) to HEX prior to the final stage of the HA1 calculation. Not sure if this due to using a different md5.h/.c file set than the original version or if it is indeed a bug in the RFC sample code. */ /* #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Werror" #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Wall" */ #include #include "http-digest.h" void CvtHex( IN HASH Bin, OUT HASHHEX Hex ) { unsigned short i; unsigned char j; for (i = 0; i < HASHLEN; i++) { j = (Bin[i] >> 4) & 0xf; if (j <= 9) Hex[i*2] = (j + '0'); else Hex[i*2] = (j + 'a' - 10); j = Bin[i] & 0xf; if (j <= 9) Hex[i*2+1] = (j + '0'); else Hex[i*2+1] = (j + 'a' - 10); }; Hex[HASHHEXLEN] = '\0'; }; /* calculate H(A1) as per spec */ void DigestCalcHA1( IN char * pszAlg, IN char * pszUserName, IN char * pszRealm, IN char * pszPassword, IN char * pszNonce, IN char * pszCNonce, OUT HASHHEX SessionKey ) { EVP_MD_CTX *Md5Ctx; unsigned char *md5_digest; unsigned int md5_digest_len = HASHLEN; /* MD5_Init */ Md5Ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(Md5Ctx, EVP_md5(), NULL); /* MD5_Update */ EVP_DigestUpdate(Md5Ctx, pszUserName, strlen(pszUserName)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszRealm, strlen(pszRealm)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszPassword, strlen(pszPassword)); /* MD5_Final */ md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len); EVP_DigestFinal_ex(Md5Ctx, md5_digest, &md5_digest_len); EVP_MD_CTX_free(Md5Ctx); if (strcasecmp(pszAlg, "md5-sess") == 0) { CvtHex(md5_digest, SessionKey); /* MD5_Init */ Md5Ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(Md5Ctx, EVP_md5(), NULL); /* MD5_Update */ EVP_DigestUpdate(Md5Ctx, SessionKey, strlen(SessionKey)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszNonce, strlen(pszNonce)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszCNonce, strlen(pszCNonce)); /* MD5_Final */ md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len); EVP_DigestFinal_ex(Md5Ctx, md5_digest, &md5_digest_len); EVP_MD_CTX_free(Md5Ctx); }; CvtHex(md5_digest, SessionKey); }; /* calculate request-digest/response-digest as per HTTP Digest spec */ void DigestCalcResponse( IN HASHHEX HA1, /* H(A1) */ IN char * pszNonce, /* nonce from server */ IN char * pszNonceCount, /* 8 hex digits */ IN char * pszCNonce, /* client nonce */ IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ IN char * pszMethod, /* method from the request */ IN char * pszDigestUri, /* requested URL */ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ OUT HASHHEX Response /* request-digest or response-digest */ ) { HASHHEX HA2Hex; EVP_MD_CTX *Md5Ctx; unsigned char *md5_digest; unsigned int md5_digest_len = HASHLEN; /* MD5_Init */ Md5Ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(Md5Ctx, EVP_md5(), NULL); /* MD5_Update */ EVP_DigestUpdate(Md5Ctx, pszMethod, strlen(pszMethod)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszDigestUri, strlen(pszDigestUri)); if (strcasecmp(pszQop, "auth-int") == 0) { EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, HEntity, HASHHEXLEN); }; /* MD5_Final */ md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len); EVP_DigestFinal_ex(Md5Ctx, md5_digest, &md5_digest_len); CvtHex(md5_digest, HA2Hex); // calculate response /* MD5_Init */ Md5Ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(Md5Ctx, EVP_md5(), NULL); /* MD5_Update */ EVP_DigestUpdate(Md5Ctx, HA1, HASHHEXLEN); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszNonce, strlen(pszNonce)); EVP_DigestUpdate(Md5Ctx, ":", 1); if (*pszQop) { EVP_DigestUpdate(Md5Ctx, pszNonceCount, strlen(pszNonceCount)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszCNonce, strlen(pszCNonce)); EVP_DigestUpdate(Md5Ctx, ":", 1); EVP_DigestUpdate(Md5Ctx, pszQop, strlen(pszQop)); EVP_DigestUpdate(Md5Ctx, ":", 1); }; EVP_DigestUpdate(Md5Ctx, HA2Hex, HASHHEXLEN); /* MD5_Final */ md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len); EVP_DigestFinal_ex(Md5Ctx, md5_digest, &md5_digest_len); CvtHex(md5_digest, Response); }; /* #pragma GCC diagnostic pop #pragma GCC diagnostic pop */ jmk-foofus-medusa-dd62069/src/modsrc/http-digest.h000066400000000000000000000021461460263104500220750ustar00rootroot00000000000000/* TAKEN from rcf2617.txt */ #ifndef _HTTP_DIGEST_H_ #define _HTTP_DIGEST_H_ #include #define HASHLEN 16 typedef unsigned char HASH[HASHLEN]; #define HASHHEXLEN 32 typedef unsigned char HASHHEX[HASHHEXLEN+1]; #define IN #define OUT /* calculate H(A1) as per HTTP Digest spec */ void DigestCalcHA1( IN char * pszAlg, IN char * pszUserName, IN char * pszRealm, IN char * pszPassword, IN char * pszNonce, IN char * pszCNonce, OUT HASHHEX SessionKey ); /* calculate request-digest/response-digest as per HTTP Digest spec */ void DigestCalcResponse( IN HASHHEX HA1, /* H(A1) */ IN char * pszNonce, /* nonce from server */ IN char * pszNonceCount, /* 8 hex digits */ IN char * pszCNonce, /* client nonce */ IN char * pszQop, /* qop-value: "", "auth", "auth-int" */ IN char * pszMethod, /* method from the request */ IN char * pszDigestUri, /* requested URL */ IN HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ OUT HASHHEX Response /* request-digest or response-digest */ ); #endif jmk-foofus-medusa-dd62069/src/modsrc/http.c000066400000000000000000001152521460263104500206160ustar00rootroot00000000000000/*************************************************************************** * http.c * * Copyright (C) 2009 by fizzgig * * fizzgig@foofus.net * * * * Implementation of a HTTP brute force module for Medusa. * * * * CHANGE LOG * * 04/15/2005 - Created by fizzgig (fizzgig@foofus.net) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * * Modifications: (JoMo-Kun) * * Support for user specified URL/User-Agent * * Replaced Base64 function from Hydra with Wget version * * Hydra Base64 appears partially broken... * * Added NTLM authentication using code from Wget * * Wget can be found here: http://wget.sunsite.dk/ * * * ***************************************************************************/ #include "module.h" #define MODULE_NAME "http.mod" #define MODULE_AUTHOR "fizzgig " #define MODULE_SUMMARY_USAGE "Brute force module for HTTP" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: http.c 9260 2015-05-27 21:52:57Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include "ntlm.h" #include "http-digest.h" #define PORT_HTTP 80 #define PORT_HTTPS 443 #define AUTH_UNKNOWN 0 #define AUTH_NONE 1 #define AUTH_BASIC 2 #define AUTH_NTLM 3 #define AUTH_DIGEST 4 typedef struct __MODULE_DATA { char *szDomain; char *szDir; char *szMethod; char *szHostHeader; char *szUserAgent; char *szCustomHeader; int nAuthType; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum HTTP_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int getAuthType(int hSocket, _MODULE_DATA* _psSessionData); int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " USER-AGENT:? (User-Agent. Default: Mozilla/1.22 (compatible; MSIE 10.0; Windows 3.1))"); writeVerbose(VB_NONE, " DIR:? (Target directory. Default \"/\")"); writeVerbose(VB_NONE, " METHOD:? (Method (GET/POST/etc). Default: GET"); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (BASIC/DIGEST/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, " CUSTOM-HEADER:? Additional HTTP header."); writeVerbose(VB_NONE, " More headers can be defined by using this option several times."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M http -m USER-AGENT:\"g3rg3 gerg\" -m DIR:exchange/\""); writeVerbose(VB_NONE, "Usage example: \"-M http -m CUSTOM-HEADER:\"Cookie: SMCHALLENGE=YES\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Note: The default behavior of NTLM authentication is to use the server supplied"); writeVerbose(VB_NONE, "domain name. In order to target local accounts, and not domain, use the DOMAIN"); writeVerbose(VB_NONE, "option to reference the local system: \"-m DOMAIN:127.0.0.1\"."); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; int nCustomHeadersSize = 0; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 4)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDir = strdup(pOpt); } else writeError(ERR_WARNING, "Method DIR requires value to be set."); } else if (strcmp(pOpt, "METHOD") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szMethod = strdup(pOpt); } else writeError(ERR_WARNING, "Method METHOD requires value to be set."); } else if (strcmp(pOpt, "USER-AGENT") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szUserAgent = strdup(pOpt); } else writeError(ERR_WARNING, "Method USER-AGENT requires value to be set."); } else if (strcmp(pOpt, "CUSTOM-HEADER") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { if ( nCustomHeadersSize == 0 ) psSessionData->szCustomHeader = malloc(strlen(pOpt) + 3); else psSessionData->szCustomHeader = realloc(psSessionData->szCustomHeader, nCustomHeadersSize + strlen(pOpt) + 3); memset(psSessionData->szCustomHeader + nCustomHeadersSize, 0, strlen(pOpt) + 3); strcpy(psSessionData->szCustomHeader + nCustomHeadersSize, pOpt); strcpy(psSessionData->szCustomHeader + nCustomHeadersSize + strlen(pOpt), "\r\n"); nCustomHeadersSize = strlen(psSessionData->szCustomHeader); } else writeError(ERR_WARNING, "Method CUSTOM-HEADER requires value to be set."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "BASIC") == 0) psSessionData->nAuthType = AUTH_BASIC; else if (strcmp(pOpt, "DIGEST") == 0) psSessionData->nAuthType = AUTH_DIGEST; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = strdup(pOpt); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } FREE(pOptTmp); } initModule(psSessionData, logins); } FREE(psSessionData->szDir); FREE(psSessionData->szMethod); FREE(psSessionData->szUserAgent); FREE(psSessionData->szDomain); FREE(psSessionData->szCustomHeader); FREE(psSessionData); return SUCCESS; } int initModule(_MODULE_DATA *_psSessionData, sLogin* _psLogin) { int hSocket = -1; enum HTTP_STATE nState = MSTATE_NEW; int nBufLength = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, _psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME, _psLogin->psServer->pHostIP); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else if (_psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_HTTPS; else params.nPort = PORT_HTTP; initConnectionParams(_psLogin, ¶ms); /* Set request parameters */ if (!_psSessionData->szDir) { _psSessionData->szDir = malloc(1); memset(_psSessionData->szDir, 0, 1); } if (!_psSessionData->szMethod) { _psSessionData->szMethod = malloc(15); memset(_psSessionData->szMethod, 0, 15); sprintf(_psSessionData->szMethod, "GET"); } if (!_psSessionData->szHostHeader) { nBufLength = strlen(_psLogin->psServer->psHost->pHost) + 1 + log(params.nPort) + 1; _psSessionData->szHostHeader = malloc(nBufLength + 1); memset(_psSessionData->szHostHeader, 0, nBufLength + 1); sprintf(_psSessionData->szHostHeader, "%s:%d", _psLogin->psServer->psHost->pHost, params.nPort); } if (!_psSessionData->szUserAgent) { _psSessionData->szUserAgent = malloc(50); memset(_psSessionData->szUserAgent, 0, 50); sprintf(_psSessionData->szUserAgent, "Mozilla/1.22 (compatible; MSIE 10.0; Windows 3.1)"); } if (!_psSessionData->szCustomHeader) { _psSessionData->szCustomHeader = malloc(1); memset(_psSessionData->szCustomHeader, 0, 1); } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (_psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* Get required authorization method */ if (_psSessionData->nAuthType == AUTH_UNKNOWN) { if ((getAuthType(hSocket, _psSessionData) == FAILURE) || (_psSessionData->nAuthType == AUTH_UNKNOWN)) { _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } nState = MSTATE_NEW; } else nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, _psSessionData, &_psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (_psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown HTTP module state (%d). Exiting...", nState); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; break; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int getAuthType(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; nSendBufferSize = strlen(_psSessionData->szMethod) + 2 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 2 + strlen(_psSessionData->szCustomHeader) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n%s\r\n", _psSessionData->szMethod, _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial non-authentication request: %s", MODULE_NAME, bufSend); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "HTTP/1.* .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive); return FAILURE; } writeError(ERR_DEBUG_MODULE, "[%s] Parsing authentication header: %s", MODULE_NAME, bufReceive); if ((strcasestr((char*)bufReceive, "WWW-Authenticate: Basic")) || (strcasestr((char*)bufReceive, "WWW-Authenticate:Basic"))) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested basic authentication.", MODULE_NAME); _psSessionData->nAuthType = AUTH_BASIC; } else if ((strcasestr((char*)bufReceive, "WWW-Authenticate: NTLM")) || (strcasestr((char*)bufReceive, "WWW-Authenticate:NTLM"))) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested integrated windows authentication.", MODULE_NAME); _psSessionData->nAuthType = AUTH_NTLM; } else if ((strcasestr((char*)bufReceive, "WWW-Authenticate: Digest")) || strcasestr((char*)bufReceive, "WWW-Authenticate:Digest")) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested digest authentication.", MODULE_NAME); _psSessionData->nAuthType = AUTH_DIGEST; } else if (strcasestr((char*)bufReceive, "WWW-Authenticate:")) { writeError(ERR_ERROR, "[%s] Server requested unknown authentication type.", MODULE_NAME); _psSessionData->nAuthType = AUTH_UNKNOWN; } else { writeError(ERR_DEBUG_MODULE, "[%s] No authentication header located.", MODULE_NAME); _psSessionData->nAuthType = AUTH_NONE; } FREE(bufReceive); return(SUCCESS); } int sendAuthBasic(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; char* szEncodedAuth = NULL; char* szLoginDomain = NULL; int nSendBufferSize = 0; int nRet = SUCCESS; if (_psSessionData->szDomain) { /* DOMAIN\USERNAME */ szLoginDomain = malloc(strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); memset(szLoginDomain, 0, strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); sprintf(szLoginDomain, "%s\\%s", _psSessionData->szDomain, szLogin); } else szLoginDomain = szLogin; writeError(ERR_DEBUG_MODULE, "[%s] Base64 encoding: %s:%s", MODULE_NAME, szLoginDomain, szPassword); szEncodedAuth = basic_authentication_encode(szLoginDomain, szPassword); writeError(ERR_DEBUG_MODULE, "[%s] Base64 encoded data is: %s", MODULE_NAME, szEncodedAuth); if (_psSessionData->szDomain) FREE(szLoginDomain); nSendBufferSize = strlen(_psSessionData->szMethod) + 2 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 23 + strlen(szEncodedAuth) + 2 + strlen(_psSessionData->szCustomHeader) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: Basic %s\r\n%s\r\n", _psSessionData->szMethod, _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szEncodedAuth, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } FREE(szEncodedAuth); FREE(bufSend); return nRet; } int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; char *szTmpBuf = NULL; char *szTmpBuf64 = NULL; /* --- Send Type-1 NTLM request --- */ /* Enable NTLM2 Session Response */ buildAuthRequest(&sTmpReq, 0x0008b207, NULL, NULL); //buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(_psSessionData->szMethod) + 2 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 22 + strlen(szTmpBuf64) + 26 + strlen(_psSessionData->szCustomHeader) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: NTLM %s\r\nConnection: keep-alive\r\n%s\r\n", _psSessionData->szMethod, _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szTmpBuf64, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); /* --- Retrieve NTLM challenge from server --- */ if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "HTTP/1.* .*WWW-Authenticate.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive); return FAILURE; } if (bufReceive[0] == '\0') { writeError(ERR_ERROR, "[%s] Service did not respond to our authentication request.", MODULE_NAME); return FAILURE; } /* --- Extract NTLM challenge from Type-2 NTLM response --- */ szTmpBuf64 = strcasestr((char*)bufReceive, "WWW-Authenticate: NTLM "); if (szTmpBuf64 == NULL) { writeError(ERR_ERROR, "[%s] Failed to locate NTLM challenge within server response.", MODULE_NAME); return FAILURE; } szTmpBuf = index(szTmpBuf64, '\r'); if (szTmpBuf) szTmpBuf[0] = '\0'; else writeError(ERR_ERROR, "[%s] Failed to identify complete NTLM challenge.", MODULE_NAME); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64 + 23); base64_decode(szTmpBuf64 + 23, (char *)&sTmpChall); FREE(bufReceive); /* --- Send Type-3 NTLM reply --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(_psSessionData->szMethod) + 2 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 22 + strlen(szTmpBuf64) + 21 + strlen(_psSessionData->szCustomHeader) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: NTLM %s\r\nConnection: close\r\n%s\r\n", _psSessionData->szMethod, _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szTmpBuf64, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); return SUCCESS; } /* http://www.ietf.org/rfc/rfc2617.txt */ int sendAuthDigest(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; char *szTmp = NULL; char *szTmp1 = NULL; char *szAuthenticate = NULL; char *szAuthorization = NULL; char *szNonce = NULL; char *szCNonce = "31337"; char *szRealm = NULL; char *szAlg = NULL; char szNonceCount[9] = "00000001"; char *szQop = NULL; char *szURI = NULL; char *szOpaque = NULL; HASHHEX HA1; HASHHEX HA2 = ""; HASHHEX Response; /* URI should start with a "/" */ if (strncmp(_psSessionData->szDir, "/", 1) == 0) { szURI = strdup(_psSessionData->szDir); } else { szURI = malloc(1 + strlen(_psSessionData->szDir) + 1); memset(szURI, 0, 1 + strlen(_psSessionData->szDir) + 1); strcpy(szURI, "/"); strcat(szURI, _psSessionData->szDir); } /* Send initial request */ writeError(ERR_DEBUG_MODULE, "[%s] Sending initial request for digest authentication.", MODULE_NAME); nSendBufferSize = strlen(_psSessionData->szMethod) + 2 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 26 + strlen(_psSessionData->szCustomHeader) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nConnection: keep-alive\r\n%s\r\n", _psSessionData->szMethod, _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Retrieve digest challenge from server */ bufReceive = medusaReceiveLine(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] No data received", MODULE_NAME); return FAILURE; } if (bufReceive[0] == '\0') { writeError(ERR_ERROR, "[%s] Failed to locate digest challenge.", MODULE_NAME); return FAILURE; } /* Parse WWW-Authenticate Digest Response */ /* Example: WWW-Authenticate: Digest realm="Inter-Tel 5000 (00103605AB8A)", nonce="86591bebf1330b5e57b8de2e4ac216b2", qop="auth" */ if ( (szTmp = strcasestr((char*)bufReceive, "WWW-Authenticate: Digest ")) != NULL ) { szTmp += 18; } else if ( (szTmp = strcasestr((char*)bufReceive, "WWW-Authenticate:Digest ")) != NULL ) { szTmp += 17; } else { writeError(ERR_ERROR, "[%s] Failed to locate digest challenge.", MODULE_NAME); return FAILURE; } szTmp1 = index(szTmp, '\r'); szAuthenticate = malloc(szTmp1 - szTmp + 1); memset(szAuthenticate, 0, szTmp1 - szTmp + 1); strncpy(szAuthenticate, szTmp, szTmp1 - szTmp); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Server WWW-Authenticate Digest Response: %s", MODULE_NAME, szAuthenticate); /* Extract Digest Algorithm, if Specified */ /* We currently only support MD5 and MD5-Sess (session) - Do others exist? */ if ( strcasestr(szAuthenticate, "algorithm=MD5-sess") || strcasestr(szAuthenticate, "algorithm=\"MD5-sess\"") ) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested Digest MD5-sess algorithm.", MODULE_NAME); szAlg = malloc(9); memset(szAlg, 0, 9); sprintf(szAlg, "MD5-sess"); } else if ( strcasestr(szAuthenticate, "algorithm=MD5") || strcasestr(szAuthenticate, "algorithm=\"MD5\"") ) { writeError(ERR_DEBUG_MODULE, "[%s] Server requested Digest MD5 algorithm.", MODULE_NAME); szAlg = malloc(4); memset(szAlg, 0, 4); sprintf(szAlg, "MD5"); } else if ( strcasestr(szAuthenticate, "algorithm=") ) { writeError(ERR_ERROR, "[%s] Server requested unknown Digest algorithm.", MODULE_NAME); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "[%s] Server did not specify a Digest algorithm, so we're assuming MD5.", MODULE_NAME); szAlg = malloc(4); memset(szAlg, 0, 4); sprintf(szAlg, "MD5"); } /* Extract Digest Realm */ szTmp = strcasestr(szAuthenticate, "realm=\""); if (szTmp) { szTmp += 7; szTmp1 = ((char*)index(szTmp, '"')); szRealm = malloc (szTmp1 - szTmp + 1); memset(szRealm, 0, szTmp1 - szTmp + 1); strncpy(szRealm, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Realm Response: %s", MODULE_NAME, szRealm); } else { writeError(ERR_ERROR, "[%s] Failed to extract server Realm response.", MODULE_NAME); szRealm = malloc(1); memset(szRealm, 0, 1); } /* Extract Digest Server Nonce */ szTmp = strcasestr(szAuthenticate, "nonce=\""); if (szTmp) { szTmp += 7; szTmp1 = index(szTmp, '"'); szNonce = malloc (szTmp1 - szTmp + 1); memset(szNonce, 0, szTmp1 - szTmp + 1); strncpy(szNonce, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Nonce Response: %s", MODULE_NAME, szNonce); } else { writeError(ERR_ERROR, "[%s] Failed to extract server Nonce response.", MODULE_NAME); szNonce = malloc(1); memset(szNonce, 0, 1); } /* Extract Digest Quality of Protection (QoP) - If Specified */ szTmp = strcasestr(szAuthenticate, "qop=\""); if (szTmp) { szTmp += 5; szTmp1 = index(szTmp, '"'); szQop = malloc (szTmp1 - szTmp + 1); memset(szQop, 0, szTmp1 - szTmp + 1); strncpy(szQop, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Quality of Protection (QoP) Response: %s", MODULE_NAME, szQop); } else { writeError(ERR_DEBUG_MODULE, "[%s] Failed to extract server Quality of Protection (QoP) response.", MODULE_NAME); szQop = NULL; } /* Extract Digest Opaque Value - If Specified */ szTmp = strcasestr(szAuthenticate, "opaque=\""); if (szTmp) { szTmp += 8; szTmp1 = index(szTmp, '"'); szOpaque = malloc(szTmp1 - szTmp + 1); memset(szOpaque, 0, szTmp1 - szTmp + 1); strncpy(szOpaque, szTmp, szTmp1 - szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Extracted Server Opaque Value: %s", MODULE_NAME, szOpaque); } else { writeError(ERR_DEBUG_MODULE, "[%s] Failed to extract server Opaque value.", MODULE_NAME); szOpaque = NULL; } FREE(szAuthenticate); /* Send digest response */ /* Example: Authorization: Digest username="it5k", realm="Inter-Tel 5000 (00103605AB8A)", nonce="94144a2abae7411d0f6af2b533425497", uri="/", response="b9c3980ae4e7fb69796772a3bacc5c18"\r\n */ writeError(ERR_DEBUG_MODULE, "[%s] szAlg: %s", MODULE_NAME, szAlg); writeError(ERR_DEBUG_MODULE, "[%s] szLogin: %s", MODULE_NAME, szLogin); writeError(ERR_DEBUG_MODULE, "[%s] szRealm: %s", MODULE_NAME, szRealm); writeError(ERR_DEBUG_MODULE, "[%s] szPassword: %s", MODULE_NAME, szPassword); writeError(ERR_DEBUG_MODULE, "[%s] szNonce: %s", MODULE_NAME, szNonce); writeError(ERR_DEBUG_MODULE, "[%s] szCNonce: %s", MODULE_NAME, szCNonce); writeError(ERR_DEBUG_MODULE, "[%s] szNonceCount: %s", MODULE_NAME, szNonceCount); writeError(ERR_DEBUG_MODULE, "[%s] szQop: %s", MODULE_NAME, szQop); writeError(ERR_DEBUG_MODULE, "[%s] szOpaque: %s", MODULE_NAME, szOpaque); writeError(ERR_DEBUG_MODULE, "[%s] szMethod: %s", MODULE_NAME, _psSessionData->szMethod); writeError(ERR_DEBUG_MODULE, "[%s] szURI: %s", MODULE_NAME, szURI); DigestCalcHA1(szAlg, szLogin, szRealm, szPassword, szNonce, szCNonce, HA1); DigestCalcResponse(HA1, szNonce, szNonceCount, szCNonce, szQop, _psSessionData->szMethod, szURI, HA2, Response); writeError(ERR_DEBUG_MODULE, "[%s] Calculated Digest Response: %s", MODULE_NAME, Response); /* BASE: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=\"%s\", response=\"%s\" QOP: , qop=%s, nc=%s, cnonce=\"%s\" OPAQUE: , opaque=\"%s\" */ nSendBufferSize = 17 + strlen(szLogin) + 10 + strlen(szRealm) + 10 + strlen(szNonce) + 8 + strlen(szURI) + 14 + strlen(szAlg) + 13 + strlen((char*)Response); /* If the server specified a QoP, the client must use a cnonce */ if ( strcasestr(szQop, "auth-int") ) { writeError(ERR_ERROR, "[%s] Integrity protection (i.e. qop: auth-int) is currently not supported.", MODULE_NAME); return FAILURE; } else if ( strcasestr(szQop, "auth") ) { nSendBufferSize += 7 + strlen(szQop) + 5 + strlen(szNonceCount) + 10 + strlen(szCNonce) + 1; } /* If the server specified an opaque value, that same value should be included in our response. */ if ( szOpaque ) { nSendBufferSize += 10 + strlen(szOpaque) + 1; } szAuthorization = malloc(nSendBufferSize + 1); memset(szAuthorization, 0, nSendBufferSize + 1); if ( (szQop != NULL) && (szOpaque != NULL) ) sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\", qop=%s, nc=00000001, cnonce=\"%s\", opaque=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response, szQop, szCNonce, szOpaque); else if (szQop != NULL) sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\", qop=%s, nc=00000001, cnonce=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response, szQop, szCNonce); else if (szOpaque != NULL) sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\", opaque=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response, szOpaque); else sprintf(szAuthorization, "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", algorithm=%s, response=\"%s\"", szLogin, szRealm, szNonce, szURI, szAlg, Response); FREE(szAlg); FREE(szRealm); FREE(szNonce); FREE(szQop); FREE(szOpaque); FREE(szURI); nSendBufferSize = strlen(_psSessionData->szMethod) + 2 + strlen(_psSessionData->szDir) + 17 + strlen(_psSessionData->szHostHeader) + 14 + strlen(_psSessionData->szUserAgent) + 17 + strlen(szAuthorization) + 26 + strlen(_psSessionData->szCustomHeader) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\nAuthorization: %s\r\nConnection: keep-alive\r\n%s\r\n", _psSessionData->szMethod, _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, szAuthorization, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szAuthorization); FREE(bufSend); return SUCCESS; } int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword) { unsigned char* pReceiveBuffer = NULL; int nReceiveBufferSize = 0; int nRet = SUCCESS; char* pTemp = NULL; char szStatusCode[4]; switch(_psSessionData->nAuthType) { case AUTH_NONE: writeError(ERR_DEBUG_MODULE, "[%s] No authentication required.", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); return MSTATE_NEW; break; case AUTH_BASIC: writeError(ERR_DEBUG_MODULE, "[%s] Sending Basic Authentication.", MODULE_NAME); nRet = sendAuthBasic(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending Windows Integrated (NTLM) Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_DIGEST: writeError(ERR_DEBUG_MODULE, "[%s] Sending Digest Authentication.", MODULE_NAME); nRet = sendAuthDigest(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &pReceiveBuffer, &nReceiveBufferSize, "HTTP/1.* [0-9]{3,3} .*\r\n") == FAILURE) || (pReceiveBuffer == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, pReceiveBuffer); return FAILURE; } pTemp = strstr((char*)pReceiveBuffer, "HTTP/1."); pTemp = index(pTemp, ' ') + 1; memset((char*)index(pTemp, 0x0d), 0, 1); memset(szStatusCode, 0, 4); strncpy(szStatusCode, pTemp, 3); switch (atoi(szStatusCode)) { case 200: writeError(ERR_DEBUG_MODULE, "[%s] 200 OK", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 301: writeError(ERR_DEBUG_MODULE, "[%s] 301 Moved Permanently", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 302: writeError(ERR_DEBUG_MODULE, "[%s] 302 Found", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 401: writeError(ERR_DEBUG_MODULE, "[%s] 401 Unauthorized", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; break; case 403: writeError(ERR_DEBUG_MODULE, "[%s] 403 Forbidden", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; case 404: writeError(ERR_DEBUG_MODULE, "[%s] 404 Not Found", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_NEW; break; default: writeError(ERR_ERROR, "Unexpected return code for %s:%s (%s)", szLogin, szPassword, pTemp); (*login)->pErrorMsg = malloc( 24 + strlen(pTemp) + 1 ); memset((*login)->pErrorMsg, 0, 24 + strlen(pTemp) + 1 ); sprintf((*login)->pErrorMsg, "Unexpected return code: %s", pTemp); (*login)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; break; } FREE(pReceiveBuffer); setPassResult(*login, szPassword); return nRet; } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/imap.c000066400000000000000000000722231460263104500205650ustar00rootroot00000000000000/* ** IMAP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2006 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Helpful item besides reading lots of RFC's ** http://www.kolab.org/pipermail/kolab-commits/2005q1/001959.html ** ** Modifications: (JoMo-Kun) ** Support for LOGIN command ** Optional module parameters ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "imap.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for IMAP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: imap.c 1878 2014-03-04 00:13:42Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_IMAP 143 #define PORT_IMAPS 993 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define AUTH_UNKNOWN 0 #define AUTH_LOGIN 1 #define AUTH_PLAIN 2 #define AUTH_NTLM 3 typedef struct __MODULE_DATA { char *szTag; int nAuthType; char* szDomain; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params); int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " TAG:? (Default: gerg)"); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (LOGIN/PLAIN/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M imap -m TAG:A0001 -m AUTH:PLAIN"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "The DOMAIN option should supply the specified domain appropriately,"); writeVerbose(VB_NONE, "regardless of authentication type. The domain can also be supplied "); writeVerbose(VB_NONE, "via the username field, but the format appears to differ by auth type."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example 1: NTLM authentication with DOMAIN option"); writeVerbose(VB_NONE, " \"medusa -M imap -m AUTH:NTLM -m DOMAIN:FOODOM -h host -u foo -p bar\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example 2: NTLM authentication with domain via username"); writeVerbose(VB_NONE, " \"medusa -M imap -m AUTH:NTLM -h host -u foo@domain -p bar\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "* If no domain is specified when using NTLM authentication, the server"); writeVerbose(VB_NONE, "supplied value will be used."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Example 3: LOGIN authentication with domain via username"); writeVerbose(VB_NONE, " \"medusa -M imap -m AUTH:LOGIN -h host -u 'domain\\\\foo' -p bar\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 3)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszTag = strdup(pOpt); } else writeError(ERR_WARNING, "Method TAG requires value to be set."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "LOGIN") == 0) psSessionData->nAuthType = AUTH_LOGIN; else if (strcmp(pOpt, "PLAIN") == 0) psSessionData->nAuthType = AUTH_PLAIN; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = strdup(pOpt); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(psSessionData, logins); } FREE(psSessionData); return SUCCESS; } int initModule(_MODULE_DATA *_psSessionData, sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_IMAPS; else params.nPort = PORT_IMAP; initConnectionParams(psLogin, ¶ms); /* set TAG, if not specified by user */ if (_psSessionData->szTag == NULL) { _psSessionData->szTag = malloc(5); memset(_psSessionData->szTag, 0, 5); sprintf(_psSessionData->szTag, "gerg"); } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); /* Reset SSL flag if set (e.g., SSL connection had been reset by anti-bruteforce mechanism) */ params.nUseSSL = 0; if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(_psSessionData, hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: /* The IMAP service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. At that point the connection should be reestablished. */ if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, _psSessionData, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params) { unsigned char *bufSend = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* Retrieve IMAP server banner */ if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^\\* OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed to retrieve IMAP server banner. Exiting...", MODULE_NAME); return FAILURE; } else if ((strstr((char*)bufReceive,"* OK ") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] Received IMAP server banner: %s", MODULE_NAME, bufReceive); FREE(bufReceive); } else if ((strstr((char*)bufReceive,"* BYE Connection refused") != NULL)) { writeError(ERR_ERROR, "[%s] IMAP server refused connection. Is SSL required?", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "[%s] Failed to retrieve IMAP server banner.", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Request IMAP server capabilities */ writeError(ERR_DEBUG_MODULE, "[%s] Sending IMAP CAPABILITIES request.", MODULE_NAME); nSendBufferSize = strlen(_psSessionData->szTag) + 13; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s CAPABILITY\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: No OK message received for CAPABILITY request.", MODULE_NAME); return FAILURE; } /* If server supports STARTTLS and we are not already within a SSL connection, let's use it. */ if ((params->nUseSSL == 0) && (strstr((char*)bufReceive, "STARTTLS") != NULL)) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Initiating STARTTLS session.", MODULE_NAME); bufSend = malloc(strlen(_psSessionData->szTag) + 11 + 1); memset(bufSend, 0, strlen(_psSessionData->szTag) + 11 + 1); sprintf((char*)bufSend, "%s STARTTLS\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: No OK message received for STARTTLS request.", MODULE_NAME); return FAILURE; } /* OK Begin TLS negotiation now. */ else { FREE(bufReceive); if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish TLSv1 connection.", MODULE_NAME); return FAILURE; } /* Resend CAPABILITY request as the AUTH types may have changed. */ writeError(ERR_DEBUG_MODULE, "[%s] Sending IMAP CAPABILITIES request.", MODULE_NAME); nSendBufferSize = strlen(_psSessionData->szTag) + 13; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s CAPABILITY\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "OK .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: No OK message received for CAPABILITY request.", MODULE_NAME); return FAILURE; } } } /* Process IMAP supported authentication types */ if (_psSessionData->nAuthType != AUTH_UNKNOWN) { writeError(ERR_DEBUG_MODULE, "[%s] Ignoring server requested AUTH type and using user-specified value.", MODULE_NAME); } else if ((strstr((char*)bufReceive,"AUTH=LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr((char*)bufReceive,"AUTH=PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr((char*)bufReceive,"AUTH=NTLM") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: NTLM"); _psSessionData->nAuthType = AUTH_NTLM; } else { writeError(ERR_ERROR, "[%s] Failed: Server did not respond that it supported any of the authentication types we handle (PLAIN, LOGIN, NTLM). Use the AUTH module option to force the use of an authentication type.", MODULE_NAME); return FAILURE; } FREE(bufReceive); return SUCCESS; } /* A0001 LOGIN username password */ int sendAuthLogin(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; int nSendBufferSize = 0; int nRet = SUCCESS; nSendBufferSize = strlen(_psSessionData->szTag) + 7 + strlen(szLogin) + 1 + strlen(szPassword) + 4 + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); if (_psSessionData->szDomain) { writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate login value: %s\\\\%s %s", MODULE_NAME, _psSessionData->szDomain, szLogin, szPassword); sprintf((char*)bufSend, "%s LOGIN \"%s\\\\%s\" \"%s\"\r\n", _psSessionData->szTag, _psSessionData->szDomain, szLogin, szPassword); } else { writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate login value: %s %s", MODULE_NAME, szLogin, szPassword); sprintf((char*)bufSend, "%s LOGIN \"%s\" \"%s\"\r\n", _psSessionData->szTag, szLogin, szPassword); } if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } FREE(bufSend); return(nRet); } /* A0001 AUTHENTICATE PLAIN credentials(base64) */ int sendAuthPlain(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; char* szTmp = NULL; char* szEncodedAuth = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; /* Send initial AUTHENTICATE PLAIN command */ nSendBufferSize = strlen(_psSessionData->szTag) + 21; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s AUTHENTICATE PLAIN\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] IMAP server did not respond with \"+\" to AUTHENTICATE PLAIN request.", MODULE_NAME); writeError(ERR_ERROR, "[%s] IMAP server sent the following response: %s", MODULE_NAME, bufReceive); return FAILURE; } /* Build a null separated string of szLogin \0 szLogin \0 szPassword */ nSendBufferSize = strlen(szLogin) + 1 + strlen(szLogin) + 1 + strlen(szPassword); szTmp = malloc(nSendBufferSize + 1); memset(szTmp, 0, nSendBufferSize + 1); /* username\0username\0password */ memcpy(szTmp, szLogin, strlen(szLogin)); memcpy(szTmp + strlen(szLogin) + 1, szLogin, strlen(szLogin)); memcpy(szTmp + strlen(szLogin) + 1 + strlen(szLogin) + 1, szPassword, strlen(szPassword)); szEncodedAuth = malloc(2 * nSendBufferSize + 1); memset(szEncodedAuth, 0, 2 * nSendBufferSize + 1); base64_encode(szTmp, nSendBufferSize, szEncodedAuth); FREE(szTmp); writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate plain value: %s", MODULE_NAME, szEncodedAuth); nSendBufferSize = strlen(szEncodedAuth) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s\r\n", szEncodedAuth); FREE(szEncodedAuth); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); return SUCCESS; } /* A0001 AUTHENTICATE NTLM NTLM IMAP Authentication Based on: http://curl.haxx.se/rfc/ntlm.html#ntlmImapAuthentication http://src.opensolaris.org/source/xref/sfw/usr/src/cmd/fetchmail/fetchmail-6.3.8/README.NTLM */ int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; char* szTmpBuf = NULL; char* szTmpBuf64 = NULL; /* --- Send initial AUTHENTICATE NTLM command --- */ nSendBufferSize = strlen(_psSessionData->szTag) + 21; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s AUTHENTICATE NTLM\r\n", _psSessionData->szTag); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with an empty challenge, consisting simply of a "+" */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] IMAP server did not respond with \"+\" to AUTHENTICATE NTLM request.", MODULE_NAME); writeError(ERR_ERROR, "[%s] IMAP server sent the following response: %s", MODULE_NAME, bufReceive); return FAILURE; } FREE(bufReceive); /* --- Send Base-64 encoded Type-1 message --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Server should respond with a Base-64 encoded Type-2 challenge message. The challenge response format is specified by RFC 1730 ("+", followed by a space, followed by the challenge message). */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Server did not send valid Type-2 challenge response.", MODULE_NAME); return FAILURE; } szTmpBuf = index((char*)bufReceive, '\r'); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, bufReceive + 2); base64_decode((char*)bufReceive + 2, (char*)&sTmpChall); FREE(bufReceive); /* --- Calculate and send Base-64 encoded Type 3 response --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s\r\n", szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); /* Server should validate the response and indicate the result of authentication. e.g. 0001 OK AUTHENTICATE NTLM completed. */ return SUCCESS; } int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** psLogin, char* szLogin, char* szPassword) { int nRet = FAILURE; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; switch(_psSessionData->nAuthType) { case AUTH_LOGIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending LOGIN Authentication.", MODULE_NAME); nRet = sendAuthLogin(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_PLAIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending PLAIN Authentication.", MODULE_NAME); nRet = sendAuthPlain(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending NTLM Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } /* Exchange 2003 Server Response Messages NO Logon failure: unknown user name or bad password. NO The specified authentication package is not supported. NO Clear text passwords have been disabled for this protocol. NO Cleartext login on this server requires the use of transport level security (SSL/TLS) */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, ".*\r\n") == FAILURE) || (bufReceive == NULL)) { /* The IMAP service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. A default install of Debian (6.0.3 Squeeze) and the Courier Mail Server (0.65) was found to drop connections immediately after the 8th failed attempt. */ if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) ) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; return FAILURE; } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; } } else if (strstr((char*)bufReceive, "OK") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "NO Clear text passwords have been disabled for this protocol.") != NULL) { writeError(ERR_ERROR, "[%s] Server reports that clear-text passwords have been disabled.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "NO Cleartext login on this server requires the use of transport level security (SSL/TLS)") != NULL) { writeError(ERR_ERROR, "[%s] Server reports that clear-text passwords are only allowed over SSL/TLS.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "NO The specified authentication package is not supported.") != NULL) { writeError(ERR_ERROR, "[%s] Server reports that the specified authentication package is not supported.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "NO") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; /* Exchange 2010 can include disconnect in message -- NO AUTHENTICATE failed.[0D][0A]* BYE Connection is closed. */ if (strstr((char*)bufReceive, "* BYE ") != NULL) { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nRet = MSTATE_NEW; } } else if (strstr((char*)bufReceive, "BAD") != NULL) { writeError(ERR_ERROR, "[%s] IMAP server responded that the command was unknown or the arguments were invalid.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Unknown IMAP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(nRet); } jmk-foofus-medusa-dd62069/src/modsrc/module.h000066400000000000000000000060101460263104500211200ustar00rootroot00000000000000/*************************************************************************** * module.h * * Copyright (C) 2006 by foofus.net * * fizzgig@foofus.net * * * * Common header file for all loadable modules * * * * CHANGE LOG * * 02/18/2004 -- Created by Foofus * * 04/05/2005 -- (fizzgig) Added include for medusa-net * * 04/12/2005 -- Final "alpha" implementation * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * ***************************************************************************/ /* See to it that we only include this file once */ #ifndef __MODULE_H__ #define __MODULE_H__ 1 /* Includes */ #include "../medusa-net.h" #include "../medusa.h" #include "../medusa-trace.h" #include "../medusa-utils.h" /* Symbols */ #define MODULE_EXTENSION ".mod" extern void initConnectionParams(sLogin* pLogin, sConnectParams* pParams); /* Prototypes for required functions */ int getParamNumber( ); /* Dictates how many parameters the module allows */ void summaryUsage( char **szUsage ); /* Allocates and populates a string with brief descriptive info */ void showUsage( ); /* Displays module usage information */ int go( sLogin* logins, int argc, char *argv[] ); /* Launches the module with available parameters */ /* Typedefs for function pointers */ typedef int (*function_getParamNumber)( ); typedef void (*function_summaryUsage)( char** ); typedef void (*function_showUsage)( ); typedef int (*function_go)( sLogin*, int, char*[] ); #endif /* (was this file already included?) */ jmk-foofus-medusa-dd62069/src/modsrc/mssql.c000066400000000000000000000530131460263104500207720ustar00rootroot00000000000000/* ** M$-SQL Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Hydra 4.7 [van Hauser ] ** Nessus [HD Moore ] ** ** Tested: ** Microsoft SQL Server 2005 9.00.1399; RTM (mixed authentication) ** Microsoft SQL Server 2005 9.00.2047; SP1 (mixed authentication) ** Microsoft SQL Server 2005 9.00.3042; SP2 (mixed authentication) ** ** Notes: ** SQL 2005: SQL logins use the password policy of the underlying operating system ** Windows Authentication mode is selected during installation, the sa login is disabled ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "mssql.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for M$-SQL sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: mssql.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include #include #define PORT_MSSQL 1433 #define PORT_MSSQLM 1434 #define MSLEN 30 typedef struct __MODULE_DATA { int nPort; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int connectMSSQL(sLogin *psLogin, _MODULE_DATA *_psSessionData); int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA* _psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "NOTE: MS-SQL Developer Edition or MSDE's concurrent workload governor limits you"); writeVerbose(VB_NONE, " to no more than five concurrent connections to the server at any one time."); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[] __attribute__((unused))) { _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if (argc != 0) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; _psSessionData->nPort = 0; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; if ((hSocket = connectMSSQL(psLogin, _psSessionData)) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish MS-SQL connection.", MODULE_NAME); return FAILURE; } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* MS-SQL Specific Functions */ /* Establish connection to remote MS-SQL server using the following logic: * if the user specified a TCP port, we use it * else if this is a new connection, we send a SQL ping to the SQL monitor port * * if a response is received, we use the port listed for the first SQL instance * (2433/tcp is used if the first instance is "hiding" its port) * * else we use the default port identified by PORT_MSSQL (i.e. 1433/tcp) */ int connectMSSQL(sLogin *_psLogin, _MODULE_DATA *_psSessionData) { sConnectParams params; int nReceiveBufferSize = 0; unsigned char *bufReceive = NULL; int nPort = PORT_MSSQL; int nPortTmp = 0; int hSocket; unsigned char pkt_sqlping[] = { 0x02 }; int nPingResponseLen = 0; int nSQLInstance = 0; int nSQLInstancePort = 0; char *szTmp = NULL; char *szTmp1 = NULL; char *szTmp2 = NULL; writeError(ERR_DEBUG_MODULE, "[%s] Querying MS-SQL monitor port to enumerate MS-SQL server TCP port.", MODULE_NAME); /* Query MS-SQL Monitor (SQL Server Browser) port to enumerate MS-SQL server TCP port The MS-SQL server instances and information about those instances for a given system can be enumerated anonymous via a simple query. For additional information about this operation, see "Threat Profiling Microsoft SQL Server" (www.nextgenss.com/papers/tp-SQL2000.pdf). The following are two example responses: Single SQL Server Instance Installation: [0x05][0x76][0x00]ServerName;WIN2K3STD;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;tcp;1433;np;\\WIN2K3STD\pipe\sql\query;; Three SQL Server Instance Installation (first using port hiding option): [0x05[0x85][0x01]ServerName;WIN2K3STD;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;np;\\WIN2K3STD\pipe\sql\query;; ServerName;WIN2K3STD;InstanceName;SQL_INSTANCE_2;IsClustered;No;Version;8.00.194;tcp;1308;np;\\WIN2K3STD\pipe\MSSQL$SQL_INSTANCE_2\sql\query;; ServerName;WIN2K3STD;InstanceName;SQLINSTANCE3;IsClustered;No;Version;8.00.194;tcp;1422;np;\\WIN2K3STD\pipe\MSSQL$SQLINSTANCE3\sql\query;; It is assumed the first byte of the response (0x05) signals a valid response. The next two bytes indicate the length of the actual data. For example, [0x85][0x01] -> 0x0185 -> 389 bytes It's possible that if a system has many instances, the UDP packet may exceed our default recv() buffer, or arrive in multiple datagrams. We don't currently handle either of these situations and some of the information would be lost. */ if ((_psLogin->psServer->psAudit->iPortOverride == 0) && (_psSessionData->nPort == 0)) { memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_MSSQLM; initConnectionParams(_psLogin, ¶ms); hSocket = medusaConnectUDP(¶ms); if (hSocket < 0) { writeError(ERR_ERROR, "[%s] Failed to connect to MS-SQL monitor UDP port (%d). Auto-identification of MS-SQL port unsuccessful on host: %s.", MODULE_NAME, PORT_MSSQLM, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (medusaSend(hSocket, pkt_sqlping, 1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] SQL server (%s) did not respond to port query request. Using default value of 1433/tcp.", MODULE_NAME, _psLogin->psServer->pHostIP); nPort = 1433; } else if (bufReceive[0] == 0x05) { writeError(ERR_DEBUG_MODULE, "[%s] Processing SQL ping response.", MODULE_NAME); nPingResponseLen = ((bufReceive[2] & 0xFF) << 8) | (bufReceive[1] & 0xFF); writeError(ERR_DEBUG_MODULE, "[%s] SQL ping response packet reported data length: %d", MODULE_NAME, nPingResponseLen); if (nReceiveBufferSize != nPingResponseLen + 3) writeError(ERR_ERROR, "[%s] Reported SQL ping data length does not match our receive buffer length. Response data may have been lost.", MODULE_NAME); nSQLInstance = 1; szTmp = (char*)bufReceive + 3; while ((szTmp = strstr(szTmp, "ServerName;")) != NULL) { szTmp1 = strstr(szTmp, ";;"); if (szTmp1 == NULL) { writeError(ERR_ERROR, "[%s] Possible incomplete capture of service information on host %s. There may be additional SQL services.", MODULE_NAME, _psLogin->psServer->pHostIP); break; } memset(szTmp1, 0, 1); szTmp1 += 2; writeError(ERR_DEBUG_MODULE, "[%s] SQL server (%s) ping response (instance: %d) - %s", MODULE_NAME, _psLogin->psServer->pHostIP, nSQLInstance, szTmp); /* ServerName;MACHINE_NAME;InstanceName;MICROSOFT##SSEE;IsClustered;No;Version;9.00.4035.00;np; */ if (strstr(szTmp, "InstanceName;MICROSOFT##SSEE") != NULL) { writeError(ERR_ERROR, "[%s] Internal database (SQL Server Embedded Edition) identified (NOT TESTED) - server %s", MODULE_NAME, _psLogin->psServer->psHost->pHost); writeVerbose(VB_NONE_FILE, "[%s] Internal database (SQL Server Embedded Edition) identified (NOT TESTED) - server %s\n", MODULE_NAME, _psLogin->psServer->psHost->pHost); } /* ServerName;MACHINE_NAME;InstanceName;DATABASE_NAME;IsClustered;No;Version;9.00.3042.00 */ else if ((szTmp2 = strstr(szTmp, ";tcp;")) == NULL) { writeError(ERR_ERROR, "[%s] Internal or hidden database identified (NOT TESTED) - server %s. (Default hidden value is 2433/tcp)", MODULE_NAME, _psLogin->psServer->psHost->pHost); writeVerbose(VB_NONE_FILE, "[%s] Internal or hidden database identified (NOT TESTED) - server %s. (Default hidden value is 2433/tcp)\n", MODULE_NAME, _psLogin->psServer->psHost->pHost); } /* ServerName;MACHINE_NAME;InstanceName;MSSQLSERVER;IsClustered;No;Version;8.00.194;tcp;1433;np; */ else { szTmp2 += 5; /* skip ";tcp;" */ if ( index(szTmp2, 0x3B) ) { memset( index(szTmp2, 0x3B), 0, 1); } /* ";" */ nPortTmp = atoi(szTmp2); if (nSQLInstancePort == 0) { nPort = nPortTmp; nSQLInstancePort++; writeError(ERR_DEBUG_MODULE, "[%s] Connecting to SQL server %s on port %d/tcp.", MODULE_NAME, _psLogin->psServer->pHostIP, nPort); } else { writeError(ERR_ERROR, "[%s] Additional SQL server identified (NOT TESTED) - server %s on port %d/tcp", MODULE_NAME, _psLogin->psServer->psHost->pHost, nPortTmp); writeVerbose(VB_NONE_FILE, "[%s] Additional SQL server identified (NOT TESTED) - server %s on port %d/tcp\n", MODULE_NAME, _psLogin->psServer->psHost->pHost, nPortTmp); } } szTmp = szTmp1; nSQLInstance++; } } else { writeError(ERR_ERROR, "[%s] SQL server (%s) sent unknown response to \"SQL Ping\" request.", MODULE_NAME, _psLogin->psServer->pHostIP); } FREE(bufReceive); if (hSocket > 0) medusaDisconnect(hSocket); } else if ((_psLogin->psServer->psAudit->iPortOverride == 0) && (_psSessionData->nPort != 0)) { nPort = _psSessionData->nPort; writeError(ERR_DEBUG_MODULE, "[%s] Using previously set port: %d/tcp", MODULE_NAME, nPort); } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else params.nPort = nPort; initConnectionParams(_psLogin, ¶ms); _psSessionData->nPort = params.nPort; hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] Failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->psHost->pHost); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } return hSocket; } void makeSQLLogin(char* szLogin, char* szPassword, unsigned char* buffer) { unsigned char pkt_hdr[] = { 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char pkt_pt2[] = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x61, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x18, 0x81, 0xb8, 0x2c, 0x08, 0x03, 0x01, 0x06, 0x0a, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x71, 0x75, 0x65, 0x6c, 0x64, 0x61, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned char pkt_pt3[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x4d, 0x53, 0x44, 0x42, 0x4c, 0x49, 0x42, 0x00, 0x00, 0x00, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; char ms_login[MSLEN + 1]; char ms_pass[MSLEN + 1]; memset(ms_login, 0, MSLEN + 1); memset(ms_pass, 0, MSLEN + 1); strncpy(ms_login, szLogin, MSLEN); strncpy(ms_pass, szPassword, MSLEN); unsigned char len_login, len_pass; len_login = (unsigned char)strlen(ms_login); len_pass = (unsigned char)strlen(ms_pass); memcpy(buffer, pkt_hdr, 39); memcpy(buffer + 39, ms_login, MSLEN); memcpy(buffer + MSLEN + 39, &len_login, 1); memcpy(buffer + MSLEN + 1 + 39, ms_pass, MSLEN); memcpy(buffer + MSLEN + 1 + 39 + MSLEN, &len_pass, 1); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1, pkt_pt2, 110); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1 + 110, &len_pass, 1); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1 + 110 + 1, ms_pass, MSLEN); memcpy(buffer + MSLEN + 1 + 39 + MSLEN + 1 + 110 + 1 + MSLEN, pkt_pt3, 270); return; } int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[3 * MSLEN + 422 + 1]; unsigned char* bufReceive; int nReceiveBufferSize = 0; unsigned char pkt_langp[] = { 0x02, 0x01, 0x00, 0x47, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 }; memset(bufSend, 0, 3 * MSLEN + 422 + 1); makeSQLLogin(szLogin, szPassword, bufSend); if (medusaSend(hSocket, bufSend, MSLEN + 1 + 39 + MSLEN + 1 + 110 + 1 + MSLEN + 270, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } if (medusaSend(hSocket, pkt_langp, 71, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { return FAILURE; } writeError(ERR_DEBUG_MODULE, "[tryLogin] medusaReceiveRaw set nReceiveBufferSize: %d", nReceiveBufferSize); if (bufReceive[8] == 0xe3) { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } writeError(ERR_DEBUG_MODULE, "[tryLogin] set iRet: %d", iRet); FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/mysql.c000066400000000000000000000671601460263104500210100ustar00rootroot00000000000000/* ** MySQL Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** MySQL 4.1 authentication support added by: pmonkey ** ** MySQL <4.1 Pass Hash Support: jmk ** ** This module supports MySQL protocol 10. ** ** The older MySQL pre-4.1 authentication scheme is vulnerable to a pass-the- ** hash authentication attack. Utilizing the old-style hashes gathered from a ** MySQL database, a user can use Medusa to verify their validity on other ** servers. A modified MySQL client can also be use to connect to located ** services directly utilizing a valid hash. ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "mysql.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for MySQL sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: mysql.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_MYSQL 3306 #define PROTO_UNKNOWN 0 #define PROTO_OLD 1 #define PROTO_NEW 2 #define PASSWORD 1 #define HASH 2 typedef struct __MYSQL_DATA { int protoFlag; int hashFlag; } _MYSQL_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _MYSQL_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MYSQL_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " PASS:? (PASSWORD*, HASH)"); writeVerbose(VB_NONE, " PASSWORD: Use normal password."); writeVerbose(VB_NONE, " HASH: Use a hash rather than a password. (non-SHA1 hashes only)"); writeVerbose(VB_NONE, "\n(*) Default value"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage examples:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "1: Normal boring check..."); writeVerbose(VB_NONE, " medusa -M mysql -h somehost -u someuser -p somepassword"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "2: Using an old-style MySQL hash..."); writeVerbose(VB_NONE, " medusa -M mysql -h somehost -U users.txt -p 39b52a209cf03d62 -m PASS:HASH"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _MYSQL_DATA *psSessionData; psSessionData = malloc(sizeof(_MYSQL_DATA)); memset(psSessionData, 0, sizeof(_MYSQL_DATA)); psSessionData->protoFlag = PROTO_NEW; if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); psSessionData->hashFlag = PASSWORD; for (i=0; ihashFlag = PASSWORD; else if (strcmp(pOpt, "HASH") == 0) psSessionData->hashFlag = HASH; else writeError(ERR_WARNING, "Invalid value for method PASS."); } free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MYSQL_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_MYSQL; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int MySQLSessionQuit(int hSocket) { unsigned char com_quit_packet[5] = { 0x01, 0x00, 0x00, 0x00, 0x01 }; if (medusaSend(hSocket, com_quit_packet, 5, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } /* Code used verbatim from: MySQL 3.21 [mysql_com.h / password.c] */ struct rand_struct { unsigned long seed1, seed2, max_value; double max_value_dbl; }; void randominit(struct rand_struct *rand_st, unsigned long seed1, unsigned long seed2) { /* for mysql 3.21.# */ rand_st->max_value = 0x3FFFFFFFL; rand_st->max_value_dbl = (double) rand_st->max_value; rand_st->seed1 = seed1 % rand_st->max_value; rand_st->seed2 = seed2 % rand_st->max_value; } double rnd(struct rand_struct *rand_st) { rand_st->seed1 = (rand_st->seed1 * 3 + rand_st->seed2) % rand_st->max_value; rand_st->seed2 = (rand_st->seed1 + rand_st->seed2 + 33) % rand_st->max_value; return (((double) rand_st->seed1) / rand_st->max_value_dbl); } /* Code used verbatim from: MySQL 4.1 [password.c] */ #define PVERSION41_CHAR '*' typedef unsigned char uint8; typedef unsigned char uchar; typedef unsigned long long int ulonglong; typedef unsigned int uint32; typedef short int16; typedef unsigned long ulong; #include "sha1.h" #define SCRAMBLE_LENGTH 20 #define SCRAMBLE_LENGTH_323 8 #define char_val(X) (X >= '0' && X <= '9' ? X-'0' :\ X >= 'A' && X <= 'Z' ? X-'A'+10 :\ X >= 'a' && X <= 'z' ? X-'a'+10 :\ '\177') void hash_password(ulong *result, const char *password, uint password_len) { register ulong nr=1345345333L, add=7, nr2=0x12345671L; ulong tmp; const char *password_end= password + password_len; for (; password < password_end; password++) { if (*password == ' ' || *password == '\t') continue; /* skip space in password */ tmp= (ulong) (uchar) *password; nr^= (((nr & 63)+add)*tmp)+ (nr << 8); nr2+=(nr2 << 8) ^ nr; add+=tmp; } result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */; result[1]=nr2 & (((ulong) 1L << 31) -1L); } void octet2hex(char *to, const uint8 *str, unsigned int len) { char _dig_vec_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const uint8 *str_end= str + len; for (; str != str_end; ++str) { *to++= _dig_vec_upper[(*str & 0xF0) >> 4]; *to++= _dig_vec_upper[*str & 0x0F]; } *to= '\0'; } void hex2octet(uint8 *to, const char *str, uint len) { const char *str_end= str + len; while (str < str_end) { register char tmp= char_val(*str++); *to++= (tmp << 4) | char_val(*str++); } } static void my_crypt(char *to, const uchar *s1, const uchar *s2, uint len) { const uint8 *s1_end= s1 + len; while (s1 < s1_end) *to++= *s1++ ^ *s2++; } double my_rnd(struct rand_struct *rand_st) { rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value; return (((double) rand_st->seed1)/rand_st->max_value_dbl); } void scramble_323(char *to, _MYSQL_DATA *_psSessionData, const char *message, const char *password) { struct rand_struct rand_st; ulong hash_pass[2], hash_message[2]; if (password && password[0]) { char extra, *to_start=to; const char *message_end= message + SCRAMBLE_LENGTH_323; /* Idea borrowed from "The Database Hacker's Handbook: Defending Database Servers" */ if (_psSessionData->hashFlag == HASH) { if (strlen(password) != 16) writeError(ERR_ERROR, "[%s] Invalid Hash Type (Old Style Hash Required)", MODULE_NAME); sscanf(password, "%08lx%08lx", &hash_pass[0], &hash_pass[1]); } else hash_password(hash_pass, password, strlen(password)); hash_password(hash_message, message, SCRAMBLE_LENGTH_323); randominit(&rand_st, hash_pass[0] ^ hash_message[0], hash_pass[1] ^ hash_message[1]); for (; message < message_end; message++) *to++= (char) (floor(my_rnd(&rand_st)*31)+64); extra=(char) (floor(my_rnd(&rand_st)*31)); while (to_start != to) *(to_start++)^=extra; } *to= 0; } void scramble(char *to, _MYSQL_DATA *_psSessionData, const char *message, const char *password) { SHA1_CONTEXT sha1_context; uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage2[SHA1_HASH_SIZE]; sha1_reset(&sha1_context); /* Stock pass-the-hash Attacks do not appear feasible. However, if another conversation is intercepted and the SHA1 hash (hash_stage2) is known, hash_stage1 could probably be derived. A new reply could then be generated based on that information. Of course, if we already have this sort of network access, what are we messing with this for? */ if (_psSessionData->hashFlag == HASH) if ( (strncmp(password, "*", 1) == 0) && (strlen(password) == 2 * SHA1_HASH_SIZE + 1) ) writeError(ERR_ERROR, "[%s] MySQL 4.1 and above use a SHA1-based authentication scheme which does not appear to be susceptible to pass-the-hash style attacks.", MODULE_NAME); /* stage 1: hash password */ sha1_input(&sha1_context, (uint8 *) password, strlen(password)); sha1_result(&sha1_context, hash_stage1); /* stage 2: hash stage 1; note that hash_stage2 is stored in the database */ sha1_reset(&sha1_context); sha1_input(&sha1_context, hash_stage1, SHA1_HASH_SIZE); sha1_result(&sha1_context, hash_stage2); /* create crypt string as sha1(message, hash_stage2) */; sha1_reset(&sha1_context); sha1_input(&sha1_context, (const uint8 *) message, SCRAMBLE_LENGTH); sha1_input(&sha1_context, hash_stage2, SHA1_HASH_SIZE); /* xor allows 'from' and 'to' overlap: lets take advantage of it */ sha1_result(&sha1_context, (uint8 *) to); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); } /* End of MySQL copy and paste items */ int MySQLPrepareAuthOld(_MYSQL_DATA *_psSessionData, char* szLogin, char* szPassword, char* szSessionSalt, unsigned char** szResponse, unsigned long* iResponseLength) { unsigned char* response; /* usernames limited to 16 characters - http://dev.mysql.com/doc/refman/5.1/en/user-names.html */ int login_len = strlen(szLogin) > 16 ? 16 : strlen(szLogin); int response_len = 4 /* header */ + 2 /* client flags */ + 3 /* max packet len */ + login_len /* username length */ + 1 /* NULL terminate username */ + 8; /* scrambled password len */ response = (unsigned char *) malloc(response_len + 1); memset(response, 0, response_len + 1); response[0] = response_len - 4; /* packet length */ response[1] = 0x00; response[2] = 0x00; response[3] = 0x01; /* packet number */ response[4] = 0x85; /* client flag */ response[5] = 0x24; response[6] = 0x00; /* max packet */ response[7] = 0x00; response[8] = 0x00; memcpy((char*)response + 9, szLogin, login_len); response[9 + login_len] = '\0'; /* null terminate login */ if ( strcmp(szPassword, "") != 0) /* password set */ scramble_323((char *) &response[9 + login_len + 1], _psSessionData, szSessionSalt, szPassword); *(iResponseLength) = response_len; *szResponse = response; return SUCCESS; } /* Protocol 10 is used by MySQL 3.22 and later. However, MySQL 4.1 introduced a new password algorithm. In some cases, MySQL 4.1 and later systems will contain accounts which are still configured with password hashes generated using the older algorithm. When we authenticate to a 4.1 server and this is the case, the server is nice enough to tell us and allow us to reauthenticate. This function generates the appropriate response for this particular case. */ int MySQLPrepareAuthNewOld(_MYSQL_DATA *_psSessionData, char* szPassword, char* szSessionSalt, unsigned char** szResponse, unsigned long* iResponseLength) { unsigned char* response; int response_len = 4 + /* header */ 1 + 8; /* scrambled password length */ response = (unsigned char *) malloc(response_len + 1); memset(response, 0, response_len + 1); response[0] = response_len - 4; /* packet length */ response[3] = 0x03; /* packet number */ scramble_323((char *) &response[4], _psSessionData, szSessionSalt, szPassword); *(iResponseLength) = response_len; *szResponse = response; return SUCCESS; } /* http://www.redferni.uklinux.net/mysql/MySQL-Protocol.html */ int MySQLPrepareAuth(_MYSQL_DATA *_psSessionData, char* szLogin, char* szPassword, char* szSessionSalt, unsigned char** szResponse, unsigned long* iResponseLength) { unsigned char* response; /* usernames limited to 16 characters - http://dev.mysql.com/doc/refman/5.1/en/user-names.html */ int login_len = strlen(szLogin) > 16 ? 16 : strlen(szLogin); int response_len = 4 /* header */ + 4 /* client flags */ + 4 /* max packet len */ + 1 /* charset */ + 23 /* future expansion */ + login_len /* username */ + 1 /* NULL termination */ + 1; /* password length */ if ( strcmp(szPassword, "") != 0 ) /* password set */ response_len += 20; response = (unsigned char *) malloc(response_len + 1); memset(response, 0, response_len + 1); response[0] = response_len - 4; /* packet body length - exclude header */ response[1] = 0x00; response[2] = 0x00; response[3] = 0x01; /* packet number */ //response[4] = 0x85; /* client flag */ response[4] = 0x05; /* client flag */ //response[5] = 0x24; response[5] = 0xa6; response[6] = 0x03; response[7] = 0x00; response[8] = 0x00; /* max packet */ response[9] = 0x00; response[10] = 0x00; response[11] = 0x01; response[12] = 0x21; /* charset utf8 */ memcpy((char*)response + 36, szLogin, login_len); /* NULL terminated username */ if ( strcmp(szPassword, "") == 0 ) /* no password set */ { response[36 + login_len + 1] = 0x00; } else { response[36 + login_len + 1] = 0x14; /* set length of scrambled password - 0x14 (20) */ /* generate SHA password hash */ scramble((char *) &response[36 + login_len + 1 + 1], _psSessionData, szSessionSalt, szPassword); } *(iResponseLength) = response_len; *szResponse = response; return SUCCESS; } int MySQLSessionInit(int hSocket, char** szSessionSalt) { unsigned char* bufReceive; char* szServerVersion; int nReceiveBufferSize = 0; int newerauth = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* check protocol version */ if (bufReceive[4] == 0xff) { if (strstr((char*)bufReceive + 7, "is not allowed to connect to this MySQL server")) { writeError(ERR_WARNING, "%s: Server responded that host is not allowed to connect to MySQL service.", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "%s: Failed to retrieve server version: %s", MODULE_NAME, bufReceive + 7); FREE(bufReceive); return FAILURE; } } if (bufReceive[4] < 10) { writeError(ERR_ERROR, "%s: Server responded requesting protocol version (%d). Version 10 support required.", MODULE_NAME, bufReceive[4]); FREE(bufReceive); return FAILURE; } else if (bufReceive[4] > 10) { writeError(ERR_WARNING, "%s: Server responded requesting protocol version (%d). Support for versions >10 is unknown.", MODULE_NAME, bufReceive[4]); } /* check server version */ szServerVersion = (char*)bufReceive + 5; if (!(strstr(szServerVersion, "3.") || strstr(szServerVersion, "4.") || strstr(szServerVersion, "5.") )) { writeError(ERR_ERROR, "%s: Server responded requesting version (%d). Only versions 3.x, 4.x, and 5.x are currently supported.", MODULE_NAME, szServerVersion); FREE(bufReceive); return FAILURE; } if ((strstr(szServerVersion, "4.1") || strstr(szServerVersion, "5.") )) { newerauth=1; writeError(ERR_DEBUG_MODULE, "%s: Server version %s is using newer auth method.", MODULE_NAME, szServerVersion); } if (newerauth) { /* retrieve session salt for newer auth */ *szSessionSalt = malloc(22); memset(*szSessionSalt, 0, 22); memcpy(*szSessionSalt, bufReceive + strlen(szServerVersion) + 10, 9); memcpy(*szSessionSalt+8 , bufReceive + strlen(szServerVersion) + 37 , 12); if (strlen(*szSessionSalt) != 20) { writeError(ERR_ERROR, "%s: Failed to retrieve valid session salt.", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "%s: Retrieved session salt: %s", MODULE_NAME, *szSessionSalt); } } else { /* use the older salt code */ *szSessionSalt = malloc(10); memset(*szSessionSalt, 0, 10); memcpy(*szSessionSalt, bufReceive + strlen(szServerVersion) + 10, 9); if (strlen(*szSessionSalt) != 8) { writeError(ERR_ERROR, "%s: Failed to retrieve valid session salt.", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "%s: Retrieved session salt: %s.", MODULE_NAME, *szSessionSalt); } } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MYSQL_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; int iReturnCode = MSTATE_EXITING; unsigned char* bufReceive = NULL; char* szSessionSalt = NULL; unsigned char* szResponse = NULL; unsigned long iResponseLength = 0; int nReceiveBufferSize = 0; /* initialize MySQL connection */ iRet = MySQLSessionInit(hSocket, &szSessionSalt); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to initialize MySQL connection (%s).", MODULE_NAME, (*psLogin)->psServer->pHostIP); (*psLogin)->iResult = LOGIN_RESULT_ERROR; return MSTATE_EXITING; } /* prepare client authentication packet */ if (strlen(szSessionSalt) == 8 || _psSessionData->protoFlag == PROTO_OLD) { if (_psSessionData->protoFlag == PROTO_OLD) { writeError(ERR_DEBUG_MODULE, "[%s] Using older style authentication based on previous server response.", MODULE_NAME); } iRet = MySQLPrepareAuthOld(_psSessionData, szLogin, szPassword, szSessionSalt, &szResponse, &iResponseLength); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to create client authentication packet.", MODULE_NAME); return FAILURE; } } else { iRet = MySQLPrepareAuth(_psSessionData, szLogin, szPassword, szSessionSalt, &szResponse, &iResponseLength); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to create client authentication packet.", MODULE_NAME); return FAILURE; } } /* send authentication attempt */ if (medusaSend(hSocket, szResponse, iResponseLength, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); FREE(szResponse); return FAILURE; } FREE(szResponse); /* process authentication response */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } if (bufReceive[4] == 0x00) { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iReturnCode = MSTATE_EXITING; } else if (bufReceive[4] == 0xFF) { (*psLogin)->iResult = LOGIN_RESULT_FAIL; if (bufReceive[5] == 0xe3 && bufReceive[6] == 0x04) { writeError(ERR_ERROR, "[%s] failed: MYSQL VERSION IS NEWER\n", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iReturnCode = MSTATE_EXITING; } else iReturnCode = MSTATE_NEW; } else if (bufReceive[4] == 0xFE) { /* Protocol 10 is used by MySQL 3.22 and later. However, MySQL 4.1 introduced a new password algorithm. In some cases, MySQL 4.1 and later systems will contain accounts which are still configured with password hashes generated using the older algorithm. When we authenticate to a 4.1 server and this is the case, the server is nice enough to tell us and allow us to reauthenticate. */ writeError(ERR_DEBUG_MODULE, "[%s] Server requested older authentication type. It is likely the remote account exists and has an older style password hash.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; /* Attempt authentication again using old-style password hash and existing connection */ _psSessionData->protoFlag = PROTO_OLD; iRet = MySQLPrepareAuthNewOld(_psSessionData, szPassword, szSessionSalt, &szResponse, &iResponseLength); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to create client authentication packet.", MODULE_NAME); return FAILURE; } /* send authentication attempt */ if (medusaSend(hSocket, szResponse, iResponseLength, 0) < 0) { writeError(ERR_ERROR, "[%s] medusaSend was not successful", MODULE_NAME); FREE(szResponse); return FAILURE; } FREE(szResponse); /* process authentication response */ FREE(bufReceive); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } if (bufReceive[4] == 0x00) { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iReturnCode = MSTATE_EXITING; } else if (bufReceive[4] == 0xFF) { (*psLogin)->iResult = LOGIN_RESULT_FAIL; if (bufReceive[5] == 0xe3 && bufReceive[6] == 0x04) { writeError(ERR_ERROR, "%s failed: MYSQL VERSION IS NEWER\n", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iReturnCode = MSTATE_EXITING; } else iReturnCode = MSTATE_NEW; } /* End of the weird downshift resend case */ } else { writeError(ERR_ERROR, "%s: Unknown response code received from server: %X", MODULE_NAME, bufReceive[4]); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iReturnCode = MSTATE_EXITING; } /* close MySQL connection */ iRet = MySQLSessionQuit(hSocket); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to terminate MySQL connection.", MODULE_NAME); return FAILURE; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iReturnCode); } jmk-foofus-medusa-dd62069/src/modsrc/ncp.c000066400000000000000000000404231460263104500204140ustar00rootroot00000000000000/* ** NCP Password/HASH Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ncpfs/nwauth ** ftp://platan.vc.cvut.cz/pub/linux/ncpfs/ ** ** Username format: BLAH.OU=Servers.O=foofus // found in current context.\nTrying server context */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "ncp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for NCP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: ncp.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBNCP_WARNING "No usable LIBNCP. Module disabled." #ifdef HAVE_LIBNCP #include typedef struct __NCP_DATA { struct ncp_conn_spec spec; struct ncp_conn *conn; char *context; } _NCP_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(sLogin** login, _NCP_DATA* _psSessionData, char* szPassword); int initModule(sLogin* login, _NCP_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " CONTEXT:? "); writeVerbose(VB_NONE, " Sets user context information."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "It should be noted that libncp does not by default automatically specific a user context."); writeVerbose(VB_NONE, "If it fails to resolve the name provided it appends the server's context to the username and attempts"); writeVerbose(VB_NONE, "to resolve that value. It is advised that users specify a context for each account being tested."); writeVerbose(VB_NONE, "A global context can be specified using the CONTEXT option. A per-user context can be defined"); writeVerbose(VB_NONE, "as part of the account name within a file containing usernames or the username passed via the "); writeVerbose(VB_NONE, "command-line."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M ncp -m CONTEXT:.OU=administrators.O=foofus -u username\""); writeVerbose(VB_NONE, " Usage example: \"-M ncp -u username.OU=administrators.O=foofus\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Libncp, by default, also uses both the NDS and BIND authenticators. Unfortunately, the only"); writeVerbose(VB_NONE, "error message returned to the module is that of the BIND authenticator. These messages are not"); writeVerbose(VB_NONE, "as descriptive as NDS and only seem to report success or failure. In order to have more useful"); writeVerbose(VB_NONE, "messages (account disabled/max logons exceeded/etc.), create a ~/.nwclient or /etc/ncpfs.conf"); writeVerbose(VB_NONE, "file with the following text:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " [Requester]"); writeVerbose(VB_NONE, " NetWare Protocol = NDS"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _NCP_DATA *psSessionData; psSessionData = malloc(sizeof(_NCP_DATA)); memset(psSessionData, 0, sizeof(_NCP_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; icontext = malloc(strlen(pOpt)); strncpy((char *)psSessionData->context, pOpt, strlen(pOpt)); } else writeError(ERR_WARNING, "Method CONTEXT requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); FREE(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _NCP_DATA *_psSessionData) { enum MODULE_STATE nState = MSTATE_NEW; char *szUserContext = NULL; long NCPErrorCode; sCredentialSet *psCredSet = NULL; int i = 0; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: FREE(szUserContext); if (_psSessionData->context != NULL) { szUserContext = malloc(strlen(psCredSet->psUser->pUser) + strlen(_psSessionData->context) + 1); memset(szUserContext, 0, strlen(psCredSet->psUser->pUser) + strlen(_psSessionData->context) + 1); strcpy(szUserContext, psCredSet->psUser->pUser); strcat(szUserContext, _psSessionData->context); } else szUserContext = psCredSet->psUser->pUser; writeError(ERR_DEBUG_MODULE, "[%s] Set user context: %s", MODULE_NAME, szUserContext); NCPErrorCode = ncp_find_conn_spec3(psLogin->psServer->pHostIP, szUserContext, "", 1, 1 ? ~0U : getuid(), 0, &_psSessionData->spec); if (NCPErrorCode) { writeError(ERR_ERROR, "[%s] Failed to find an appropriate connection: %d.", MODULE_NAME, NCPErrorCode); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* Initiate NCP session connection - retry if necessary */ writeError(ERR_DEBUG_MODULE, "Attempting to establish connection with NCP server."); for (i = 1; i <= psLogin->psServer->psHost->iRetries + 1; i++) { NCPErrorCode = NWCCOpenConnByName(NULL, _psSessionData->spec.server, NWCC_NAME_FORMAT_BIND, NWCC_OPEN_NEW_CONN, NWCC_RESERVED, &_psSessionData->conn); if (NCPErrorCode) { writeError(ERR_ERROR, "[%s] Failed establishing NCP session (%d/%d): Error Code: %d Host: %s User: %s Pass: %s", MODULE_NAME, i, psLogin->psServer->psHost->iRetries + 1, NCPErrorCode, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); if (i == psLogin->psServer->psHost->iRetries + 1) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(&psLogin, _psSessionData, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: ncp_close(_psSessionData->conn); nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module (%d) state %d host: %s", MODULE_NAME, psLogin->iId, nState, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } if (_psSessionData->context != NULL) if (szUserContext != NULL) FREE(szUserContext); FREE(psCredSet); return SUCCESS; } int tryLogin(sLogin** psLogin, _NCP_DATA* _psSessionData, char* szPassword) { unsigned int i; int iRet; short int NCPErrorCode = 0; char *pErrorMsg = NULL; char ErrorCode[12]; int object_type = NCP_BINDERY_USER; char *szTemp = NULL; short int ncpErrorCode[] = { 0xFFFF, /* UNKNOWN_ERROR_CODE */ 0x0000, /* STATUS_SUCCESS */ 0xFD63, /* STATUS_LOGON_FAILURE */ 0xFDA7, /* SPECIFIED_BINARY_OBJECT_DOES_NOT_EXIST */ /* include/ncp/ncplib.h */ 0x8998, /* NWE_VOL_INVALID */ 0x899B, /* NWE_DIRHANDLE_INVALID */ 0x89C5, /* NWE_LOGIN_LOCKOUT */ 0x89D3, /* NWE_Q_NO_RIGHTS */ 0x89D5, /* NWE_Q_NO_JOB */ //0x89D6, /* NWE_Q_NO_JOB_RIGHTS */ 0x89D6, /* NWE_PASSWORD_UNENCRYPTED */ 0x89D7, /* NWE_PASSWORD_NOT_UNIQUE */ 0x89D8, /* NWE_PASSWORD_TOO_SHORT */ 0x89D9, /* NWE_LOGIN_MAX_EXCEEDED */ 0x89DA, /* NWE_LOGIN_UNAUTHORIZED_TIME */ 0x89DB, /* NWE_LOGIN_UNAUTHORIZED_STATION */ 0x89DC, /* NWE_ACCT_DISABLED */ 0x89DE, /* NWE_PASSWORD_INVALID */ 0x89DF, /* NWE_PASSWORD_EXPIRED */ 0x89E9, /* NWE_BIND_MEMBER_ALREADY_EXISTS */ 0x89FB, /* NWE_NCP_NOT_SUPPORTED */ 0x89FC, /* NWE_SERVER_UNKNOWN */ 0x89FD, /* NWE_CONN_NUM_INVALID */ 0x89FF, /* NWE_SERVER_FAILURE */ }; char *ncpErrorMsg[] = { "UNKNOWN_ERROR_CODE", "STATUS_SUCCESS", "STATUS_LOGON_FAILURE", "SPECIFIED_BINARY_OBJECT_DOES_NOT_EXIST", "NWE_VOL_INVALID", "NWE_DIRHANDLE_INVALID", "NWE_LOGIN_LOCKOUT", "NWE_Q_NO_RIGHTS", "NWE_Q_NO_JOB", //"NWE_Q_NO_JOB_RIGHTS", "NWE_PASSWORD_UNENCRYPTED", "NWE_PASSWORD_NOT_UNIQUE", "NWE_PASSWORD_TOO_SHORT", "NWE_LOGIN_MAX_EXCEEDED", "NWE_LOGIN_UNAUTHORIZED_TIME", "NWE_LOGIN_UNAUTHORIZED_STATION", "NWE_ACCT_DISABLED", "NWE_PASSWORD_INVALID", "NWE_PASSWORD_EXPIRED", "NWE_BIND_MEMBER_ALREADY_EXISTS", "NWE_NCP_NOT_SUPPORTED", "NWE_SERVER_UNKNOWN", "NWE_CONN_NUM_INVALID", "NWE_SERVER_FAILURE" }; memset(&ErrorCode, 0, 12); // NCP_BINDERY_NAME_LEN 48 // NCPFS_MAX_CFG_USERNAME 256 // NetWare 5 case insensitive??? size_t l = strlen(szPassword); if (l >= sizeof(_psSessionData->spec.password)) { ncp_close(_psSessionData->conn); writeError(ERR_ERROR, "[%s] Password too long. Max length 48 characters.", MODULE_NAME); iRet = MSTATE_EXITING; return(iRet); } memset(_psSessionData->spec.password, 0, sizeof(_psSessionData->spec.password)); memcpy(_psSessionData->spec.password, szPassword, l); /* Upper-case password */ szTemp = _psSessionData->spec.password; while(*szTemp != '\0') { *szTemp = toupper((unsigned char) *szTemp); szTemp++; } NCPErrorCode = ncp_login_conn(_psSessionData->conn, _psSessionData->spec.user, object_type, _psSessionData->spec.password); /* Locate appropriate NCP code message */ pErrorMsg = ncpErrorMsg[0]; /* UNKNOWN_ERROR_CODE */ for (i = 0; i < sizeof(ncpErrorCode)/2; i++) { if (NCPErrorCode == ncpErrorCode[i]) { pErrorMsg = ncpErrorMsg[i]; break; } } switch (NCPErrorCode & 0x0000FFFF) { case 0x0000: /* Success */ (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; break; case 0x89F0: /* Incorrect password - BIND Authenticator */ case 0x89FF: /* Incorrect password - NWE_SERVER_FAILURE */ case 0xFD63: /* Incorrect password - NDS Authenticator */ writeError(ERR_DEBUG_MODULE, "[%s] Incorrect password. Error code: %X", MODULE_NAME, NCPErrorCode); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; break; default: writeError(ERR_DEBUG_MODULE, "[%s] Failed to open connection. Error code: %X", MODULE_NAME, NCPErrorCode); sprintf(ErrorCode, "0x%8.8X:", NCPErrorCode); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strncpy((*psLogin)->pErrorMsg, ErrorCode, strlen(ErrorCode)); strncat((*psLogin)->pErrorMsg, pErrorMsg, strlen(pErrorMsg)); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; break; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBNCP_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBNCP_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the ncpfs headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Are the ncpfs headers and static library installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/nntp.c000066400000000000000000000306721460263104500206200ustar00rootroot00000000000000/* ** NNTP Password Checking Medusa Module ** ** Original AUTHINFO Mode ** http://www.mibsoftware.com/userkt/nntpext/0032.htm ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "nntp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for NNTP sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: nntp.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_NNTP 119 #define PORT_NNTPS 563 typedef struct __MODULE_DATA { int nMode; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(int hSocket, sLogin** psLogin); int terminateConnection(int hSocket); int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M nntp -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[] __attribute__((unused))) { _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if (argc != 0) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_NNTPS; else params.nPort = PORT_NNTP; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } nState = initConnection(hSocket, &psLogin); break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) terminateConnection(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int terminateConnection(int hSocket) { unsigned char bufSend[BUF_SIZE]; memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "QUIT\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); } medusaDisconnect(hSocket); return SUCCESS; } int initConnection(int hSocket, sLogin** psLogin) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Retrieve NNTP server banner */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data. Exiting...", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } else if ((strstr((char*)bufReceive,"200") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] Retrieved NNTP service banner.", MODULE_NAME); } /* 400 Too Many Connections */ else if ((strstr((char*)bufReceive,"400") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] Too many connections from host received by server.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Failed to retrieve NNTP service banner.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } /* Verify that authentication is required */ memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "HELP\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; return MSTATE_EXITING; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_EXITING; } /* 480 Authentication Required */ else if (strstr((char*)bufReceive, "480") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Server requires authentication.", MODULE_NAME); iRet = MSTATE_RUNNING; } else { writeError(ERR_ERROR, "[%s] Server does not appear to require authentication.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } return iRet; } int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* send username */ memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "AUTHINFO USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* 381 More Authentication Required */ else if (strstr((char*)bufReceive,"381") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Receive 381 response requesting user password.", MODULE_NAME); } else { writeError(ERR_DEBUG_MODULE, "[%s] Server did not send a 381 response. Password authentication for user may not be required.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } /* send password */ memset(bufSend, 0, sizeof(bufSend)); if (strlen((char*)szPassword) == 0) sprintf((char*)bufSend, "AUTHINFO PASS \"\"\r\n"); else sprintf((char*)bufSend, "AUTHINFO PASS %.250s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* 281 Authentication accepted */ else if (strstr((char*)bufReceive, "281") != NULL) { writeError(ERR_ERROR, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } /* 482 Authentication rejected */ else if (strstr((char*)bufReceive, "482") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt rejected.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } /* 501 Bad Command Usage */ else if (strstr((char*)bufReceive, "501") != NULL) { writeError(ERR_ERROR, "[%s] Bad command usage.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } /* 502 Authentication Failed */ else if (strstr((char*)bufReceive, "502") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } else { writeError(ERR_ERROR, "[%s] Unknown server response.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_RUNNING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/ntlm.c000066400000000000000000001150161460263104500206070ustar00rootroot00000000000000/* ** NTLM Authentication Protocol Support Functions ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Functions for processing Type-1, Type-2 and Type-3 messages used during ** NTLM authentication. The following document is an excellent resource ** on this topic: ** ** http://davenport.sourceforge.net/ntlm.html ** ** The ntlm.h/.c files combine content from multiple sources into a single ** convenient location. It is based on code contributed to the Hydra ** project by ilo@reversing.org along with analysis of the Fetchmail and ** Samba source. */ /* #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Werror" #pragma GCC diagnostic push #pragma GCC diagnostic warning "-Wall" */ #include #include #include #include #include #include #include "ntlm.h" /* Byte order macros */ #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 */ /* Samba MD4 implementation */ /* 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<>(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; } /* Samba DES implementation */ #define uchar unsigned char #define int16 signed short typedef int BOOL; #define False 0 #define True 1 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>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]; } } /* Samba encryption implementation*/ /**************************************************************************** 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 __attribute__((unused))) { return 0; } /******************************************************************* safe string copy into a known length string. maxlength does not include the terminating zero. ********************************************************************/ #undef DEBUG #define DEBUG(level, s) do { printf s; } while (0) 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 } /* libtnlm copyrigth was left here, anyway the interface was slightly modified */ /* included libntlm-3.2.9 (c) even if this code is based in 2.1 version*/ /* Libntlm AUTHORS -- information about the authors Copyright (C) 2002, 2003, 2004 Simon Josefsson See the end for copying conditions. Grant Edwards Original author of libntlm Andrew Tridgell Wrote functions borrowed from SMB. Simon Josefsson Build environment, maintainer. Frediano Ziglio Contributed LGPL versions of some of the GPL'd Samba files. */ /* 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<(signed int)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<(signed int)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; } /* Generate a Type-1 NTLM message */ void buildAuthRequest(tSmbNtlmAuthRequest *request, long flags, char *host, char *domain) { char *h = NULL; char *p = NULL; if (host == NULL) host = ""; if (domain == NULL) domain = ""; h = strdup(host); p = strchr(h,'@'); if (p) { if (!domain) domain = p+1; *p = '\0'; } if (flags ==0) flags = 0x0000b207; /* Lowest security options to avoid negotiation */ request->bufIndex = 0; memcpy(request->ident,"NTLMSSP\0\0\0",8); SIVAL(&request->msgType,0,1); SIVAL(&request->flags,0,flags); assert(strlen(host) < 128); AddString(request,host,h); assert(strlen(domain) < 128); AddString(request,domain,domain); free(h); } /* Process Type-2 message and generate Type-3 NTLM/NTLM2 response*/ void buildAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, long flags, char *user, char *password, char *domainname, char *host) { uint8 lmRespData[24]; uint8 ntRespData[24]; /* The NTLM2 client nonce is typically a random 8-byte value. Ours is less random. */ uint8 clientNonce[8] = { 0x2E, 0x46, 0x4F, 0x4F, 0x46, 0x55, 0x53, 0x2E }; uint8 sessionHash[8]; char *u = strdup(user); char *p = strchr(u,'@'); char *w = NULL; char *d = strdup(GetUnicodeString(challenge,uDomain)); char *domain = d; writeError(ERR_INFO, "NTLM Authentication Challenge - Ident: %s", challenge->ident); writeError(ERR_INFO, "NTLM Authentication Challenge - mType: %d", IVAL(&challenge->msgType,0)); writeError(ERR_INFO, "NTLM Authentication Challenge - Domain: %s", GetUnicodeString(challenge,uDomain)); writeError(ERR_INFO, "NTLM Authentication Challenge - Flags: %08x", IVAL(&challenge->flags,0)); writeErrorBin(ERR_INFO, "NTLM Authentication Challenge - Challenge:", (unsigned char *)challenge->challengeData, 8); if (domainname != NULL) domain = domainname; if (host == NULL) host = ""; w = strdup(host); if (p) { domain = p+1; *p = '\0'; } /* NTLM2 Session Response http://davenport.sourceforge.net/ntlm.html#theNtlm2SessionResponse 0x00080000 - Negotiate NTLM2 key Indicates that the NTLM2 signing and sealing scheme should be used for protecting authenticated communications. Note that this refers to a particular session security scheme, and is not related to the use of NTLMv2 authentication. This flag can, however, have an effect on the response calculations */ if (challenge->flags & 0x00080000) { EVP_MD_CTX *Md5Ctx; unsigned char *md5_digest; unsigned int md5_digest_len = 16; /* MD5_Init */ Md5Ctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(Md5Ctx, EVP_md5(), NULL); /* MD5_Update */ EVP_DigestUpdate(Md5Ctx, challenge->challengeData, 8); EVP_DigestUpdate(Md5Ctx, clientNonce, 8); /* MD5_Final */ md5_digest = (unsigned char *)OPENSSL_malloc(md5_digest_len); EVP_DigestFinal_ex(Md5Ctx, md5_digest, &md5_digest_len); EVP_MD_CTX_free(Md5Ctx); /* session nonce (md5_digest) is truncated to 8 bytes to form the NTLM2 session hash */ memcpy(sessionHash, md5_digest, 8); memcpy(lmRespData, clientNonce, 8); SMBNTencrypt((unsigned char*)password, sessionHash, ntRespData); } else { SMBencrypt((unsigned char*)password, challenge->challengeData, lmRespData); SMBNTencrypt((unsigned char*)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); assert(strlen(domain) < 128); AddUnicodeString(response,uDomain,domain); assert(strlen(u) < 128); AddUnicodeString(response,uUser,u); assert(strlen(w) < 128); AddUnicodeString(response,uWks,w); AddString(response,sessionKey,NULL); if (flags != 0) challenge->flags = flags; /* Overide flags! */ response->flags = challenge->flags; if(d) free(d); if(u) free(u); } /* Debugging functions */ void dumpAuthRequest(tSmbNtlmAuthRequest *request) { fprintf(stderr, "NTLM Request:\n"); fprintf(stderr, " Ident = %s\n", request->ident); fprintf(stderr, " mType = %d\n", IVAL(&request->msgType,0)); fprintf(stderr, " Flags = %08x\n", IVAL(&request->flags,0)); fprintf(stderr, " Host = %s\n", GetString(request,host)); fprintf(stderr, " Domain = %s\n", GetString(request,domain)); } void dumpAuthChallenge(tSmbNtlmAuthChallenge *challenge) { fprintf(stderr, "NTLM Challenge:\n"); fprintf(stderr, " Ident = %s\n", challenge->ident); fprintf(stderr, " mType = %d\n", IVAL(&challenge->msgType,0)); fprintf(stderr, " Domain = %s\n", GetUnicodeString(challenge,uDomain)); fprintf(stderr, " Flags = %08x\n", IVAL(&challenge->flags,0)); fprintf(stderr, " Challenge = "); dumpRaw(stderr, challenge->challengeData,8); fprintf(stderr, " Incomplete!! parse optional parameters\n"); } void dumpAuthResponse(tSmbNtlmAuthResponse *response) { fprintf(stderr, "NTLM Response:\n"); fprintf(stderr, " Ident = %s\n", response->ident); fprintf(stderr, " mType = %d\n", IVAL(&response->msgType,0)); fprintf(stderr, " LmResp = "); DumpBuffer(stderr, response,lmResponse); fprintf(stderr, " NTResp = "); DumpBuffer(stderr, response,ntResponse); fprintf(stderr, " Domain = %s\n", GetUnicodeString(response,uDomain)); fprintf(stderr, " User = %s\n", GetUnicodeString(response,uUser)); fprintf(stderr, " Wks = %s\n", GetUnicodeString(response,uWks)); fprintf(stderr, " sKey = "); DumpBuffer(stderr, response,sessionKey); fprintf(stderr, " Flags = %08x\n", IVAL(&response->flags,0)); } /* #pragma GCC diagnostic pop #pragma GCC diagnostic pop */ jmk-foofus-medusa-dd62069/src/modsrc/ntlm.h000066400000000000000000000070431460263104500206140ustar00rootroot00000000000000/* ** NTLM Authentication Protocol Support Functions ** ** ------------------------------------------------------------------------ ** Copyright (C) 2008 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Functions for processing Type-1, Type-2 and Type-3 messages used during ** NTLM authentication. The following document is an excellent resource ** on this topic: ** ** http://davenport.sourceforge.net/ntlm.html ** ** The ntlm.h/.c files combine content from multiple sources into a single ** convenient location. It is based on code contributed to the Hydra ** project (ilo@reversing.org) along with analysis of the Fetchmail and ** Samba source. */ #ifndef _MEDUSA_NTLM_H_ #define _MEDUSA_NTLM_H_ #include #include "../medusa-trace.h" /* These structures are byte-order dependant, and should not be manipulated except by the use of the routines provided */ typedef unsigned short uint16; typedef unsigned int uint32; typedef unsigned char uint8; typedef struct { uint16 len; uint16 maxlen; uint32 offset; } tSmbStrHeader; typedef struct { char ident[8]; uint32 msgType; uint32 flags; tSmbStrHeader host; 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) /* A flags value of 0 selects the minimum security level. Host and domain values are optional and can be set to NULL. */ void buildAuthRequest(tSmbNtlmAuthRequest *request, long flags, char *host, char *domain); /* Generates a Type-3 response for a given Type-2 request (challenge) and user credentials. If the user defines the optional parameters (flags, host, and domain), these values will superseed what the server specified. Leave the values set to 0 and NULL to use the server specified values. */ void buildAuthResponse(tSmbNtlmAuthChallenge *challenge, tSmbNtlmAuthResponse *response, long flags, char *user, char *password, char *domain, char *host); /* Debugging Functions */ void dumpAuthRequest(tSmbNtlmAuthRequest *request); void dumpAuthChallenge(tSmbNtlmAuthChallenge *challenge); void dumpAuthResponse(tSmbNtlmAuthResponse *response); #endif jmk-foofus-medusa-dd62069/src/modsrc/pcanywhere.c000066400000000000000000000512411460263104500220010ustar00rootroot00000000000000/* ** PcAnywhere Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** pcaEncrypt() based on code from: ** Hydra 5.0 [David Maciejak ] ** ** Based on packet captures from: ** Server Version 10.5.1 ** Client 10.0.2 ** ** PCA Authentication Methods: ** ADS (Active Directory Services) [1] ** FTP [2] ** HTTP [2] ** HTTPS [2] ** Microsoft LDAP [2] ** Netscape LDAP [2] ** Novell LDAP [2] ** NT [1] ** pcAnywhere [1] ** Windows [3] ** ** [1] Verified working ** [2] Untested ** [3] Verified to work when PcAnywhere host authenticates against domain accounts. ** Authentication fails for local accounts with both the module and the PcAnywhere ** client. Not sure what's going on... ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "pcanywhere.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for PcAnywhere sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: pcanywhere.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define PORT_PCA 5631 #define BUF_SIZE 300 typedef struct __PCA_DATA { char domain[17]; } _PCA_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _PCA_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _PCA_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "NOTE: PcAnywhere allows only one connection at a time. Running multiple threads per target"); writeVerbose(VB_NONE, " may not work well."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DOMAIN:?"); writeVerbose(VB_NONE, " Option allows manual setting of domain to check against when host uses NT authentication."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M pcanywhere -m DOMAIN:FOODOM\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _PCA_DATA *psSessionData; psSessionData = malloc(sizeof(_PCA_DATA)); memset(psSessionData, 0, sizeof(_PCA_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; idomain, pOpt, 16); memset(psSessionData->domain + strlen(psSessionData->domain) + 1, 0x5C, 1); // '\' } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } FREE(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _PCA_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int nFirstPass = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_PCA; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); /* When not running in debug mode, we are failing to get the initial prompt from the server on connections after our initial attempt. Using the following sleep seems to fix the issue. Not sure if there is a disconnect command or something that we could send the server to make this a non-issue. */ if (nFirstPass != 0) sleep(1); nFirstPass = 1; if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ /* encrypt/decrypt: Symantec 31337 Crypto */ void pcaEncrypt(char *plaintext, char *ciphertext, int key, int offset) { unsigned int i; writeError(ERR_DEBUG_MODULE, "pcaEncrypt [plaintext]: %s", plaintext); if (strlen(plaintext) > 0) { ciphertext[0] = plaintext[0] ^ key; for (i = 1; i < strlen(plaintext); i++) ciphertext[i] = ciphertext[i-1] ^ plaintext[i] ^ (i - offset); } writeError(ERR_DEBUG_MODULE, "pcaEncrypt [ciphertext]: %s", ciphertext); } int pcaUserAuth(int hSocket, char* szDomain, char* szLogin, char* szPassword) { unsigned char bufSend[MAX_BUF]; int nSendBufferSize = 0; unsigned char bufSend1[] = { 0x6f, 0x62, 0x01, 0x02, 0x00, 0x00, 0x00 }; int nSendBufferSize1 = 7; unsigned char* bufReceive; int nReceiveBufferSize = 0; char* szTmp; char clogin[128]=""; char cpass[128]=""; /* retrieve logon prompt */ // SEND: 6f 62 01 02 00 00 00 // RECV: 00 7d 08 // RECV: 00 7c 08 20 0d 0a 45 6e 74 65 72 20 6c 6f 67 69 6e 20 6e 61 6d 65 3a 20 writeError(ERR_DEBUG_MODULE, "%s: Retrieving login prompt.", MODULE_NAME); if (medusaSend(hSocket, bufSend1, nSendBufferSize1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } /* When not running in debug mode, we are failing to get the login prompt from the server. Using the following sleep seems to fix the issue. This is probably just hiding some bug in the module code... */ sleep(1); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr((char*)bufReceive + 6, "Enter login name:")) { writeError(ERR_INFO, "%s: Host sent native PcAnywhere authentication prompt.", MODULE_NAME); pcaEncrypt(szLogin, clogin, 0xAB, 1); pcaEncrypt(szPassword, cpass, 0xAB, 1); memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(clogin); strncpy((char*)bufSend + 2, clogin, BUF_SIZE - 3); nSendBufferSize = strlen(clogin) + 2; } else if (strstr((char*)bufReceive + 6, "Enter user name:")) { writeError(ERR_INFO, "%s: Host sent NT authentication prompt.", MODULE_NAME); if (strlen(szDomain) > 0) { // FOODOM\administrator //0000001C 06 . //0000001D 14 ed a2 ec aa e6 af f6 91 f2 97 f7 93 f1 8e f7 ........ ........ //0000002D 8b e5 81 ff 9f ..... szTmp = malloc(strlen(szDomain) + 1 + strlen(szLogin) + 1); memset(szTmp, 0, strlen(szDomain) + 1 + strlen(szLogin) + 1); strcpy(szTmp, szDomain); strcat(szTmp, "\\"); strcat(szTmp, szLogin); pcaEncrypt(szTmp, clogin, 0xAB, 1); writeError(ERR_DEBUG_MODULE, "%s: Setting domain\\user value: %s", MODULE_NAME, szTmp); FREE(szTmp); memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(clogin); strncpy((char*)bufSend + 2, clogin, BUF_SIZE - 3); nSendBufferSize = strlen(clogin) + 2; } else { pcaEncrypt(szLogin, clogin, 0xF7, 0); memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(clogin) + 1; bufSend[2] = 0xf7; strncpy((char*)bufSend + 3, clogin, BUF_SIZE - 4); nSendBufferSize = strlen(clogin) + 3; } pcaEncrypt(szPassword, cpass, 0xAB, 1); } else if (bufReceive + 6) { writeError(ERR_ERROR, "%s: Server responded with unknown login prompt: %s", MODULE_NAME, bufReceive + 6); FREE(bufReceive); return FAILURE; } else { writeError(ERR_ERROR, "%s: Server failed to respond with login prompt.", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* send username */ writeError(ERR_DEBUG_MODULE, "%s: Sending username.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } /* retrieve password prompt */ // RECV: 00 3a 08 20 0d 0a 45 6e 74 65 72 20 70 61 73 73 77 6f 72 64 3a 20 // SEND: 2 + strlen(login) bytes nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr((char*)bufReceive + 6, "Enter password:")) { writeError(ERR_DEBUG_MODULE, "%s: Retrieved \"Enter password:\"", MODULE_NAME); } else { writeError(ERR_ERROR, "%s: Server did not send: \"Enter password:\"", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* send encrypted password */ memset(bufSend, 0, BUF_SIZE); bufSend[0] = 0x06; bufSend[1] = strlen(cpass); strncpy((char*)bufSend + 2, cpass, BUF_SIZE - 3); nSendBufferSize = strlen(cpass) + 2; writeError(ERR_DEBUG_MODULE, "%s: Sending password.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } int pcaNegCrypt(int hSocket) { unsigned char bufSend[] = { 0x6f, 0x61, 0x00, 0x09, 0x00, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }; int nSendBufferSize = 14; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Testing encryption level. Only the default is currently supported. */ // SEND: 6f 61 00 09 00 fe 00 00 ff ff 00 00 00 00 // RECV: 1b 62 00 02 00 00 00 writeError(ERR_DEBUG_MODULE, "%s: Checking encryption level.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if (strstr((char*)bufReceive + 28, "Host is denying connection")) { writeError(ERR_ERROR, "%s: PcAnywhere host denied connection. Host requires encryption which is currently not supported.", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); return SUCCESS; } int pcaSessionInit(int hSocket) { unsigned char bufSend1[] = { 0x00, 0x00, 0x00, 0x00 }; int nSendBufferSize1 = 4; unsigned char bufSend2[] = { 0x6f, 0x06, 0xff }; int nSendBufferSize2 = 3; unsigned char* bufReceive; int nReceiveBufferSize = 0; /* Initial connection. Retrieve PCA banner */ // SEND: 00 00 00 00 // RECV: 50 6c 65 61 73 65 20 70 72 65 73 73 20 3c 45 6e 74 65 72 3e 2e 2e 2e 0d 0a writeError(ERR_DEBUG_MODULE, "%s: Retrieving RCA banner.", MODULE_NAME); if (medusaSend(hSocket, bufSend1, nSendBufferSize1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { /* can we not perform more than a single thread per host? */ writeError(ERR_ERROR, "%s: Failed to retrieve host banner. Is someone currently connected via PcAnywhere?", MODULE_NAME); return FAILURE; } else if (strstr((char*)bufReceive + 11, "Please press ...")) { writeError(ERR_DEBUG_MODULE, "%s: Retrieved \"Please press ...\"", MODULE_NAME); } else { writeError(ERR_ERROR, "%s: Server did not send: \"Please press ...\"", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); /* Unknown negotiation */ // SEND: 6f 06 ff // RECV: 78 02 1b 61 01 09 00 ff 00 00 ff 00 00 00 00 00 writeError(ERR_DEBUG_MODULE, "%s: Sending unknown packet.", MODULE_NAME); if (medusaSend(hSocket, bufSend2, nSendBufferSize2, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _PCA_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; unsigned char* bufReceive; int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "%s: Initializing PcAnywhere connection.", MODULE_NAME); iRet = pcaSessionInit(hSocket); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to initialize PcAnywhere connection.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } writeError(ERR_DEBUG_MODULE, "%s: Negotiating encryption level.", MODULE_NAME); iRet = pcaNegCrypt(hSocket); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to negotiate encryption level.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } /* check if authentication was successful */ // RECV: (success) // XX XX 1b 49 00 50 6a 6d 6b 00 00 00 00 00 00 00 .M.I.Pjmk....... // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ // 00 00 00 00 0f 00 00 00 00 00 00 00 58 50 43 4c ............XPCL // 49 45 4e 54 30 31 00 00 00 00 00 00 00 00 00 00 IENT01.......... // 00 00 00 00 00 00 00 00 00 00 00 00 05 00 36 83 ..............6. // 33 0a 00 00 00 00 14 3...... // RECV: (failure) // XX XX 0d 0a 00 7b 08 49 6e 76 61 6c 69 64 20 6c .....{.Invalid l // 6f 67 69 6e 2e 20 50 6c 65 61 73 65 20 74 72 79 ogin. Please try // 20 61 67 61 69 6e 2e again. writeError(ERR_DEBUG_MODULE, "%s: Attempting PcAnywhere user authentication.", MODULE_NAME); iRet = pcaUserAuth(hSocket, _psSessionData->domain, szLogin, szPassword); if (iRet == FAILURE) { writeError(ERR_ERROR, "%s: Failed to send authentication information to PcAnywhere host.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; return FAILURE; } else if (strstr((char*)bufReceive + 5, "Invalid login") || strstr((char*)bufReceive + 6, "Enter password")) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); writeError(ERR_INFO, "%s : Machine name: %s Current logged on user: %s.", MODULE_NAME, bufReceive + 42, bufReceive + 4); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/pop3.c000066400000000000000000000771141460263104500205240ustar00rootroot00000000000000/* ** POP3 Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "pop3.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for POP3 sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: pop3.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define BUF_SIZE 300 #define PORT_POP3 110 #define PORT_POP3S 995 #define MODE_NORMAL 0 #define MODE_AS400 1 #define AUTH_UNKNOWN 0 #define AUTH_USER 1 #define AUTH_PLAIN 2 #define AUTH_LOGIN 3 #define AUTH_NTLM 4 typedef struct __MODULE_DATA { int nMode; int nAuthType; char* szDomain; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int getAuthType(int hSocket, _MODULE_DATA* _psSessionData); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " MODE:? (NORMAL, AS400) [optional]"); writeVerbose(VB_NONE, " Sets the mode for error detection."); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (USER/PLAIN/LOGIN/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " Module will query service for accepted methods via an \"AUTH\" request."); writeVerbose(VB_NONE, " USER (clear-text), SASL PLAIN, SASL LOGIN, and SASL NTLM authentication methods are supported."); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, " AUTH USER - Appends domain to username (e.g. user@domain.com)."); writeVerbose(VB_NONE, " AUTH NTLM - Supplies specified domain during NTLM authentication. The default"); writeVerbose(VB_NONE, " behaviour is to use the server supplied domain value."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: "); writeVerbose(VB_NONE, " \"medusa -M pop3 -m MODE:AS400 -U accounts.txt -p password\""); writeVerbose(VB_NONE, " \"medusa -M pop3 -m DOMAIN:foo.com -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 3)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inMode = MODE_AS400; else writeError(ERR_WARNING, "Invalid value for method MODE."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "USER") == 0) psSessionData->nAuthType = AUTH_USER; else if (strcmp(pOpt, "PLAIN") == 0) psSessionData->nAuthType = AUTH_PLAIN; else if (strcmp(pOpt, "LOGIN") == 0) psSessionData->nAuthType = AUTH_LOGIN; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = strdup(pOpt); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive; int nReceiveBufferSize = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_POP3S; else params.nPort = PORT_POP3; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* establish initial connection */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "%s failed: Server did not respond with '+OK'. Exiting...", MODULE_NAME); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; } /* POP3 STARTTLS Extension http://www.faqs.org/rfcs/rfc2595.html */ /* The capability name "STLS" indicates this command is present and permitted in the current state. "CAPA" can be used to test for its presence. Are there cases where "STLS" may not be implemented? */ /* Initiate STLS only if we don't already have a SSL connection */ if (psLogin->psServer->psHost->iUseSSL == 0) { memset(bufSend, 0, BUF_SIZE); sprintf((char*)bufSend, "STLS\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; if (medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received: %s", MODULE_NAME, bufReceive); return FAILURE; } /* [SUPPORTED] +OK Begin TLS negotiation / +OK Ready to start TLS [NOT SUPPORTED] +OK STLS completed [ERROR] -ERR Command not permitted when TLS active */ else if (strstr((char*)bufReceive, "+OK") != NULL) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Starting TLS negotiation.", MODULE_NAME); if (medusaConnectSocketSSL(¶ms, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); return FAILURE; } } else { writeError(ERR_DEBUG_MODULE, "[%s] TLS negotiation not available.", MODULE_NAME); FREE(bufReceive); } } /* Query service for accepted authentication methods */ if (_psSessionData->nAuthType == AUTH_UNKNOWN) { getAuthType(hSocket, _psSessionData); if (_psSessionData->nAuthType == AUTH_UNKNOWN) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } break; case MSTATE_RUNNING: /* The POP3 service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. At that point the connection should be reestablished. */ if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int getAuthType(int hSocket, _MODULE_DATA* _psSessionData) { unsigned char* bufReceive; unsigned char* bufSend; int nReceiveBufferSize = 0; bufSend = malloc(6 + 1); memset(bufSend, 0, 6 + 1); sprintf((char*)bufSend, "CAPA\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n\\.*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Server did not respond that it supported any of the authentication types we handle (USER, LOGIN, and NTLM). Use the AUTH module option to force the use of an authentication type: %s", MODULE_NAME, bufReceive); return FAILURE; } else if ((strstr((char*)bufReceive, "USER") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: USER (clear-text)"); _psSessionData->nAuthType = AUTH_USER; } else if ((strstr((char*)bufReceive, "SASL") != NULL)) { if ((strstr((char*)bufReceive, "PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: SASL PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr((char*)bufReceive, "LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: SASL LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr((char*)bufReceive, "NTLM") != NULL)) { writeError(ERR_DEBUG_MODULE, "Server requested authentication type: SASL NTLM"); _psSessionData->nAuthType = AUTH_NTLM; } else { writeError(ERR_ERROR, "[%s] Server requested unsupported SASL method.", MODULE_NAME); return FAILURE; } } else if ((strstr((char*)bufReceive, "-ERR") != NULL)) { writeError(ERR_ERROR, "[%s] Server did not understand CAPA request. Defaulting to USER authentication type, use \"-m AUTH\" option to specify alternative method.", MODULE_NAME); _psSessionData->nAuthType = AUTH_USER; } return SUCCESS; } int sendAuthUSER(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char bufSend[BUF_SIZE]; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nRet = FAILURE; writeError(ERR_DEBUG_MODULE, "[%s] Initiating USER (clear-text) Authentication Attempt.", MODULE_NAME); /* send username */ memset(bufSend, 0, sizeof(bufSend)); if (_psSessionData->szDomain) sprintf((char*)bufSend, "USER %.100s@%.150s\r\n", szLogin, _psSessionData->szDomain); else sprintf((char*)bufSend, "USER %.250s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Failed: Server did not respond as expected to USER authentication attempt: %s", MODULE_NAME, bufReceive); return FAILURE; } else if (strstr((char*)bufReceive, " signing off.")) { writeError(ERR_DEBUG_MODULE, "[%s] Server informed us it was signing off. Restarting connection.", MODULE_NAME); nRet = MSTATE_NEW; return(nRet); } else if (strstr((char*)bufReceive, "ERR Cleartext login on this server requires the use of transport level security (SSL/TLS)")) { writeError(ERR_ERROR, "[%s] Server requires use of SSL/TLS.", MODULE_NAME); return FAILURE; } else if (strstr((char*)bufReceive, "ERR Clear text passwords have been disabled for this protocol.")) { writeError(ERR_ERROR, "[%s] Server does not accept clear-text password authentication.", MODULE_NAME); return FAILURE; } /* send password */ memset(bufSend, 0, sizeof(bufSend)); sprintf((char*)bufSend, "PASS %.250s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* PLAIN SASL Mechanism http://tools.ietf.org/html/rfc5034 http://tools.ietf.org/html/rfc4616 Example: AUTH PLAIN dGVzdAB0ZXN0AHRlc3Q= */ int sendAuthPLAIN(int hSocket, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; char* szTmpBuf = NULL; char* szTmpBuf64 = NULL; int nSendBufferSize = 0; writeError(ERR_DEBUG_MODULE, "[%s] Initiating PLAIN Authentication Attempt.", MODULE_NAME); /* AUTH PLAIN B64(USERNAME\0USERNAME\0PASSWORD) */ nSendBufferSize = strlen(szLogin) + 1 + strlen(szLogin) + 1 + strlen(szPassword); szTmpBuf = malloc(nSendBufferSize + 1); memset(szTmpBuf, 0, nSendBufferSize + 1); strcpy(szTmpBuf, szLogin); strcpy(szTmpBuf + strlen(szLogin) + 1, szLogin); strcpy(szTmpBuf + strlen(szLogin) + 1 + strlen(szLogin) + 1, szPassword); szTmpBuf64 = malloc((2 * nSendBufferSize + 2) + 1); memset(szTmpBuf64, 0, (2 * nSendBufferSize + 2) + 1); base64_encode(szTmpBuf, nSendBufferSize, szTmpBuf64); FREE(szTmpBuf); bufSend = malloc(11 + strlen(szTmpBuf64) + 2 + 1); memset(bufSend, 0, 11 + strlen(szTmpBuf64) + 2 + 1); sprintf((char*)bufSend, "AUTH PLAIN %s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); return SUCCESS; } /* AUTH LOGIN method base64-encodes both prompts and credentials. For example: AUTH LOGIN + VXNlcm5hbWU6 (Username:) Zm9v (foo) + UGFzc3dvcmQ6 (Password:) YmFy (bar) */ int sendAuthLOGIN(int hSocket, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; char* szPrompt = NULL; char* szTmpBuf = NULL; int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "[%s] Initiating LOGIN Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTH LOGIN command --- */ bufSend = malloc(12 + 1); memset(bufSend, 0, 12 + 1); sprintf((char*)bufSend, "AUTH LOGIN\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with a base64-encoded username prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] POP3 server did not respond with \"+ \" to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } else if (strstr((char*)bufReceive,"-ERR The specified authentication package is not supported.") != NULL) { writeError(ERR_ERROR, "[%s] Server response: The specified authentication package is not supported.", MODULE_NAME); return FAILURE; } szTmpBuf = index((char*)bufReceive, '\r'); szTmpBuf[0] = '\0'; szPrompt = malloc(strlen((char*)bufReceive + 2) + 1); memset(szPrompt, 0, strlen((char*)bufReceive + 2) + 1); base64_decode((char*)bufReceive + 2, szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] POP3 server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send username --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ bufSend = malloc((2 * strlen(szLogin) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szLogin) + 2) + 2 + 1); base64_encode(szLogin, strlen(szLogin), (char*)bufSend); strcat((char*)bufSend, "\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } /* Server should respond with a base64-encoded password prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] POP3 server did not respond with \"+ \" to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } szTmpBuf = index((char*)bufReceive, '\r'); szTmpBuf[0] = '\0'; szPrompt = malloc(strlen((char*)bufReceive + 2) + 1); memset(szPrompt, 0, strlen((char*)bufReceive + 2) + 1); base64_decode((char*)bufReceive + 2, szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] POP3 server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send password --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ bufSend = malloc((2 * strlen(szPassword) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szPassword) + 2) + 2 + 1); base64_encode(szPassword, strlen(szPassword), (char*)bufSend); strcat((char*)bufSend, "\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* NTLM POP3 Authentication Based on: http://curl.haxx.se/rfc/ntlm.html#ntlmPop3Authentication http://src.opensolaris.org/source/xref/sfw/usr/src/cmd/fetchmail/fetchmail-6.3.8/README.NTLM */ int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; char* szTmpBuf = NULL; char* szTmpBuf64 = NULL; writeError(ERR_DEBUG_MODULE, "[%s] Initiating NTLM Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTHENTICATE NTLM command --- */ bufSend = malloc(11 + 1); memset(bufSend, 0, 11 + 1); sprintf((char*)bufSend, "AUTH NTLM\r\n"); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with an empty challenge, consisting simply of a "+" */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ *OK.*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] POP3 server did not respond with \"+ OK\" to AUTH NTLM request.", MODULE_NAME); return FAILURE; } FREE(bufReceive); /* --- Send Base-64 encoded Type-1 message --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen((char*)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Server should respond with a Base-64 encoded Type-2 challenge message. The challenge response format is specified by RFC 1730 ("+", followed by a space, followed by the challenge message). */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+ .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Server did not send valid Type-2 challenge response.", MODULE_NAME); return FAILURE; } szTmpBuf = index((char*)bufReceive, '\r'); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, bufReceive + 2); base64_decode((char*)bufReceive + 2, (char *)&sTmpChall); FREE(bufReceive); /* --- Calculate and send Base-64 encoded Type 3 response --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen(szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char*)bufSend, "%s\r\n", szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); /* Server should validate the response and indicate the result of authentication. e.g. +OK User successfully logged on */ return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int nRet = FAILURE; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; switch(_psSessionData->nAuthType) { case AUTH_USER: writeError(ERR_DEBUG_MODULE, "[%s] Sending USER (clear-text) Authentication.", MODULE_NAME); nRet = sendAuthUSER(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_PLAIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending PLAIN Authentication.", MODULE_NAME); nRet = sendAuthPLAIN(hSocket, szLogin, szPassword); break; case AUTH_LOGIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending LOGIN Authentication.", MODULE_NAME); nRet = sendAuthLOGIN(hSocket, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending NTLM Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "\\+OK.*\r\n|-ERR.*\r\n") == FAILURE) || (bufReceive == NULL)) { /* The POP3 service may be configured to drop connections after an arbitrary number of failed logon attempts. We will reuse the established connection to send authentication attempts until that disconnect happens. A default install of Debian (6.0.3 Squeeze) and the Courier Mail Server (0.65) was found to drop connections immediately after the 8th failed attempt. */ if ( medusaCheckSocket(hSocket, (*psLogin)->psServer->psAudit->iSocketWait) ) { writeError(ERR_ERROR, "[%s] Failed: Unexpected or no data received.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; return FAILURE; } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; } } else if (bufReceive[0] == '+') { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "-ERR The specified authentication package is not supported.") != NULL) { writeError(ERR_ERROR, "[%s] Server response: The specified authentication package is not supported.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else { if (_psSessionData->nMode == MODE_AS400) { /* www.venera.com/downloads/Enumeration_of_AS400_users_via_pop3.pdf Example: -ERR Logon attempt invalid CPF2204 */ if (strstr((char*)bufReceive, "CPF2204")) { writeError(ERR_ERROR, "[%s] User profile was not found.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "CPF22E2")) { writeError(ERR_DEBUG_MODULE, "[%s] Valid user, incorrect password.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_NEW; } else if (strstr((char*)bufReceive, "CPF22E3")) { writeError(ERR_ERROR, "[%s] Valid user, but profile is disabled.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "CPF22E4")) { writeError(ERR_ERROR, "[%s] Valid user, but password for profile has expired.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "CPF22E5")) { writeError(ERR_ERROR, "[%s] Valid user, but no password associated with user profile.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char*)bufReceive, "-ERR Logon attempt invalid")) { writeError(ERR_DEBUG_MODULE, "[%s] Generic POP3 invalid attempt message. AS/400 may not be configured for verbose messages.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Unknown AS/400 error message: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } } else { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; //nRet = MSTATE_RUNNING; nRet = MSTATE_NEW; } } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(nRet); } jmk-foofus-medusa-dd62069/src/modsrc/postgres.c000066400000000000000000000245371460263104500215120ustar00rootroot00000000000000/* ** PostgreSQL Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "postgres.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for PostgreSQL sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: postgres.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBPQ_WARNING "No usable LIBPQ. Module disabled." #ifdef HAVE_LIBPQ #include "libpq-fe.h" #define PORT_POSTGRESQL 5432 typedef struct __POSTGRESQL_DATA { char *szDB; } _POSTGRESQL_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(sLogin** login, _POSTGRESQL_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _POSTGRESQL_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DB:? "); writeVerbose(VB_NONE, " Sets target database name."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M postgres -m DB:some_db\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _POSTGRESQL_DATA *psSessionData; psSessionData = malloc(sizeof(_POSTGRESQL_DATA)); memset(psSessionData, 0, sizeof(_POSTGRESQL_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDB = strdup(pOpt); } else writeError(ERR_WARNING, "Method DB requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _POSTGRESQL_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_POSTGRESQL; initConnectionParams(psLogin, ¶ms); /* set database name, if not specified by user */ if (_psSessionData->szDB == NULL) { _psSessionData->szDB = malloc(10); memset(_psSessionData->szDB, 0, 10); sprintf(_psSessionData->szDB, "template1"); } writeError(ERR_DEBUG_MODULE, "[%s] Set database name: %s", MODULE_NAME, _psSessionData->szDB); while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(&psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(sLogin** psLogin, _POSTGRESQL_DATA* _psSessionData, char* szLogin, char* szPassword) { char *szConnectionString; int iRet; szConnectionString = malloc(strlen((*psLogin)->psServer->pHostIP) + strlen(szLogin) + strlen(szPassword) + strlen(_psSessionData->szDB) + 47); memset(szConnectionString, 0, strlen((*psLogin)->psServer->pHostIP) + strlen(szLogin) + strlen(szPassword) + strlen(_psSessionData->szDB) + 47); sprintf(szConnectionString, "host = '%s' dbname = '%s' user = '%s' password = '%s' ", (*psLogin)->psServer->pHostIP, _psSessionData->szDB, szLogin, szPassword); if (PQstatus(PQconnectdb(szConnectionString)) == CONNECTION_OK) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } setPassResult((*psLogin), szPassword); free(szConnectionString); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBPQ_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBPQ_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBPQ installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBPQ installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/rdp.c000066400000000000000000000450621460263104500204250ustar00rootroot00000000000000/* ** RDP Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2015 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** FreeRDP/client/Sample/freerdp.c * FreeRDP: A Remote Desktop Protocol Implementation * FreeRDP Test UI * Copyright 2011 Marc-Andre Moreau ** */ #include #include #include #include #include #include "module.h" #include #include #include #define MODULE_NAME "rdp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for RDP (Microsoft Terminal Server) sessions" #define MODULE_VERSION "0.2" #define MODULE_VERSION_SVN "$Id: ssh.c 1403 2010-09-01 21:41:00Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define PORT_RDP 3389 #define NTLM_HASH_BLANK "31D6CFE0D16AE931B73C59D7E0C089C0" typedef struct __MODULE_DATA { char* szDomain; int isPassTheHash; int isBlankPassword; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(_MODULE_DATA* _psSessionData, sLogin** login, freerdp* instance, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); void initWLog(); static BOOL tf_context_new(freerdp* instance, rdpContext* context); static void tf_context_free(freerdp* instance, rdpContext* context); static BOOL tf_begin_paint(rdpContext* context); static BOOL tf_end_paint(rdpContext* context); int tf_pre_connect(freerdp* instance); int tf_post_connect(freerdp* instance); struct tf_context { rdpContext _p; }; typedef struct tf_context tfContext; extern FREERDP_API int freerdp_channels_global_init(void); extern FREERDP_API int freerdp_channels_global_uninit(void); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, " PASS:? (PASSWORD*, HASH)"); writeVerbose(VB_NONE, " PASSWORD: Use normal password."); writeVerbose(VB_NONE, " HASH: Use a NTLM hash rather than a password."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M rdp\""); writeVerbose(VB_NONE, "Usage example: \"-M rdp -m PASS:HASH -u Administrator -p 31D78236327B9619B14ED8EC9AB454C1"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Note: This module does NOT work against Microsoft Windows 2003/XP and earlier."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 2)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDomain = strdup(pOpt); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else if (strcmp(pOpt, "PASS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method PASS requires value to be set."); else if (strcmp(pOpt, "PASSWORD") == 0) psSessionData->isPassTheHash = FALSE; else if (strcmp(pOpt, "HASH") == 0) psSessionData->isPassTheHash = TRUE; else writeError(ERR_WARNING, "Invalid value for method PASS."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; freerdp* instance; wLog *root; /* Retrieve next available credential set to test */ psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME, psLogin->psServer->pHostIP); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* Suppress FreeRDP library FreeRDP output */ root = WLog_GetRoot(); if ((iVerboseLevel <= 5) && (iErrorLevel <= 5)) WLog_SetStringLogLevel(root, "OFF"); else WLog_SetStringLogLevel(root, "INFO"); instance = freerdp_new(); instance->PreConnect = (signed int (*)(struct rdp_freerdp *))tf_pre_connect; instance->PostConnect = (signed int (*)(struct rdp_freerdp *))tf_post_connect; instance->ContextSize = sizeof(tfContext); instance->ContextNew = tf_context_new; instance->ContextFree = tf_context_free; freerdp_context_new(instance); instance->settings->IgnoreCertificate = TRUE; instance->settings->AuthenticationOnly = TRUE; instance->settings->ServerHostname = psLogin->psServer->pHostIP; if (psLogin->psServer->psAudit->iPortOverride > 0) instance->settings->ServerPort = psLogin->psServer->psAudit->iPortOverride; else instance->settings->ServerPort = PORT_RDP; writeError(ERR_DEBUG_MODULE, "Id: %d initialized FreeRDP instance.", psLogin->iId); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(_psSessionData, &psLogin, instance, psCredSet->psUser->pUser, psCredSet->pPass); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); /* FreeRDP session needs to be reset following blank password logon attempt. */ if (_psSessionData->isBlankPassword) { _psSessionData->isBlankPassword = FALSE; nState = MSTATE_NEW; } } break; case MSTATE_EXITING: freerdp_free(instance); nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); freerdp_free(instance); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ static BOOL tf_context_new(freerdp* instance, rdpContext* context) { return TRUE; } static void tf_context_free(freerdp* instance, rdpContext* context) { } static BOOL tf_begin_paint(rdpContext* context) { rdpGdi* gdi = context->gdi; gdi->primary->hdc->hwnd->invalid->null = TRUE; return TRUE; } static BOOL tf_end_paint(rdpContext* context) { rdpGdi* gdi = context->gdi; if (gdi->primary->hdc->hwnd->invalid->null) return TRUE; return TRUE; } int tf_pre_connect(freerdp* instance) { rdpSettings* settings; settings = instance->settings; settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_PATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_OPAQUE_RECT_INDEX] = TRUE; settings->OrderSupport[NEG_DRAWNINEGRID_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIDSTBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIPATBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTISCRBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTIOPAQUERECT_INDEX] = TRUE; settings->OrderSupport[NEG_MULTI_DRAWNINEGRID_INDEX] = TRUE; settings->OrderSupport[NEG_LINETO_INDEX] = TRUE; settings->OrderSupport[NEG_POLYLINE_INDEX] = TRUE; settings->OrderSupport[NEG_MEMBLT_INDEX] = TRUE; settings->OrderSupport[NEG_MEM3BLT_INDEX] = TRUE; settings->OrderSupport[NEG_SAVEBITMAP_INDEX] = TRUE; settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_INDEX_INDEX] = TRUE; settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_SC_INDEX] = TRUE; settings->OrderSupport[NEG_POLYGON_CB_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_SC_INDEX] = TRUE; settings->OrderSupport[NEG_ELLIPSE_CB_INDEX] = TRUE; return TRUE; } int tf_post_connect(freerdp* instance) { if (!gdi_init(instance, PIXEL_FORMAT_XRGB32)) return FALSE; instance->update->BeginPaint = tf_begin_paint; instance->update->EndPaint = tf_end_paint; return TRUE; } int tryLogin(_MODULE_DATA* _psSessionData, sLogin** psLogin, freerdp* instance, char* szLogin, char* szPassword) { int SMBerr; char *pErrorMsg = NULL; char ErrorCode[12]; int nRet; unsigned int i; int old_stderr; int old_stdout; unsigned char *p = NULL; unsigned char *ntlm_hash = NULL; /* Nessus Plugins: smb_header.inc */ /* Note: we are currently only examining the lower 2 bytes of data */ int smbErrorCode[] = { 0xFFFFFFFF, /* UNKNOWN_ERROR_CODE */ 0x00000000, /* STATUS_SUCCESS */ 0xC000000D, /* STATUS_INVALID_PARAMETER */ 0xC000005E, /* STATUS_NO_LOGON_SERVERS */ 0xC000006D, /* STATUS_LOGON_FAILURE */ 0xC000006E, /* STATUS_ACCOUNT_RESTRICTION */ 0xC000006F, /* STATUS_INVALID_LOGON_HOURS */ 0x00C10002, /* STATUS_INVALID_LOGON_HOURS (LM Authentication) */ 0xC0000070, /* STATUS_INVALID_WORKSTATION */ 0x00C00002, /* STATUS_INVALID_WORKSTATION (LM Authentication) */ 0xC0000071, /* STATUS_PASSWORD_EXPIRED */ 0xC0000072, /* STATUS_ACCOUNT_DISABLED */ 0xC000015B, /* STATUS_LOGON_TYPE_NOT_GRANTED */ 0xC000018D, /* STATUS_TRUSTED_RELATIONSHIP_FAILURE */ 0xC0000193, /* STATUS_ACCOUNT_EXPIRED */ 0xC0000199, /* STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT */ 0x00BF0002, /* STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM Authentication) */ 0xC0000224, /* STATUS_PASSWORD_MUST_CHANGE */ 0x00C20002, /* STATUS_PASSWORD_MUST_CHANGE (LM Authentication) */ 0xC0000234, /* STATUS_ACCOUNT_LOCKED_OUT (No LM Authentication Code) */ 0x00050001, /* AS400_STATUS_LOGON_FAILURE */ 0x00000064, /* The machine you are logging onto is protected by an authentication firewall. */ 0xC0000022, /* STATUS_ACCESS_DENIED */ 0xC00000CC, /* STATUS_BAD_NETWORK_NAME */ 0x0002000D /* ERRCONNECT_CONNECT_TRANSPORT_FAILED */ }; char *smbErrorMsg[] = { "UNKNOWN_ERROR_CODE", "STATUS_SUCCESS", "STATUS_INVALID_PARAMETER", "STATUS_NO_LOGON_SERVERS", "STATUS_LOGON_FAILURE", "STATUS_ACCOUNT_RESTRICTION", "STATUS_INVALID_LOGON_HOURS", "STATUS_INVALID_LOGON_HOURS (LM)", "STATUS_INVALID_WORKSTATION", "STATUS_INVALID_WORKSTATION (LM)", "STATUS_PASSWORD_EXPIRED", "STATUS_ACCOUNT_DISABLED", "STATUS_LOGON_TYPE_NOT_GRANTED", "STATUS_TRUSTED_RELATIONSHIP_FAILURE", "STATUS_ACCOUNT_EXPIRED", "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", "STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM)", "STATUS_PASSWORD_MUST_CHANGE", "STATUS_PASSWORD_MUST_CHANGE (LM)", "STATUS_ACCOUNT_LOCKED_OUT", "AS400_STATUS_LOGON_FAILURE", "AUTHENTICATION_FIREWALL_PROTECTION", "STATUS_ACCESS_DENIED", "STATUS_BAD_NETWORK_NAME", "ERRCONNECT_CONNECT_TRANSPORT_FAILED" }; instance->settings->Username = szLogin; /* If the domain is not defined, local accounts are targeted */ if (_psSessionData->szDomain) instance->settings->Domain = _psSessionData->szDomain; /* Pass-the-hash support added to FreeRDP 1.2.x development tree */ if (_psSessionData->isPassTheHash) { /* Extract NTLM hash from PwDump format */ /* [PwDump] D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ p = szPassword; i = 0; while ((*p != '\0') && (i < 1)) { if (*p == ':') i++; p++; } if (*p == '\0') { ntlm_hash = szPassword; } else { ntlm_hash = p; memset(ntlm_hash + 32, '\0', 1); } instance->settings->ConsoleSession = TRUE; instance->settings->RestrictedAdminModeRequired = TRUE; instance->settings->PasswordHash = ntlm_hash; } else instance->settings->Password = szPassword; /* Blank password support FreeRDP does not support blank passwords. It attempts to pull credentials from a local SAM file if a password of length 0 is supplied. We're using pass-the-hash to get around this issue. */ if (strlen(szPassword) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Using pass-the-hash to test blank password.", MODULE_NAME); instance->settings->ConsoleSession = TRUE; instance->settings->RestrictedAdminModeRequired = TRUE; instance->settings->PasswordHash = NTLM_HASH_BLANK; _psSessionData->isBlankPassword = TRUE; } nRet = freerdp_connect(instance); writeError(ERR_DEBUG_MODULE, "[%s] freerdp_connect exit code: %d", MODULE_NAME, nRet); if (nRet == 1) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } else { SMBerr = freerdp_get_last_error(instance->context); /* Locate appropriate SMB code message */ pErrorMsg = smbErrorMsg[0]; /* UNKNOWN_ERROR_CODE */ for (i = 0; i < sizeof(smbErrorCode)/4; i++) { if (SMBerr == (smbErrorCode[i] & 0xFFFFFFFF)) { pErrorMsg = smbErrorMsg[i]; break; } } switch(SMBerr) { case 0x00020014: /* ERRCONNECT_LOGON_FAILURE */ case 0xC000006A: /* STATUS_WRONG_PASSWORD */ case 0xC000006D: /* STATUS_LOGON_FAILURE */ (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; break; case 0xC0000022: /* STATUS_ACCESS_DENIED */ case 0xC0000071: /* STATUS_PASSWORD_EXPIRED */ case 0xC0000072: /* STATUS_ACCOUNT_DISABLED */ case 0xC0000224: /* STATUS_PASSWORD_MUST_CHANGE */ case 0xC000006E: /* STATUS_ACCOUNT_RESTRICTION */ case 0xC0000234: /* STATUS_ACCOUNT_LOCKED_OUT */ case 0xC0000193: /* STATUS_ACCOUNT_EXPIRED */ case 0xC000015B: /* STATUS_LOGON_TYPE_NOT_GRANTED */ case 0x0002000D: /* ERRCONNECT_CONNECT_TRANSPORT_FAILED */ (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; sprintf(ErrorCode, "0x%8.8X:", SMBerr); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strcpy((*psLogin)->pErrorMsg, ErrorCode); strcat((*psLogin)->pErrorMsg, pErrorMsg); nRet = MSTATE_EXITING; break; default: sprintf(ErrorCode, "0x%8.8X:", SMBerr); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strcpy((*psLogin)->pErrorMsg, ErrorCode); strcat((*psLogin)->pErrorMsg, pErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; break; } } setPassResult((*psLogin), szPassword); return(nRet); } jmk-foofus-medusa-dd62069/src/modsrc/rexec.c000066400000000000000000000210431460263104500207370ustar00rootroot00000000000000/* ** REXEC Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "rexec.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for REXEC sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: rexec.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_REXEC 512 #define RECEIVE_DELAY 1000000 /* Response wait time (usec) */ // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[] __attribute__((unused))) { if (argc != 0) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) writeError(ERR_ERROR, "[%s] module asked for REXEC with SSL. Don't know if such a thing exists...\n"); else params.nPort = PORT_REXEC; params.nSourcePort = 1023; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char* bufSend; unsigned char* bufReceive; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* send: 0x00/username/0x00/password/0x00/id/0x00 */ nSendBufferSize = 1 + strlen(szLogin) + 1 + strlen(szPassword) + 1 + 2 + 1; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend + 1, szLogin, strlen(szLogin)); memcpy(bufSend + 1 + strlen(szLogin) + 1, szPassword, strlen(szPassword)); strcpy(bufSend + 1 + strlen(szLogin) + 1 + strlen(szPassword) + 1, "id"); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); nReceiveBufferSize = 0; bufReceive = medusaReceiveRawDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY, RECEIVE_DELAY); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } /* response starts with null */ else if ((nReceiveBufferSize > 1) && (strstr((char *)bufReceive + 1, "uid") != NULL)) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if ((nReceiveBufferSize > 1) && (strstr((char *)bufReceive + 1, "Command ID in library") != NULL)) { writeError(ERR_DEBUG_MODULE, "%s : AS/400 Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/rlogin.c000066400000000000000000000232151460263104500211260ustar00rootroot00000000000000/* ** RLOGIN Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "rlogin.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for RLOGIN sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: rlogin.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_RLOGIN 513 #define RECEIVE_DELAY 1000000 /* Response wait time (usec) */ // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[] __attribute__((unused))) { if (argc != 0) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) writeError(ERR_DEBUG_MODULE, "[%s] module asked for RLOGIN/SSL. Don't know if such a thing exists...\n"); else params.nPort = PORT_RLOGIN; params.nSourcePort = 1023; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char* bufSend; unsigned char* bufReceive; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* send: 0x00/username/0x00/username/0x00/xterm/0x00 */ nSendBufferSize = 1 + strlen(szLogin) + 1 + strlen(szLogin) + 1 + 5 + 1; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend + 1, szLogin, strlen(szLogin)); memcpy(bufSend + 1 + strlen(szLogin) + 1, szLogin, strlen(szLogin)); strcpy(bufSend + 1 + strlen(szLogin) + 1 + strlen(szLogin) + 1, "xterm"); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); nReceiveBufferSize = 0; bufReceive = medusaReceiveRawDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY, RECEIVE_DELAY); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if ((nReceiveBufferSize > 1) && (strstr((char *)bufReceive + 1, "Incorrect") != NULL)) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if ((nReceiveBufferSize > 1) && (strstr((char *)bufReceive + 1, "Password") != NULL)) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt asked for password.", MODULE_NAME); nSendBufferSize = strlen(szPassword) + 1 + 1; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); sprintf((char *)bufSend, "%s\r", szPassword); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRawDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY, RECEIVE_DELAY); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data.", MODULE_NAME); return FAILURE; } else if ((nReceiveBufferSize == 2) || (strstr((char *)bufReceive, "incorrect") != NULL)) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed here.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { /* We can't tell for sure but it wasn't a failure or a password prompt */ writeError(ERR_DEBUG_MODULE, "%s : Login attempt succeeded via password send.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } } else { /* We can't tell for sure but it wasn't a failure or a password prompt */ writeError(ERR_INFO, "%s : Login attempt succeeded via .rhosts", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/rsh.c000066400000000000000000000211741460263104500204320ustar00rootroot00000000000000/* ** RSH Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "rsh.mod" #define MODULE_AUTHOR "pMonkey " #define MODULE_SUMMARY_USAGE "Brute force module for RSH sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: rsh.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_RSH 514 #define RECEIVE_DELAY 1000000 /* Response wait time (usec) */ // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Rsh is a service where you either have .rhosts/hosts.equiv access\nfrom the source host or you don't. Passwords really don't matter.\nSo the best way to use this module is with a single dummy password and a\nlist of users you suspect may have .rhosts/hosts.equiv allows for your source.\nGood luck."); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[] __attribute__((unused))) { if ((argc < 0) || (argc > 3)) { // Show usage information writeError(ERR_ERROR, "%s is expecting 0 parameters, but it was passed %d", MODULE_NAME, argc); } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) writeError(ERR_DEBUG_MODULE, "[%s] module asked for SSL but don't even know if such a thing exists\n"); else params.nPort = PORT_RSH; params.nSourcePort = 1023; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char* bufSend; unsigned char* bufReceive; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* NOTE: No password required for rsh/rlogin */ szPassword = szLogin; /* send: 0x00/username/0x00/username/0x00/id/0x00 */ nSendBufferSize = 1 + strlen(szLogin) + 1 + strlen(szLogin) + 1 + 2 + 1; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend + 1, szLogin, strlen(szLogin)); memcpy(bufSend + 1 + strlen(szLogin) + 1, szLogin, strlen(szLogin)); strcpy(bufSend + 1 + strlen(szLogin) + 1 + strlen(szLogin) + 1, "id"); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); nReceiveBufferSize = 0; bufReceive = medusaReceiveRawDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY, RECEIVE_DELAY); if (bufReceive == NULL) { writeError(ERR_ERROR, "%s failed: medusaReceive returned no data. Exiting...", MODULE_NAME); return FAILURE; } /* response starts with null */ else if ((nReceiveBufferSize > 1) && (strstr((char *)bufReceive + 1, "uid") != NULL)) { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/sha1.c000066400000000000000000000240351460263104500204710ustar00rootroot00000000000000/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* Original Source from: http://www.faqs.org/rfcs/rfc3174.html DESCRIPTION This file implements the Secure Hashing Algorithm 1 as defined in FIPS PUB 180-1 published April 17, 1995. The SHA-1, produces a 160-bit message digest for a given data stream. It should take about 2**n steps to find a message with the same digest as a given message and 2**(n/2) to find any two messages with the same digest, when n is the digest size in bits. Therefore, this algorithm can serve as a means of providing a "fingerprint" for a message. PORTABILITY ISSUES SHA-1 is defined in terms of 32-bit "words". This code uses (included via "sha1.h" to define 32 and 8 bit unsigned integer types. If your C compiler does not support 32 bit unsigned integers, this code is not appropriate. CAVEATS SHA-1 is designed to work with messages less than 2^64 bits long. Although SHA-1 allows a message digest to be generated for messages of any number of bits less than 2^64, this implementation only works with messages with a length that is a multiple of the size of an 8-bit character. CHANGES 2002 by Peter Zaitsev to - fit to new prototypes according to MySQL standard - Some optimizations - All checking is now done in debug only mode - More comments */ typedef unsigned char uint8; typedef unsigned char uchar; typedef unsigned long long int ulonglong; typedef unsigned int uint32; typedef short int16; typedef signed char int8; #include "sha1.h" /* Define the SHA1 circular left shift macro */ #define SHA1CircularShift(bits,word) \ (((word) << (bits)) | ((word) >> (32-(bits)))) /* Local Function Prototyptes */ static void SHA1PadMessage(SHA1_CONTEXT*); static void SHA1ProcessMessageBlock(SHA1_CONTEXT*); /* Initialize SHA1Context SYNOPSIS sha1_reset() context [in/out] The context to reset. DESCRIPTION This function will initialize the SHA1Context in preparation for computing a new SHA1 message digest. RETURN SHA_SUCCESS ok != SHA_SUCCESS sha Error Code. */ const uint32 sha_const_key[5]= { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; int sha1_reset(SHA1_CONTEXT *context) { #ifndef DBUG_OFF if (!context) return SHA_NULL; #endif context->Length = 0; context->Message_Block_Index = 0; context->Intermediate_Hash[0] = sha_const_key[0]; context->Intermediate_Hash[1] = sha_const_key[1]; context->Intermediate_Hash[2] = sha_const_key[2]; context->Intermediate_Hash[3] = sha_const_key[3]; context->Intermediate_Hash[4] = sha_const_key[4]; context->Computed = 0; context->Corrupted = 0; return SHA_SUCCESS; } /* Return the 160-bit message digest into the array provided by the caller SYNOPSIS sha1_result() context [in/out] The context to use to calculate the SHA-1 hash. Message_Digest: [out] Where the digest is returned. DESCRIPTION NOTE: The first octet of hash is stored in the 0th element, the last octet of hash in the 19th element. RETURN SHA_SUCCESS ok != SHA_SUCCESS sha Error Code. */ int sha1_result(SHA1_CONTEXT *context, uint8 Message_Digest[SHA1_HASH_SIZE]) { int i; #ifndef DBUG_OFF if (!context || !Message_Digest) return SHA_NULL; if (context->Corrupted) return context->Corrupted; #endif if (!context->Computed) { SHA1PadMessage(context); /* message may be sensitive, clear it out */ bzero((char*) context->Message_Block,64); context->Length = 0; /* and clear length */ context->Computed = 1; } for (i = 0; i < SHA1_HASH_SIZE; i++) Message_Digest[i] = (int8)((context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ))); return SHA_SUCCESS; } /* Accepts an array of octets as the next portion of the message. SYNOPSIS sha1_input() context [in/out] The SHA context to update message_array An array of characters representing the next portion of the message. length The length of the message in message_array RETURN SHA_SUCCESS ok != SHA_SUCCESS sha Error Code. */ int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array, unsigned length) { if (!length) return SHA_SUCCESS; #ifndef DBUG_OFF /* We assume client konows what it is doing in non-debug mode */ if (!context || !message_array) return SHA_NULL; if (context->Computed) return (context->Corrupted= SHA_STATE_ERROR); if (context->Corrupted) return context->Corrupted; #endif while (length--) { context->Message_Block[context->Message_Block_Index++]= (*message_array & 0xFF); context->Length += 8; /* Length is in bits */ #ifndef DBUG_OFF /* Then we're not debugging we assume we never will get message longer 2^64 bits. */ if (context->Length == 0) return (context->Corrupted= 1); /* Message is too long */ #endif if (context->Message_Block_Index == 64) { SHA1ProcessMessageBlock(context); } message_array++; } return SHA_SUCCESS; } /* Process the next 512 bits of the message stored in the Message_Block array. SYNOPSIS SHA1ProcessMessageBlock() DESCRIPTION Many of the variable names in this code, especially the single character names, were used because those were the names used in the publication. */ /* Constants defined in SHA-1 */ static const uint32 K[]= { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; static void SHA1ProcessMessageBlock(SHA1_CONTEXT *context) { int t; /* Loop counter */ uint32 temp; /* Temporary word value */ uint32 W[80]; /* Word sequence */ uint32 A, B, C, D, E; /* Word buffers */ int index; /* Initialize the first 16 words in the array W */ for (t = 0; t < 16; t++) { index=t*4; W[t] = context->Message_Block[index] << 24; W[t] |= context->Message_Block[index + 1] << 16; W[t] |= context->Message_Block[index + 2] << 8; W[t] |= context->Message_Block[index + 3]; } for (t = 16; t < 80; t++) { W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); } A = context->Intermediate_Hash[0]; B = context->Intermediate_Hash[1]; C = context->Intermediate_Hash[2]; D = context->Intermediate_Hash[3]; E = context->Intermediate_Hash[4]; for (t = 0; t < 20; t++) { temp= SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for (t = 20; t < 40; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for (t = 40; t < 60; t++) { temp= (SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]); E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } for (t = 60; t < 80; t++) { temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; E = D; D = C; C = SHA1CircularShift(30,B); B = A; A = temp; } context->Intermediate_Hash[0] += A; context->Intermediate_Hash[1] += B; context->Intermediate_Hash[2] += C; context->Intermediate_Hash[3] += D; context->Intermediate_Hash[4] += E; context->Message_Block_Index = 0; } /* Pad message SYNOPSIS SHA1PadMessage() context: [in/out] The context to pad DESCRIPTION According to the standard, the message must be padded to an even 512 bits. The first padding bit must be a '1'. The last 64 bits represent the length of the original message. All bits in between should be 0. This function will pad the message according to those rules by filling the Message_Block array accordingly. It will also call the ProcessMessageBlock function provided appropriately. When it returns, it can be assumed that the message digest has been computed. */ static void SHA1PadMessage(SHA1_CONTEXT *context) { /* Check to see if the current message block is too small to hold the initial padding bits and length. If so, we will pad the block, process it, and then continue padding into a second block. */ int i=context->Message_Block_Index; if (i > 55) { context->Message_Block[i++] = 0x80; bzero((char*) &context->Message_Block[i], sizeof(context->Message_Block[0])*(64-i)); context->Message_Block_Index=64; /* This function sets context->Message_Block_Index to zero */ SHA1ProcessMessageBlock(context); bzero((char*) &context->Message_Block[0], sizeof(context->Message_Block[0])*56); context->Message_Block_Index=56; } else { context->Message_Block[i++] = 0x80; bzero((char*) &context->Message_Block[i], sizeof(context->Message_Block[0])*(56-i)); context->Message_Block_Index=56; } /* Store the message length as the last 8 octets */ context->Message_Block[56] = (int8) (context->Length >> 56); context->Message_Block[57] = (int8) (context->Length >> 48); context->Message_Block[58] = (int8) (context->Length >> 40); context->Message_Block[59] = (int8) (context->Length >> 32); context->Message_Block[60] = (int8) (context->Length >> 24); context->Message_Block[61] = (int8) (context->Length >> 16); context->Message_Block[62] = (int8) (context->Length >> 8); context->Message_Block[63] = (int8) (context->Length); SHA1ProcessMessageBlock(context); } jmk-foofus-medusa-dd62069/src/modsrc/sha1.h000066400000000000000000000041321460263104500204720ustar00rootroot00000000000000/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* This is the header file for code which implements the Secure Hashing Algorithm 1 as defined in FIPS PUB 180-1 published April 17, 1995. Many of the variable names in this code, especially the single character names, were used because those were the names used in the publication. Please read the file sha1.c for more information. Modified 2002 by Peter Zaitsev to better follow MySQL standards */ #include enum sha_result_codes { SHA_SUCCESS = 0, SHA_NULL, /* Null pointer parameter */ SHA_INPUT_TOO_LONG, /* input data too long */ SHA_STATE_ERROR /* called Input after Result */ }; #define SHA1_HASH_SIZE 20 /* Hash size in bytes */ /* This structure will hold context information for the SHA-1 hashing operation */ typedef struct SHA1_CONTEXT { ulonglong Length; /* Message length in bits */ uint32 Intermediate_Hash[SHA1_HASH_SIZE/4]; /* Message Digest */ int Computed; /* Is the digest computed? */ int Corrupted; /* Is the message digest corrupted? */ int16 Message_Block_Index; /* Index into message block array */ uint8 Message_Block[64]; /* 512-bit message blocks */ } SHA1_CONTEXT; int sha1_reset(SHA1_CONTEXT *context); int sha1_input(SHA1_CONTEXT *context, const uint8 *message_array, unsigned length); int sha1_result(SHA1_CONTEXT *context, uint8 Message_Digest[SHA1_HASH_SIZE]); jmk-foofus-medusa-dd62069/src/modsrc/smbnt-smb1.c000066400000000000000000001353311460263104500216220ustar00rootroot00000000000000/* ** SMB LAN Manager Password/HASH Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2024 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ */ #include "smbnt.h" #ifdef HAVE_LIBSSL /* Split DOMAIN\USER style usernames */ char* parseFullyQualifiedUsername(_SMBNT_DATA *_psSessionData, char* szLogin) { char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; char *szUser = NULL; if ( strstr(szLogin, "\\") || strstr(szLogin, "\\\\") ) { if ((_psSessionData->accntFlag == NTDOMAIN) || (_psSessionData->accntFlag == OTHER)) { writeError(ERR_NOTICE, "[%s] Using the DOMAIN\\USER format with the GROUP/GROUP_OTHER module options is redundant.", MODULE_NAME); } pOptTmp = strdup(szLogin); writeError(ERR_DEBUG_MODULE, "Processing domain and username: %s", pOptTmp); pOpt = strtok_r(pOptTmp, "\\", &strtok_ptr); strncpy((char *) _psSessionData->workgroup_other, pOpt, 16); writeError(ERR_DEBUG_MODULE, "Processing domain: %s", _psSessionData->workgroup_other); pOpt = strtok_r(NULL, "\\", &strtok_ptr); szUser = strdup(pOpt); writeError(ERR_DEBUG_MODULE, "Processing username: %s", szUser); FREE(pOptTmp); _psSessionData->accntFlag = OTHER; } else { szUser = strdup(szLogin); writeError(ERR_DEBUG_MODULE, "Processing username: %s", szUser); } return szUser; } static unsigned char Get7Bits(unsigned char *input, int startBit) { register unsigned int word; word = (unsigned) input[startBit / 8] << 8; word |= (unsigned) input[startBit / 8 + 1]; word >>= 15 - (startBit % 8 + 7); return word & 0xFE; } /* Make the key */ static void MakeKey(unsigned char *key, unsigned char *des_key) { unsigned char byte; unsigned char parity = 0; des_key[0] = Get7Bits(key, 0); des_key[1] = Get7Bits(key, 7); des_key[2] = Get7Bits(key, 14); des_key[3] = Get7Bits(key, 21); des_key[4] = Get7Bits(key, 28); des_key[5] = Get7Bits(key, 35); des_key[6] = Get7Bits(key, 42); des_key[7] = Get7Bits(key, 49); for (size_t i = 0; i < 8; i++) { byte = des_key[i]; while (byte) { parity ^= byte & 1; byte >>= 1; } /* Set the least significant bit to the opposite of the calculated parity */ des_key[i] = (des_key[i] & 0xFE) | (parity ^ 1); } } /* Do the DesEncryption */ void DesEncrypt(unsigned char *clear, unsigned char *key, unsigned char *cipher) { unsigned char des_key[8]; MakeKey(key, des_key); int len; EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, des_key, NULL); EVP_EncryptUpdate(ctx, cipher, &len, clear, 8); EVP_CIPHER_CTX_free(ctx); } /* HashLM Function: Create a LM hash from the challenge Variables: lmhash = the hash created from this function pass = users password challenge = the challenge received from the server */ int HashLM(_SMBNT_DATA *_psSessionData, unsigned char **lmhash, unsigned char *pass, unsigned char *challenge) { static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; unsigned char password[14 + 1]; unsigned char lm_hash[21]; unsigned char lm_response[24]; int i = 0, j = 0; unsigned char *p = NULL; char HexChar; int HexValue; memset(password, 0, 14 + 1); memset(lm_hash, 0, 21); memset(lm_response, 0, 24); /* Use LM Hash instead of password */ /* D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ if (_psSessionData->hashFlag == HASH) { p = pass; while ((*p != '\0') && (i < 1)) { if (*p == ':') i++; p++; } } /* If "-e ns" was used, don't treat these values as hashes. */ if ((_psSessionData->hashFlag == HASH) && (i >= 1)) { p = pass; if (*p == '\0') { writeError(ERR_ERROR, "Error reading PwDump file."); return FAILURE; } else if (*p == 'N') { writeError(ERR_DEBUG_MODULE, "Found \"NO PASSWORD\" for LM Hash."); /* Generate 16-byte LM hash */ DesEncrypt(magic, &password[0], &lm_hash[0]); DesEncrypt(magic, &password[7], &lm_hash[8]); } else { writeError(ERR_DEBUG_MODULE, "Convert ASCII PwDump LM Hash (%s).", p); for (i = 0; i < 16; i++) { HexValue = 0x0; for (j = 0; j < 2; j++) { HexChar = (char) p[2 * i + j]; if (HexChar > 0x39) HexChar = HexChar | 0x20; /* convert upper case to lower */ if (!(((HexChar >= 0x30) && (HexChar <= 0x39)) || /* 0 - 9 */ ((HexChar >= 0x61) && (HexChar <= 0x66)))) { /* a - f */ writeError(ERR_ERROR, "Error invalid char (%c) for hash.", HexChar); return FAILURE; } HexChar -= 0x30; if (HexChar > 0x09) /* HexChar is "a" - "f" */ HexChar -= 0x27; HexValue = (HexValue << 4) | (char) HexChar; } lm_hash[i] = (unsigned char) HexValue; } } } else { /* Password == Machine Name */ if (_psSessionData->hashFlag == MACHINE_NAME) { for (i = 0; i < 16; i++) { if (_psSessionData->machine_name[i] > 0x39) _psSessionData->machine_name[i] = _psSessionData->machine_name[i] | 0x20; /* convert upper case to lower */ } pass = _psSessionData->machine_name; } /* convert lower case characters to upper case */ strncpy((char *)password, (char *)pass, 14); for (i = 0; i < 14; i++) { if ((password[i] >= 0x61) && (password[i] <= 0x7a)) /* a - z */ password[i] -= 0x20; } /* Generate 16-byte LM hash */ DesEncrypt(magic, &password[0], &lm_hash[0]); DesEncrypt(magic, &password[7], &lm_hash[8]); } /* NULL-pad 16-byte LM hash to 21-bytes Split resultant value into three 7-byte thirds DES-encrypt challenge using each third as a key Concatenate three 8-byte resulting values to form 24-byte LM response */ DesEncrypt(challenge, &lm_hash[0], &lm_response[0]); DesEncrypt(challenge, &lm_hash[7], &lm_response[8]); DesEncrypt(challenge, &lm_hash[14], &lm_response[16]); memcpy(*lmhash, lm_response, 24); return SUCCESS; } /* MakeNTLM Function: Create a NTLM hash from the password */ int MakeNTLM(_SMBNT_DATA *_psSessionData, unsigned char *ntlmhash, unsigned char *pass) { EVP_MD_CTX *md4Context; unsigned int hash_len = 16; unsigned char hash[hash_len]; /* MD4_SIGNATURE_SIZE = 16 */ unsigned char unicodePassword[256 * 2]; /* MAX_NT_PASSWORD = 256 */ unsigned int i = 0, j = 0; int mdlen; unsigned char *p = NULL; unsigned char *ntlm_hash = NULL; char HexChar; int HexValue; unsigned char NO_PASSWORD[1] = ""; /* Use NTLM Hash instead of password */ if (_psSessionData->hashFlag == HASH) { /* [OLD] 1000:D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ /* [NEW] D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ p = pass; while ((*p != '\0') && (i < 1)) { if (*p == ':') i++; p++; } if (*p == '\0') { ntlm_hash = pass; } else { ntlm_hash = p; memset(ntlm_hash + 32, '\0', 1); } } /* If "-e ns" was used, don't treat these values as hashes. */ if ((_psSessionData->hashFlag == HASH)) { if (*ntlm_hash == '\0') { writeError(ERR_ERROR, "Error reading hash or PwDump file."); return FAILURE; } else if (*ntlm_hash == 'N') { writeError(ERR_DEBUG_MODULE, "Found \"NO PASSWORD\" for NTLM Hash."); pass = NO_PASSWORD; /* Initialize the Unicode version of the secret (== password). */ /* This implicitly supports 8-bit ISO8859/1 characters. */ bzero(unicodePassword, sizeof(unicodePassword)); for (i = 0; i < strlen((char *) pass); i++) unicodePassword[i * 2] = (unsigned char) pass[i]; mdlen = strlen((char *) pass) * 2; /* length in bytes */ md4Context = EVP_MD_CTX_new(); EVP_DigestInit_ex(md4Context, EVP_md4(), NULL); EVP_DigestUpdate(md4Context, unicodePassword, mdlen); EVP_DigestFinal_ex(md4Context, hash, &hash_len); EVP_MD_CTX_free(md4Context); } else { writeError(ERR_DEBUG_MODULE, "Convert ASCII PwDump NTLM Hash (%s).", ntlm_hash); for (i = 0; i < 16; i++) { HexValue = 0x0; for (j = 0; j < 2; j++) { HexChar = (char) ntlm_hash[2 * i + j]; if (HexChar > 0x39) HexChar = HexChar | 0x20; /* convert upper case to lower */ if (!(((HexChar >= 0x30) && (HexChar <= 0x39)) || /* 0 - 9 */ ((HexChar >= 0x61) && (HexChar <= 0x66)))) { /* a - f */ writeError(ERR_ERROR, "Error invalid char (%c) for hash.", HexChar); return FAILURE; } HexChar -= 0x30; if (HexChar > 0x09) /* HexChar is "a" - "f" */ HexChar -= 0x27; HexValue = (HexValue << 4) | (char) HexChar; } hash[i] = (unsigned char) HexValue; } } } else { /* Password == Machine Name */ if (_psSessionData->hashFlag == MACHINE_NAME) { for (i = 0; i < 16; i++) { if (_psSessionData->machine_name[i] > 0x39) _psSessionData->machine_name[i] = _psSessionData->machine_name[i] | 0x20; /* convert upper case to lower */ } pass = _psSessionData->machine_name; } /* Initialize the Unicode version of the secret (== password). */ /* This implicitly supports 8-bit ISO8859/1 characters. */ bzero(unicodePassword, sizeof(unicodePassword)); for (i = 0; i < strlen((char *) pass); i++) unicodePassword[i * 2] = (unsigned char) pass[i]; mdlen = strlen((char *) pass) * 2; /* length in bytes */ md4Context = EVP_MD_CTX_new(); EVP_DigestInit_ex(md4Context, EVP_md4(), NULL); EVP_DigestUpdate(md4Context, unicodePassword, mdlen); EVP_DigestFinal_ex(md4Context, hash, &hash_len); EVP_MD_CTX_free(md4Context); } memcpy(ntlmhash, hash, 16); return SUCCESS; } /* HashNTLM Function: Create a NTLM hash from the challenge Variables: ntlmhash = the hash created from this function pass = users password challenge = the challenge received from the server */ int HashNTLM(_SMBNT_DATA *_psSessionData, unsigned char **ntlmhash, unsigned char *pass, unsigned char *challenge) { int ret; unsigned char hash[16]; /* MD4_SIGNATURE_SIZE = 16 */ unsigned char p21[21]; unsigned char ntlm_response[24]; ret = MakeNTLM(_psSessionData, (unsigned char *)&hash, (unsigned char *)pass); if (ret == FAILURE) return FAILURE; memset(p21, '\0', 21); memcpy(p21, hash, 16); DesEncrypt(challenge, p21 + 0, ntlm_response + 0); DesEncrypt(challenge, p21 + 7, ntlm_response + 8); DesEncrypt(challenge, p21 + 14, ntlm_response + 16); memcpy(*ntlmhash, ntlm_response, 24); return SUCCESS; } /* HashLMv2 This function implements the LMv2 response algorithm. The LMv2 response is used to provide pass-through authentication compatibility with older servers. The response is based on the NTLM password hash and is exactly 24 bytes. The below code is based heavily on the following resources: http://davenport.sourceforge.net/ntlm.html#theLmv2Response samba-3.0.28a - libsmb/smbencrypt.c jcifs - packet capture of LMv2-only connection */ int HashLMv2(_SMBNT_DATA *_psSessionData, unsigned char **LMv2hash, unsigned char *szLogin, unsigned char *szPassword) { unsigned char ntlm_hash[16]; unsigned char unicodeUsername[20 * 2]; unsigned char unicodeTarget[256 * 2]; int ret; unsigned int i; unsigned char client_challenge[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }; unsigned char* message; size_t message_len; unsigned char* kr_buf; size_t kr_buf_len = 16; unsigned char* lmv2_response; size_t lmv2_response_len = 16; /* --- HMAC #1 Caculations --- */ /* Calculate and set NTLM password hash */ memset(ntlm_hash, 0, 16); ret = MakeNTLM(_psSessionData, (unsigned char *)&ntlm_hash, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; /* The Unicode uppercase username is concatenated with the Unicode authentication target (the domain or server name specified in the Target Name field of the Type 3 message). Note that this calculation always uses the Unicode representation, even if OEM encoding has been negotiated; also note that the username is converted to uppercase, while the authentication target is case-sensitive and must match the case presented in the Target Name field. The HMAC-MD5 message authentication code algorithm (described in RFC 2104) is applied to this value using the 16-byte NTLM hash as the key. This results in a 16-byte value - the NTLMv2 hash. */ /* Initialize the Unicode version of the username and target. */ /* This implicitly supports 8-bit ISO8859/1 characters. */ /* convert lower case characters to upper case */ bzero(unicodeUsername, sizeof(unicodeUsername)); for (i = 0; i < strlen((char *)szLogin); i++) { if ((szLogin[i] >= 0x61) && (szLogin[i] <= 0x7a)) /* a - z */ unicodeUsername[i * 2] = (unsigned char) szLogin[i] - 0x20; else unicodeUsername[i * 2] = (unsigned char) szLogin[i]; } bzero(unicodeTarget, sizeof(unicodeTarget)); for (i = 0; i < strlen((char *)_psSessionData->workgroup); i++) unicodeTarget[i * 2] = (unsigned char)_psSessionData->workgroup[i]; message_len = 2 * strlen((char *)szLogin) + 2 * strlen((char *)_psSessionData->workgroup); message = malloc(message_len); memset(message, 0, message_len); memcpy(message, unicodeUsername, 2 * strlen((char *)szLogin)); memcpy(message + 2 * strlen((char *)szLogin), unicodeTarget, 2 * strlen((char *)_psSessionData->workgroup)); kr_buf = malloc(kr_buf_len); memset(kr_buf, 0, kr_buf_len); hmac_md5(message, message_len, &kr_buf, &kr_buf_len, ntlm_hash, sizeof(ntlm_hash)); FREE(message); /* --- HMAC #2 Calculations --- */ /* The challenge from the Type 2 message is concatenated with our fixed client nonce. The HMAC-MD5 message authentication code algorithm is applied to this value using the 16-byte NTLMv2 hash (calculated above) as the key. This results in a 16-byte output value. */ message_len = 16; message = malloc(message_len); memset(message, 0, 16); memcpy(message, _psSessionData->challenge, 8); memcpy(message + 8, client_challenge, 8); lmv2_response = malloc(lmv2_response_len); memset(lmv2_response, 0, lmv2_response_len); hmac_md5(message, message_len, &lmv2_response, &lmv2_response_len, kr_buf, kr_buf_len); FREE(kr_buf); /* --- 24-byte LMv2 Response Complete --- */ *LMv2hash = malloc(24); memset(*LMv2hash, 0, 24); memcpy(*LMv2hash, lmv2_response, 16); memcpy(*LMv2hash + 16, client_challenge, 8); FREE(lmv2_response); return SUCCESS; } /* HashNTLMv2 This function implements the NTLMv2 response algorithm. Support for this algorithm was added with Microsoft Windows with NT 4.0 SP4. It should be noted that code doesn't currently work with Microsoft Vista. While NTLMv2 authentication with Samba and Windows 2003 functions as expected, Vista systems respond with the oh-so-helpful "INVALID_PARAMETER" error code. LMv2-only authentication appears to work against Vista in cases where LM and NTLM are refused. The below code is based heavily on the following two resources: http://davenport.sourceforge.net/ntlm.html#theNtlmv2Response samba-3.0.28 - libsmb/smbencrypt.c NTLMv2 network authentication is required when attempting to authenticated to a system which has the following policy enforced: GPO: "Network Security: LAN Manager authentication level" Setting: "Send NTLMv2 response only\refuse LM & NTLM" */ int HashNTLMv2(_SMBNT_DATA *_psSessionData, unsigned char **NTLMv2hash, int *iByteCount, unsigned char *szLogin, unsigned char *szPassword) { unsigned char ntlm_hash[16]; unsigned char ntlmv2_response[56 + 20 * 2 + 256 * 2]; unsigned char unicodeUsername[20 * 2]; unsigned char unicodeTarget[256 * 2]; //HMACMD5Context ctx; unsigned char kr_buf[16]; unsigned int i; int ret, iTargetLen; unsigned char client_challenge[8] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }; /* -- Example NTLMv2 Response Data -- [0] HMAC: (16 bytes) [16] Header: Blob Signature [01 01 00 00] (4 bytes) [20] Reserved: [00 00 00 00] (4 bytes) [24] Time: Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601. (8 bytes) [32] Client Nonce: (8 bytes) [40] Unknown: 00 00 00 00 (4 bytes) [44] Target Information (from the Type 2 message) NetBIOS domain/workgroup: Type: domain 02 00 (2 bytes) Length: 12 00 (2 bytes) Name: WORKGROUP [NULL spacing -> 57 00 4f 00 ...] (18 bytes) End-of-list: 00 00 00 00 (4 bytes) Termination: 00 00 00 00 (4 bytes) */ iTargetLen = 2 * strlen((char *)_psSessionData->workgroup); memset(ntlm_hash, 0, 16); memset(ntlmv2_response, 0, 56 + 20 * 2 + 256 * 2); memset(kr_buf, 0, 16); /* --- HMAC #1 Caculations --- */ /* Calculate and set NTLM password hash */ ret = MakeNTLM(_psSessionData, (unsigned char *)&ntlm_hash, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; /* The Unicode uppercase username is concatenated with the Unicode authentication target (the domain or server name specified in the Target Name field of the Type 3 message). Note that this calculation always uses the Unicode representation, even if OEM encoding has been negotiated; also note that the username is converted to uppercase, while the authentication target is case-sensitive and must match the case presented in the Target Name field. The HMAC-MD5 message authentication code algorithm (described in RFC 2104) is applied to this value using the 16-byte NTLM hash as the key. This results in a 16-byte value - the NTLMv2 hash. */ /* Initialize the Unicode version of the username and target. */ /* This implicitly supports 8-bit ISO8859/1 characters. */ /* convert lower case characters to upper case */ bzero(unicodeUsername, sizeof(unicodeUsername)); for (i = 0; i < strlen((char *)szLogin); i++) { if ((szLogin[i] >= 0x61) && (szLogin[i] <= 0x7a)) /* a - z */ unicodeUsername[i * 2] = (unsigned char) szLogin[i] - 0x20; else unicodeUsername[i * 2] = (unsigned char) szLogin[i]; } bzero(unicodeTarget, sizeof(unicodeTarget)); for (i = 0; i < strlen((char *)_psSessionData->workgroup); i++) unicodeTarget[i * 2] = (unsigned char)_psSessionData->workgroup[i]; /* NTLMv2 disabled, use LMv2. Replace these with hmac_md() if ever trying to fix this. */ //hmac_md5_init_limK_to_64(ntlm_hash, 16, &ctx); //hmac_md5_update((const unsigned char *)unicodeUsername, 2 * strlen((char *)szLogin), &ctx); //hmac_md5_update((const unsigned char *)unicodeTarget, 2 * strlen((char *)_psSessionData->workgroup), &ctx); //hmac_md5_final(kr_buf, &ctx); /* --- Blob Construction --- */ memset(ntlmv2_response + 16, 1, 2); /* Blob Signature 0x01010000 */ memset(ntlmv2_response + 18, 0, 2); memset(ntlmv2_response + 20, 0, 4); /* Reserved */ /* Time -- Take a Unix time and convert to an NT TIME structure: Little-endian, 64-bit signed value representing the number of tenths of a microsecond since January 1, 1601. */ struct timespec ts; unsigned long long nt; ts.tv_sec = (time_t)time(NULL); ts.tv_nsec = 0; if (ts.tv_sec ==0) nt = 0; else if (ts.tv_sec == TIME_T_MAX) nt = 0x7fffffffffffffffLL; else if (ts.tv_sec == (time_t)-1) nt = (unsigned long)-1; else { nt = ts.tv_sec; nt += TIME_FIXUP_CONSTANT_INT; nt *= 1000*1000*10; /* nt is now in the 100ns units */ } SIVAL(ntlmv2_response + 24, 0, nt & 0xFFFFFFFF); SIVAL(ntlmv2_response + 24, 4, nt >> 32); /* End time calculation */ /* Set client challenge - using a non-random value in this case. */ memcpy(ntlmv2_response + 32, client_challenge, 8); /* Client Nonce */ memset(ntlmv2_response + 40, 0, 4); /* Unknown */ /* Target Information Block */ /* 0x0100 Server name 0x0200 Domain name 0x0300 Fully-qualified DNS host name 0x0400 DNS domain name TODO: Need to rework negotiation code to correctly extract target information */ memset(ntlmv2_response + 44, 0x02, 1); /* Type: Domain */ memset(ntlmv2_response + 45, 0x00, 1); memset(ntlmv2_response + 46, iTargetLen, 1); /* Length */ memset(ntlmv2_response + 47, 0x00, 1); /* Name of domain or workgroup */ for (i = 0; i < strlen((char *)_psSessionData->workgroup); i++) ntlmv2_response[48 + i * 2] = (unsigned char)_psSessionData->workgroup[i]; memset(ntlmv2_response + 48 + iTargetLen, 0, 4); /* End-of-list */ /* --- HMAC #2 Caculations --- */ /* The challenge from the Type 2 message is concatenated with the blob. The HMAC-MD5 message authentication code algorithm is applied to this value using the 16-byte NTLMv2 hash (calculated above) as the key. This results in a 16-byte output value. */ /* NTLMv2 disabled, use LMv2. Replace these with hmac_md() if ever trying to fix this. */ //hmac_md5_init_limK_to_64(kr_buf, 16, &ctx); //hmac_md5_update(_psSessionData->challenge, 8, &ctx); //hmac_md5_update(ntlmv2_response + 16, 48 - 16 + iTargetLen + 4, &ctx); //hmac_md5_final(ntlmv2_response, &ctx); *iByteCount = 48 + iTargetLen + 4; *NTLMv2hash = malloc(*iByteCount); memset(*NTLMv2hash, 0, *iByteCount); memcpy(*NTLMv2hash, ntlmv2_response, *iByteCount); return SUCCESS; } /* NBS Session Request Function: Request a new session from the server Returns: TRUE on success else FALSE. */ int NBSSessionRequest(int hSocket, _SMBNT_DATA* _psSessionData) { char nb_name[32]; /* netbiosname */ char nb_local[32]; /* netbios localredirector */ unsigned char rqbuf[7] = { 0x81, 0x00, 0x00, 0x48, 0x20, 0x00, 0x20 }; unsigned char *buf = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int i = 0; /* if we are running in native mode (aka port 445) don't do netbios */ if (_psSessionData->protoFlag == WIN2000_NATIVEMODE) return 0; /* convert computer name to netbios name -- https://support.microsoft.com/kb/194203 */ memset(nb_name, 0, 32); memset(nb_local, 0, 32); if (_psSessionData->machine_name[0] == 0x00) { writeVerbose(VB_GENERAL, "%s: NetBIOS calling name: *SMBSERVER", MODULE_NAME); memcpy(nb_name, "CKFDENECFDEFFCFGEFFCCACACACACACA", 32); /* *SMBSERVER */ } else { writeVerbose(VB_GENERAL, "%s: NetBIOS calling name: %s", MODULE_NAME, _psSessionData->machine_name); for (i = 0; i< 16; i++) { memset(nb_name + i * 2, ((_psSessionData->machine_name[i]) >> 4) + 0x41, 1); memset(nb_name + i * 2 + 1, ((_psSessionData->machine_name[i]) & 0x0F) + 0x41, 1); } } writeVerbose(VB_GENERAL, "%s: NetBIOS calling name: %s (encoded)", MODULE_NAME, nb_name); memcpy(nb_local, "ENEFEEFFFDEBCACACACACACACACACACA", 32); /* MEDUSA */ buf = malloc(100); memset(buf, 0, 100); memcpy(buf, (char *) rqbuf, 5); memcpy(buf + 5, nb_name, 32); memcpy(buf + 37, (char *) rqbuf + 5, 2); memcpy(buf + 39, nb_local, 32); memcpy(buf + 71, (char *) rqbuf + 5, 1); if (medusaSend(hSocket, buf, 76, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } FREE(buf); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; if ((unsigned char)bufReceive[0] == 0x82) return SUCCESS; /* success */ else return FAILURE; /* failed */ } /* NetBIOS Name Service Query */ int NBSTATQuery(sLogin *_psLogin,_SMBNT_DATA* _psSessionData) { sConnectParams params; int hSocket; int i = 0, j = 0; int iResponseOffset = 56; int iNameCount = 0; int iNameType = 0; char nb_name[16]; unsigned char nbstat[50] = { 0x81, 0xec, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21, 0x00, 0x01 }; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; /* if we are running in native mode (aka port 445) don't do netbios */ if (_psSessionData->protoFlag == WIN2000_NATIVEMODE) return 0; memset(¶ms, 0, sizeof(sConnectParams)); initConnectionParams(_psLogin, ¶ms); params.nPort = PORT_NBNS; hSocket = medusaConnectUDP(¶ms); if (hSocket < 0) { writeError(ERR_ERROR, "[%s] Failed to connect to NBNS UDP port (%d). Auto-identification of NetBIOS name unsuccessful on host: %s.", MODULE_NAME, PORT_NBNS, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (medusaSend(hSocket, nbstat, 50, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if ((bufReceive == NULL) || (nReceiveBufferSize < iResponseOffset + 1)) return FAILURE; /* Find the primary domain/workgroup name */ /* name (15 bytes) + type (1 byte) + flages (2 bytes) */ iNameCount = bufReceive[iResponseOffset]; writeVerbose(VB_GENERAL, "%s: NBSTAT - Number of names: %d", MODULE_NAME, iNameCount); if ((iResponseOffset + iNameCount * 16) > nReceiveBufferSize) { writeError(ERR_ERROR, "%s failed: unexpected response size to nbstat query.", MODULE_NAME); return FAILURE; } iResponseOffset++; for (i = 0; i < iNameCount; i++) { iNameType = bufReceive[iResponseOffset + 15]; memset(nb_name, 0, 16); memcpy(nb_name, bufReceive + iResponseOffset, 16); switch(iNameType) { case 0x00: writeVerbose(VB_GENERAL, "%s: NetBIOS Name (workstation service name): %s", MODULE_NAME, nb_name); break; case 0x03: writeVerbose(VB_GENERAL, "%s: NetBIOS Name (messenger service name): %s", MODULE_NAME, nb_name); break; case 0x1B: writeVerbose(VB_GENERAL, "%s: NetBIOS Name (domain master browser name): %s", MODULE_NAME, nb_name); break; case 0x1C: writeVerbose(VB_GENERAL, "%s: NetBIOS Name (domain group name): %s", MODULE_NAME, nb_name); for (j = 0; j < 16; j++) _psSessionData->workgroup[j] = nb_name[j]; break; case 0x20: writeVerbose(VB_GENERAL, "%s: NetBIOS Name (server service name): %s", MODULE_NAME, nb_name); for (j = 0; j < 16; j++) _psSessionData->machine_name[j] = nb_name[j]; break; default: writeVerbose(VB_GENERAL, "%s: NetBIOS Name (other type - %d): %s", MODULE_NAME,iNameType, nb_name); break; } iResponseOffset += 18; } writeVerbose(VB_GENERAL, "%s: Server machine name: %s", MODULE_NAME, _psSessionData->machine_name); writeVerbose(VB_GENERAL, "%s: Server primary domain: %s", MODULE_NAME, _psSessionData->workgroup); FREE(bufReceive); return SUCCESS; } /* SMBNegProt Function: Negotiate protocol with server ... Actually a pseudo negotiation since the whole program counts on NTLM support :) The challenge is retrieved from the answer No error checking is performed i.e cross your fingers.... */ int SMBNegProt(int hSocket, _SMBNT_DATA* _psSessionData) { unsigned char buf[168] = { 0x00, 0x00, 0x00, 0xa4, 0xff, 0x53, 0x4d, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x81, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x33, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00 }; unsigned char* bufReceive; int nReceiveBufferSize = 0; int i = 0, j = 0; int iLength = 168; int iResponseOffset = 73; if (_psSessionData->authLevel == AUTH_LM) { writeError(ERR_DEBUG_MODULE, "[%s] Setting Negotiate Protocol Response for LM.", MODULE_NAME); buf[3] = 0x89; /* Set message length */ buf[37] = 0x66; /* Set byte count for dialects */ iLength = 141; iResponseOffset = 65; } if (medusaSend(hSocket, buf, iLength, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; /* retrieve the security mode */ /* [0] Mode: (0) ? (1) USER security mode [1] Password: (0) PLAINTEXT password (1) ENCRYPTED password. Use challenge/response [2] Signatures: (0) Security signatures NOT enabled (1) ENABLED [3] Sig Req: (0) Security signatures NOT required (1) REQUIRED SAMBA: 0x01 (default) WinXP: 0x0F (default) WinXP: 0x07 (Windows 2003 / DC) */ switch (bufReceive[39]) { case 0x01: writeVerbose(VB_GENERAL, "%s: Server requested PLAINTEXT password.", MODULE_NAME); _psSessionData->security_mode = PLAINTEXT; if (_psSessionData->hashFlag == HASH) { writeError(ERR_ERROR, "%s: Server requested PLAINTEXT password. HASH password mode not supported for this configuration.", MODULE_NAME); return FAILURE; } if (_psSessionData->hashFlag == MACHINE_NAME) { writeError(ERR_ERROR, "%s: Server requested PLAINTEXT password. MACHINE password mode not supported for this configuration.", MODULE_NAME); return FAILURE; } break; case 0x03: writeVerbose(VB_GENERAL, "%s: Server requested ENCRYPTED password without security signatures.", MODULE_NAME); _psSessionData->security_mode = ENCRYPTED; break; case 0x07: case 0x0F: writeVerbose(VB_GENERAL, "%s: Server requested ENCRYPTED password.", MODULE_NAME); _psSessionData->security_mode = ENCRYPTED; break; default: writeError(ERR_ERROR, "%s: Unknown security mode request: %2.2X. Proceeding using ENCRYPTED password mode.", MODULE_NAME, bufReceive[39]); _psSessionData->security_mode = ENCRYPTED; break; } /* Retrieve the challenge */ memcpy(_psSessionData->challenge, (char *) bufReceive + iResponseOffset, sizeof(_psSessionData->challenge)); /* Find the primary domain/workgroup name */ while ((bufReceive[iResponseOffset + 8 + i * 2] != 0) && (i < 16)) { _psSessionData->workgroup[i] = bufReceive[iResponseOffset + 8 + i * 2]; i++; } while ((bufReceive[iResponseOffset + 8 + (i + j + 1) * 2] != 0) && (j < 16)) { _psSessionData->machine_name[j] = bufReceive[iResponseOffset + 8 + (i + j + 1) * 2]; j++; } writeVerbose(VB_GENERAL, "%s: Server machine name: %s", MODULE_NAME, _psSessionData->machine_name); writeVerbose(VB_GENERAL, "%s: Server primary domain: %s", MODULE_NAME, _psSessionData->workgroup); FREE(bufReceive); return SUCCESS; } /* SMBSessionSetup Function: Send username + response to the challenge from the server. Returns: TRUE on success else FALSE. */ unsigned long SMBSessionSetup(int hSocket, sLogin** psLogin, _SMBNT_DATA *_psSessionData, char* szLogin, char* szPassword) { unsigned char buf[512]; unsigned char *LMv2hash = NULL; unsigned char *NTLMv2hash = NULL; unsigned char *NTLMhash = NULL; unsigned char *LMhash = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int ret; int iByteCount; int iOffset = 0; unsigned char szPath[256]; unsigned long SMBSessionRet; if (_psSessionData->accntFlag == LOCAL) { strcpy((char *) _psSessionData->workgroup, "localhost"); } else if (_psSessionData->accntFlag == BOTH) { memset(_psSessionData->workgroup, 0, 16); } else if (_psSessionData->accntFlag == OTHER) { strncpy(_psSessionData->workgroup, _psSessionData->workgroup_other, 16); } /* NetBIOS Session Service */ unsigned char szNBSS[4] = { 0x00, /* Message Type: Session Message */ 0x00, 0x00, 0x85 /* Length -- MUST SET */ }; /* SMB Header */ unsigned char szSMB[32] = { 0xff, 0x53, 0x4d, 0x42, /* Server Component */ 0x73, /* SMB Command: Session Setup AndX */ 0x00, 0x00, 0x00, 0x00, /* NT Status: STATUS_SUCCESS */ 0x08, /* Flags */ 0x01, 0x40, /* Flags2 */ 0x00, 0x00, /* Process ID High */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Signature */ 0x00, 0x00, /* Reserved */ 0xFF, 0xFF, /* Tree ID */ 0x13, 0x37, /* Process ID */ 0x00, 0x00, /* User ID */ 0x01, 0x00 /* Multiplex ID */ }; memset(buf, 0, 512); memcpy(buf, szNBSS, 4); memcpy(buf +4, szSMB, 32); if (_psSessionData->security_mode == ENCRYPTED) { /* Session Setup AndX Request */ if (_psSessionData->authLevel == AUTH_LM) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting LM password authentication.", MODULE_NAME); unsigned char szSessionRequest[23] = { 0x0a, /* Word Count */ 0x75, /* AndXCommand: Tree Connect */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LAN Manager Password Hash Length */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 59; /* szNBSS + szSMB + szSessionRequest */ iByteCount = 24; /* Start with length of LM hash */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 23); /* Calculate and set LAN Manager password hash */ LMhash = (unsigned char *) malloc(24); memset(LMhash, 0, 24); ret = HashLM(_psSessionData, &LMhash, (unsigned char *) szPassword, (unsigned char *) _psSessionData->challenge); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset, LMhash, 24); FREE(LMhash); } else if (_psSessionData->authLevel == AUTH_NTLM) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting NTLM password authentication.", MODULE_NAME); unsigned char szSessionRequest[29] = { 0x0d, /* Word Count */ 0x75, /* AndXCommand: Tree Connect */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LAN Manager Password Hash Length */ 0x18, 0x00, /* NT LAN Manager Password Hash Length */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x50, 0x00, 0x00, 0x00, /* Capabilities */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 65; /* szNBSS + szSMB + szSessionRequest */ iByteCount = 48; /* Start with length of NTLM and LM hashes */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 29); /* Calculate and set NTLM password hash */ NTLMhash = (unsigned char *) malloc(24); memset(NTLMhash, 0, 24); /* We don't need to actually calculated a LM hash for this mode, only NTLM */ ret = HashNTLM(_psSessionData, &NTLMhash, (unsigned char *) szPassword, (unsigned char *) _psSessionData->challenge); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset + 24, NTLMhash, 24); /* Skip space for LM hash */ FREE(NTLMhash); } else if (_psSessionData->authLevel == AUTH_LMv2) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting LMv2 password authentication.", MODULE_NAME); unsigned char szSessionRequest[29] = { 0x0d, /* Word Count */ 0x75, /* AndXCommand: Tree Connect */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LAN Manager Password Hash Length */ 0x00, 0x00, /* NT LAN Manager Password Hash Length */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x50, 0x00, 0x00, 0x00, /* Capabilities */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 65; /* szNBSS + szSMB + szSessionRequest */ iByteCount = 24; /* Start with length of LMv2 response */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 29); /* Calculate and set LMv2 response hash */ ret = HashLMv2(_psSessionData, &LMv2hash, (unsigned char *) szLogin, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset, LMv2hash, 24); FREE(LMv2hash); } else if (_psSessionData->authLevel == AUTH_NTLMv2) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting LMv2/NTLMv2 password authentication.", MODULE_NAME); unsigned char szSessionRequest[29] = { 0x0d, /* Word Count */ 0x75, /* AndXCommand: Tree Connect */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x18, 0x00, /* LMv2 Response Hash Length */ 0x4b, 0x00, /* NTLMv2 Response Hash Length -- MUST SET */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x50, 0x00, 0x00, 0x00, /* Capabilities */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 65; /* szNBSS + szSMB + szSessionRequest */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 29); /* Calculate and set LMv2 response hash */ ret = HashLMv2(_psSessionData, &LMv2hash, (unsigned char *) szLogin, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; memcpy(buf + iOffset, LMv2hash, 24); FREE(LMv2hash); /* Calculate and set NTLMv2 response hash */ ret = HashNTLMv2(_psSessionData, &NTLMv2hash, &iByteCount, (unsigned char *) szLogin, (unsigned char *) szPassword); if (ret == FAILURE) return FAILURE; /* Set NTLMv2 Response Length */ memset(buf + iOffset - 12, iByteCount, 1); writeError(ERR_DEBUG_MODULE, "HashNTLMv2 response length: %d", iByteCount); memcpy(buf + iOffset + 24, NTLMv2hash, iByteCount); FREE(NTLMv2hash); iByteCount += 24; /* Reflects length of both LMv2 and NTLMv2 responses */ } } else if (_psSessionData->security_mode == PLAINTEXT) { writeError(ERR_DEBUG_MODULE, "[%s] Attempting PLAINTEXT password authentication.", MODULE_NAME); unsigned char szSessionRequest[23] = { 0x0a, /* Word Count */ 0x75, /* AndXCommand: Tree Connect */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0xff, 0xff, /* Max Buffer */ 0x02, 0x00, /* Max Mpx Count */ 0x3c, 0x7d, /* VC Number */ 0x00, 0x00, 0x00, 0x00, /* Session Key */ 0x00, 0x00, /* Password Length -- MUST SET */ 0x00, 0x00, 0x00, 0x00, /* Reserved */ 0x49, 0x00 /* Byte Count -- MUST SET */ }; iOffset = 59; /* szNBSS + szSMB + szSessionRequest */ /* Set Session Setup AndX Request header information */ memcpy(buf + 36, szSessionRequest, 23); /* Calculate and set password length */ /* Samba appears to append NULL characters equal to the password length plus 2 */ iByteCount = 2 * strlen(szPassword) + 2; buf[iOffset - 8] = (iByteCount) % 256; buf[iOffset - 7] = (iByteCount) / 256; /* set ANSI password */ /* Depending on the SAMBA server configuration, multiple passwords may be successful when dealing with mixed-case values. The SAMBA parameter "password level" appears to determine how many characters within a password are tested by the server both upper and lower case. For example, assume a SAMBA account has a password of "Fred" and the server is configured with "password level = 2". Medusa sends the password "FRED". The SAMBA server will brute-force test this value for us with values like: "FRed", "FrEd", "FreD", "fREd", "fReD", "frED", ... The default setting is "password level = 0". This results in only two attempts to being made by the remote server; the password as is and the password in all-lower case. */ strncpy((char *)buf + iOffset, szPassword, 256); } else { writeError(ERR_ERROR, "%s: security_mode was not properly set. This should not happen.", MODULE_NAME); return FAILURE; } /* Set account and workgroup values */ memcpy(buf + iOffset + iByteCount, szLogin, strlen(szLogin)); iByteCount += strlen(szLogin) + 1; /* NULL pad account name */ memcpy(buf + iOffset + iByteCount, _psSessionData->workgroup, strlen((char *) _psSessionData->workgroup)); iByteCount += strlen((char *) _psSessionData->workgroup) + 1; /* NULL pad workgroup name */ /* Set native OS and LAN Manager values */ sprintf((char *)buf + iOffset + iByteCount, "Unix"); iByteCount += strlen("Unix") + 1; /* NULL pad OS name */ sprintf((char *)buf + iOffset + iByteCount, "Samba"); iByteCount += strlen("Samba") + 1; /* NULL pad LAN Manager name */ /* Set data byte count */ buf[iOffset - 2] = iByteCount; writeError(ERR_DEBUG_MODULE, "[%s] Set byte count: %2.2X", MODULE_NAME, buf[57]); /* Set AndXOffset */ buf[39] = (iOffset - 4 + iByteCount) % 256; buf[40] = (iOffset - 4 + iByteCount) / 256; /* Chained Tree AndX Request - Test for ADMIN$ access */ iOffset += iByteCount; unsigned char szTreeConnectRequest[9] = { 0x04, /* Word Count */ 0xff, /* AndXCommand: No further commands */ 0x00, /* Reserved */ 0x00, 0x00, /* AndXOffset */ 0x08, 0x00, /* Flags */ 0x01, 0x00 /* Password Length */ }; memcpy(buf + iOffset, szTreeConnectRequest, 9); iOffset += 9; /* Set byte count (BCC) */ /* Password (1) + "\\" + "host IP" + "\ADMIN$" + null termination + service (6) */ iByteCount = 1 + 2 + strlen((char *) (*psLogin)->psServer->pHostIP) + 7 + 1 + 6; buf[iOffset] = (iByteCount) % 256; buf[iOffset + 1] = (iByteCount) / 256; writeError(ERR_DEBUG_MODULE, "[%s] Set byte count (BCC): 0x%2.2X%2.2X", MODULE_NAME, buf[iOffset + 1], buf[iOffset]); iOffset += 2; /* Set password field */ memset(buf + iOffset, 0, 1); iOffset++; /* Set target path -- e.g., \\192.168.0.1\ADMIN$ */ memset(szPath, 0, 256); snprintf((char *)szPath, sizeof(szPath), "\\\\%s\\ADMIN$", (*psLogin)->psServer->pHostIP); memcpy(buf + iOffset, szPath, strlen((char *)szPath)); iOffset += strlen((char *)szPath) + 1; /* Set service field */ unsigned char szService[6] = { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00 }; memcpy(buf + iOffset, szService, 6); iOffset += 6; /* End Chained Tree AndX Request */ /* Set the header length */ buf[2] = (iOffset - 4) / 256; buf[3] = (iOffset - 4) % 256; writeError(ERR_DEBUG_MODULE, "[%s] Set NBSS header length: %2.2X", MODULE_NAME, buf[3]); if (medusaSend(hSocket, buf, iOffset, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if ((bufReceive == NULL) || (nReceiveBufferSize == 0)) return FAILURE; /* 41 - Action (Guest/Non-Guest Account) */ /* 9 - NT Status (Error code) */ SMBSessionRet = ((bufReceive[41] & 0x01) << 24) | ((bufReceive[11] & 0xFF) << 16) | ((bufReceive[10] & 0xFF) << 8) | (bufReceive[9] & 0xFF); FREE(bufReceive); return SMBSessionRet; } #endif jmk-foofus-medusa-dd62069/src/modsrc/smbnt-smb2.c000066400000000000000000000165051460263104500216240ustar00rootroot00000000000000#include "smbnt.h" #ifdef SMBNT_SMB2_SUPPORT_ENABLED #define SMBv2 16 /* libsmb2:include/libsmb2-private.h */ #ifndef SMB2_SEC_NTLMSSP #define SMB2_SEC_UNDEFINED 0 /* use KRB if available, otherwise NTLM */ #define SMB2_SEC_NTLMSSP 1 #define SMB2_SEC_KRB5 2 #endif /* https://docs.microsoft.com/en-us/windows-server/storage/file-server/troubleshoot/smbv1-not-installed-by-default-in-windows * 2020/07/01 * New installations of Windows 10 and Server 2016 or later no longer support SMBv1. */ int SMB2NegProt(int hSocket, _SMBNT_DATA* _psSessionData) { /* Dialect: SMB 2.??? (highest) */ unsigned char buf[179] = { 0x00, 0x00, 0x00, 0xaf, 0xff, 0x53, 0x4d, 0x42, 0x72, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x8b, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x33, 0x00, 0x02, 0x4d, 0x49, 0x43, 0x52, 0x4f, 0x53, 0x4f, 0x46, 0x54, 0x20, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x53, 0x20, 0x33, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x53, 0x61, 0x6d, 0x62, 0x61, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x20, 0x31, 0x2e, 0x30, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c, 0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00, 0x02, 0x53, 0x4d, 0x42, 0x20, 0x32, 0x2e, 0x3f, 0x3f, 0x3f, 0x00 }; unsigned char* bufReceive; int nReceiveBufferSize = 0; if (medusaSend(hSocket, buf, sizeof(buf), 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; /* SMBv2 negotiation (SMBv1: 0xff) */ if (bufReceive[4] == 0xfe) { writeVerbose(VB_GENERAL, "%s: Server negotiated SMBv2", MODULE_NAME); _psSessionData->smbVersion = SMBv2; _psSessionData->smb2 = smb2_init_context(); if (_psSessionData->smb2 == NULL) { writeError(ERR_ERROR, "[%s] Failed to initialize context.", MODULE_NAME); return FAILURE; } smb2_set_authentication(_psSessionData->smb2, SMB2_SEC_NTLMSSP); smb2_set_security_mode(_psSessionData->smb2, SMB2_NEGOTIATE_SIGNING_ENABLED); return SUCCESS; } return FAILURE; } /* SMB2ConvertPassword Function: Prepare NTLM password hash for libsmb2. */ int SMB2ConvertPassword(_SMBNT_DATA *_psSessionData, unsigned char* szPassword, unsigned char** szPassword2) { unsigned int i = 0; unsigned char *p = NULL; unsigned char NO_PASSWORD[1] = ""; /* Use NTLM Hash instead of password */ /* D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ if (_psSessionData->hashFlag == HASH) { p = szPassword; while ((*p != '\0') && (i < 1)) { if (*p == ':') i++; p++; } } /* If "-e ns" was used, don't treat these values as hashes. */ if ((_psSessionData->hashFlag == HASH) && (i >= 1)) { if (*p == '\0') { writeError(ERR_ERROR, "Error reading PwDump file."); return FAILURE; } else if (*p == 'N') { writeError(ERR_DEBUG_MODULE, "Found \"NO PASSWORD\" for NTLM Hash."); *szPassword2 = NO_PASSWORD; } else { memset(p + 32, '\0', 1); writeError(ERR_DEBUG_MODULE, "Prepare ASCII PwDump NTLM Hash (%s).", p); if (asprintf((char **)szPassword2, "ntlm:%s", p) < 0) { return FAILURE; } } } else if ((_psSessionData->hashFlag == HASH)) { writeError(ERR_DEBUG_MODULE, "Prepare ASCII PwDump NTLM Hash (%s).", szPassword); if (asprintf((char **)szPassword2, "ntlm:%s", szPassword) < 0) { return FAILURE; } } else { *szPassword2 = szPassword; writeError(ERR_DEBUG_MODULE, "[%s] Using standard password: %s", MODULE_NAME, *szPassword2); } return SUCCESS; } /* SMB2SessionSetup */ unsigned long SMB2SessionSetup(int hSocket, sLogin** psLogin, _SMBNT_DATA *_psSessionData, char* szLogin, char* szPassword) { int SMBerr, SMBaction; unsigned long SMBSessionRet; const char *pErrorMsg = NULL; char ErrorCode[10]; int iRet; unsigned int i; unsigned char* szPassword2 = NULL; regex_t preg; int errcode = REG_NOMATCH; char errmsg[512]; size_t nmatch = 1; regmatch_t pmatch[1]; if (_psSessionData->accntFlag == LOCAL) { strcpy((char *) _psSessionData->workgroup, "."); } else if (_psSessionData->accntFlag == BOTH) { memset(_psSessionData->workgroup, 0, 16); } else if (_psSessionData->accntFlag == OTHER) { strncpy(_psSessionData->workgroup, _psSessionData->workgroup_other, 16); } writeError(ERR_DEBUG_MODULE, "[%s] Set authentication request data.", MODULE_NAME); smb2_set_domain(_psSessionData->smb2, _psSessionData->workgroup); smb2_set_user(_psSessionData->smb2, szLogin); if (SMB2ConvertPassword(_psSessionData, szPassword, &szPassword2) == FAILURE) { writeError(ERR_ERROR, "Failed to prepare libsmb2 password."); return FAILURE; } smb2_set_password(_psSessionData->smb2, szPassword2); writeError(ERR_DEBUG_MODULE, "[%s] Initiate SMB2 connection.", MODULE_NAME); if (smb2_connect_share(_psSessionData->smb2, (*psLogin)->psServer->pHostIP, "ADMIN$", NULL) < 0) { pErrorMsg = smb2_get_error(_psSessionData->smb2); writeError(ERR_DEBUG_MODULE, "[%s] Failed to connect to ADMIN$: %s", MODULE_NAME, pErrorMsg); /* Extract error code from libsmb2 error message: ERROR: [smb2.mod] Failed to connect to ADMIN$: Session setup failed with (0xc000006d) STATUS_LOGON_FAILURE */ errcode = regcomp(&preg, "0x[a-fA-F0-9]+", REG_EXTENDED|REG_ICASE); if (errcode) { memset(errmsg, 0, 512); regerror(errcode, &preg, errmsg, 512); writeError(ERR_ERROR, "Regex compilation failed: %s", errmsg); return FAILURE; } errcode = regexec(&preg, pErrorMsg, nmatch, pmatch, 0); if (errcode == REG_NOMATCH) { writeError(ERR_ERROR, "[%s] Regex failed to match smb2_connect_share error message.", MODULE_NAME); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "[%s] Regex successfully matched smb2_connect_share error message.", MODULE_NAME); memset(errmsg, 0, 512); memcpy(errmsg, pErrorMsg + pmatch[0].rm_so, pmatch[0].rm_eo - pmatch[0].rm_so); SMBSessionRet = (int)strtol(errmsg, NULL, 0); writeError(ERR_DEBUG_MODULE, "[%s] smb2_connect_share session return code: 0x%6.6X", MODULE_NAME, SMBSessionRet); } } else { writeError(ERR_DEBUG_MODULE, "[%s] smb2_connect_share returned without error.", MODULE_NAME); SMBSessionRet = 0x00000000; smb2_disconnect_share(_psSessionData->smb2); } return SMBSessionRet; } #else int SMB2NegProt(int hSocket, _SMBNT_DATA* _psSessionData) { writeVerbose(VB_NONE, "** Module was not built with LIBSMB2 support **"); return FAILURE; } unsigned long SMB2SessionSetup(int hSocket, sLogin** psLogin, _SMBNT_DATA *_psSessionData, char* szLogin, char* szPassword) { writeVerbose(VB_NONE, "** Module was not built with LIBSMB2 support **"); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/smbnt.c000066400000000000000000000660301460263104500207610ustar00rootroot00000000000000/* ** SMB LAN Manager Password/HASH Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2024 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: SMB Auditing Tool ** [Copyright (C) Patrik Karlsson 2001] ** ** This code allows Medusa to directly test NTLM hashes against ** a Windows host. This may be useful for an auditor who has aquired ** a sam._ or pwdump file and would like to quickly determine ** which are valid entries. ** ** Several "-m 'METHOD:VALUE'" options can be used with this module. The ** following are valid methods: GROUP, GROUP_OTHER, PASS, AUTH and NETBIOS. ** The following values are useful for these methods: ** ** GROUP:? ** LOCAL == Check local account. ** DOMAIN == Check credentials against this hosts primary ** domain controller via this host. ** BOTH == Check both. This leaves the workgroup field set ** blank and then attempts to check the credentials ** against the host. If the account does not exist ** locally on the host being tested, that host then ** queries its domain controller. ** ** GROUP_OTHER:? ** Configure arbitrary domain for host to authenticate against. ** ** PASS:? ** PASSWORD == Use a normal password. ** HASH == Use a NTLM hash rather than a password. ** MACHINE == Use the Machine's NetBIOS name as the password. ** ** AUTH:? ** LM == LM authentication (case-insensitive) ** NTLM == NTLMv1 authentication ** LMv2 == LMv2 authentication ** NTLMv2 == NTLMv2 authentication ** ** NETBIOS ** Force NetBIOS Mode (Disable Native Win2000 Mode) ** ** Be careful of mass domain account lockout with this. For ** example, assume you are checking several accounts against ** many domain workstations. If you are not using the 'LOCAL' ** option and these accounts do not exist locally on the ** workstations, each workstation will in turn check their ** respective domain controller. This could cause a bunch of ** lockouts. Of course, it'd look like the workstations, not ** you, were doing it. ;) ** ** **FYI, this code is unable to test accounts on default XP ** hosts which are not part of a domain and do not have normal ** file sharing enabled. Default XP does not allow shares and ** returns STATUS_LOGON_FAILED for both valid and invalid ** credentials. XP with simple sharing enabled returns SUCCESS ** for both valid and invalid credentials. If anyone knows a ** way to test in these configurations... ** ** See http://www.foofus.net/jmk/passhash.html for further ** examples. */ #include "smbnt.h" #ifdef HAVE_LIBSSL // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " GROUP:? (DOMAIN, LOCAL*, BOTH)"); writeVerbose(VB_NONE, " Option sets NetBIOS workgroup field."); writeVerbose(VB_NONE, " DOMAIN: Check credentials against this hosts primary domain controller via this host."); writeVerbose(VB_NONE, " LOCAL: Check local account."); writeVerbose(VB_NONE, " BOTH: Check both. This leaves the workgroup field set blank and then attempts to check"); writeVerbose(VB_NONE, " the credentials against the host. If the account does not exist locally on the "); writeVerbose(VB_NONE, " host being tested, that host then queries its domain controller."); writeVerbose(VB_NONE, " GROUP_OTHER:? "); writeVerbose(VB_NONE, " Option allows manual setting of domain to check against. Use instead of GROUP."); writeVerbose(VB_NONE, " PASS:? (PASSWORD*, HASH, MACHINE)"); writeVerbose(VB_NONE, " PASSWORD: Use normal password."); writeVerbose(VB_NONE, " HASH: Use a NTLM hash rather than a password."); writeVerbose(VB_NONE, " MACHINE: Use the machine's NetBIOS name as the password."); writeVerbose(VB_NONE, " AUTH:? (LM, NTLM, LMv2*, NTLMv2)"); writeVerbose(VB_NONE, " Option sets LAN Manager Authentication level."); writeVerbose(VB_NONE, " LM: "); writeVerbose(VB_NONE, " NTLM: "); writeVerbose(VB_NONE, " LMv2: "); writeVerbose(VB_NONE, " NTLMv2: "); writeVerbose(VB_NONE, " NETBIOS"); writeVerbose(VB_NONE, " Force NetBIOS Mode (Disable Native Win2000 Mode). Win2000 mode is the default."); writeVerbose(VB_NONE, " Default mode is to test TCP/445 using Native Win2000. If this fails, module will"); writeVerbose(VB_NONE, " fall back to TCP/139 using NetBIOS mode. To test only TCP/139, use the following:"); writeVerbose(VB_NONE, " medusa -M smbnt -m NETBIOS -n 139"); writeVerbose(VB_NONE, "\n(*) Default value"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage examples:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "1: Normal boring check..."); writeVerbose(VB_NONE, " medusa -M smbnt -h somehost -u someuser -p somepassword"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "2: Testing domain credentials against a client system..."); writeVerbose(VB_NONE, " medusa -M smbnt -h somehost -U users.txt -p password -m GROUP:DOMAIN"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "3: Testing each credential from a PwDump file against the target's domain via the target..."); writeVerbose(VB_NONE, " medusa -M smbnt -h somehost -C pwdump.txt -m PASS:HASH -m GROUP:DOMAIN"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "4: Testing each hash from a PwDump file against a specific user local to the target..."); writeVerbose(VB_NONE, " medusa -M smbnt -H hosts.txt -C pwdump.txt -u someuser -m PASS:HASH"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "5: Testing an individual NTLM hash..."); writeVerbose(VB_NONE, " medusa -M smbnt -H hosts.txt -u administrator -p 92D887C8010492C2944E2DF489A880E4:7A2EDE4F51BC5A03984C6BA2C239CF63::: -m PASS:HASH"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Access level:"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "This module performs both an SMB authentication request (Session Setup AndX) and a "); writeVerbose(VB_NONE, "share connection request (Tree Connect AndX). The share connection request is for the "); writeVerbose(VB_NONE, "default hidden administrative share ADMIN$. The goal is to identify if the credentials "); writeVerbose(VB_NONE, "being tested have administrative rights to the target system. The following examples "); writeVerbose(VB_NONE, "highlight how to interrupt the responses."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Valid administrative-level credentials: [SUCCESS (ADMIN$ - Access Allowed)]"); writeVerbose(VB_NONE, " Valid user-level credentials: [SUCCESS (ADMIN$ - Access Denied)]"); writeVerbose(VB_NONE, " Valid credentials, access level unknown: [SUCCESS (ADMIN$ - Share Unavailable)]"); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _SMBNT_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_SMBNT_DATA)); memset(psSessionData, 0, sizeof(_SMBNT_DATA)); if ((argc < 0) || (argc > 5)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); psSessionData->authLevel = AUTH_LMv2; psSessionData->accntFlag = LOCAL; psSessionData->hashFlag = PASSWORD; psSessionData->protoFlag = WIN2000_NATIVEMODE; for (i=0; iaccntFlag = LOCAL; else if (strcmp(pOpt, "DOMAIN") == 0) psSessionData->accntFlag = NTDOMAIN; else if (strcmp(pOpt, "BOTH") == 0) psSessionData->accntFlag = BOTH; else writeError(ERR_WARNING, "Invalid value for method GROUP."); } else if (strcmp(pOpt, "GROUP_OTHER") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { strncpy((char *) psSessionData->workgroup_other, pOpt, 16); psSessionData->accntFlag = OTHER; } else writeError(ERR_WARNING, "Method GROUP_OTHER requires value to be set."); } else if (strcmp(pOpt, "PASS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method PASS requires value to be set."); else if (strcmp(pOpt, "PASSWORD") == 0) psSessionData->hashFlag = PASSWORD; else if (strcmp(pOpt, "HASH") == 0) psSessionData->hashFlag = HASH; else if (strcmp(pOpt, "MACHINE") == 0) psSessionData->hashFlag = MACHINE_NAME; else writeError(ERR_WARNING, "Invalid value for method PASS."); } else if (strcmp(pOpt, "AUTH") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method AUTH requires value to be set."); else if (strcmp(pOpt, "LM") == 0) psSessionData->authLevel = AUTH_LM; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->authLevel = AUTH_NTLM; else if (strcmp(pOpt, "LMv2") == 0) psSessionData->authLevel = AUTH_LMv2; else if (strcmp(pOpt, "NTLMv2") == 0) { psSessionData->authLevel = AUTH_NTLMv2; /* NTLMv2 authentication is returning a STATUS_INVALID_PARAMETER response with 2012R2 servers. This issue pre-dates the AndX modification. */ writeError(ERR_FATAL, "NTLMv2 support currently disabled. The default authentication mode of LMv2 should work in all cases that NTLMv2 is required."); } else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "NETBIOS") == 0) { psSessionData->protoFlag = WIN_NETBIOSMODE; } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } FREE(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SMBNT_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char *szUser = NULL; sConnectParams params; sCredentialSet *psCredSet = NULL; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); szUser = parseFullyQualifiedUsername(_psSessionData, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_SMBNT; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (params.nPort == PORT_SMBNT) { hSocket = medusaConnect(¶ms); if ( hSocket < 0 ) { writeError(ERR_NOTICE, "%s Failed to establish WIN2000_NATIVE mode. Attempting WIN_NETBIOS mode.)", MODULE_NAME); params.nPort = PORT_SMB; _psSessionData->protoFlag = WIN_NETBIOSMODE; hSocket = medusaConnect(¶ms); } } else { hSocket = medusaConnect(¶ms); } if (hSocket < 0) { writeError(ERR_ERROR, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); if (NBSTATQuery(psLogin, _psSessionData) < 0) { writeError(ERR_ERROR, "NetBIOS Name Query Failed with host: %s (proceeding anyways).", psLogin->psServer->pHostIP); } if (NBSSessionRequest(hSocket, _psSessionData) < 0) { writeError(ERR_ERROR, "Session Setup Failed with host: %s. Is the server service running?", psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (SMBNegProt(hSocket, _psSessionData) < 0) { writeError(ERR_DEBUG_MODULE, "[%s] SMBv1 protocol negotiation failed with host: %s. Attempting SMBv2 connection.", MODULE_NAME, psLogin->psServer->pHostIP); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (SMB2NegProt(hSocket, _psSessionData) < 0) { writeError(ERR_ERROR, "SMBv2 protocol negotiation failed with host: %s", psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } else { nState = MSTATE_RUNNING; } } else { nState = MSTATE_RUNNING; } break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, szUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); FREE(szUser); szUser = parseFullyQualifiedUsername(_psSessionData, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; #ifdef SMBNT_SMB2_SUPPORT_ENABLED smb2_destroy_context(_psSessionData->smb2); #endif nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module (%d) state %d host: %s", MODULE_NAME, psLogin->iId, nState, psLogin->psServer->pHostIP); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; #ifdef SMBNT_SMB2_SUPPORT_ENABLED smb2_destroy_context(_psSessionData->smb2); #endif psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } writeError(ERR_DEBUG_MODULE, "[%s] Exiting module...", MODULE_NAME); FREE(psCredSet); FREE(szUser); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _SMBNT_DATA* _psSessionData, char* szLogin, char* szPassword) { int SMBerr, SMBaction; unsigned long SMBSessionRet; char *pErrorMsg = NULL; char ErrorCode[10]; int iRet; unsigned int i; /* Nessus Plugins: smb_header.inc */ /* Note: we are currently only examining the lower 2 bytes of data */ int smbErrorCode[] = { 0xFFFFFFFF, /* UNKNOWN_ERROR_CODE */ 0x00000000, /* STATUS_SUCCESS */ 0xC000000D, /* STATUS_INVALID_PARAMETER */ 0xC000005E, /* STATUS_NO_LOGON_SERVERS */ 0xC000006D, /* STATUS_LOGON_FAILURE */ 0xC000006E, /* STATUS_ACCOUNT_RESTRICTION */ 0xC000006F, /* STATUS_INVALID_LOGON_HOURS */ 0x00C10002, /* STATUS_INVALID_LOGON_HOURS (LM Authentication) */ 0xC0000070, /* STATUS_INVALID_WORKSTATION */ 0x00C00002, /* STATUS_INVALID_WORKSTATION (LM Authentication) */ 0xC0000071, /* STATUS_PASSWORD_EXPIRED */ 0xC0000072, /* STATUS_ACCOUNT_DISABLED */ 0xC000015B, /* STATUS_LOGON_TYPE_NOT_GRANTED */ 0xC000018D, /* STATUS_TRUSTED_RELATIONSHIP_FAILURE */ 0xC0000193, /* STATUS_ACCOUNT_EXPIRED */ 0xC0000199, /* STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT */ 0x00BF0002, /* STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM Authentication) */ 0xC0000224, /* STATUS_PASSWORD_MUST_CHANGE */ 0x00C20002, /* STATUS_PASSWORD_MUST_CHANGE (LM Authentication) */ 0xC0000234, /* STATUS_ACCOUNT_LOCKED_OUT (No LM Authentication Code) */ 0x00050001, /* AS400_STATUS_LOGON_FAILURE */ 0x00000064, /* The machine you are logging onto is protected by an authentication firewall. */ 0xC0000022, /* STATUS_ACCESS_DENIED */ 0xC00000CC /* STATUS_BAD_NETWORK_NAME */ }; char *smbErrorMsg[] = { "UNKNOWN_ERROR_CODE", "STATUS_SUCCESS", "STATUS_INVALID_PARAMETER", "STATUS_NO_LOGON_SERVERS", "STATUS_LOGON_FAILURE", "STATUS_ACCOUNT_RESTRICTION", "STATUS_INVALID_LOGON_HOURS", "STATUS_INVALID_LOGON_HOURS (LM)", "STATUS_INVALID_WORKSTATION", "STATUS_INVALID_WORKSTATION (LM)", "STATUS_PASSWORD_EXPIRED", "STATUS_ACCOUNT_DISABLED", "STATUS_LOGON_TYPE_NOT_GRANTED", "STATUS_TRUSTED_RELATIONSHIP_FAILURE", "STATUS_ACCOUNT_EXPIRED", "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", "STATUS_ACCOUNT_EXPIRED_OR_DISABLED (LM)", "STATUS_PASSWORD_MUST_CHANGE", "STATUS_PASSWORD_MUST_CHANGE (LM)", "STATUS_ACCOUNT_LOCKED_OUT", "AS400_STATUS_LOGON_FAILURE", "AUTHENTICATION_FIREWALL_PROTECTION", "STATUS_ACCESS_DENIED", "STATUS_BAD_NETWORK_NAME" }; memset(&ErrorCode, 0, 10); if (_psSessionData->smbVersion == SMBv2) { SMBSessionRet = SMB2SessionSetup(hSocket, psLogin, _psSessionData, szLogin, szPassword); } else { SMBSessionRet = SMBSessionSetup(hSocket, psLogin, _psSessionData, szLogin, szPassword); } SMBerr = (unsigned long) SMBSessionRet & 0x00FFFFFF; SMBaction = ((unsigned long) SMBSessionRet & 0xFF000000) >> 24; writeError(ERR_DEBUG_MODULE, "SMBSessionRet: %8.8X SMBerr: %4.4X SMBaction: %2.2X", SMBSessionRet, SMBerr, SMBaction); /* Locate appropriate SMB code message */ pErrorMsg = smbErrorMsg[0]; /* UNKNOWN_ERROR_CODE */ for (i = 0; i < sizeof(smbErrorCode)/4; i++) { if (SMBerr == (smbErrorCode[i] & 0x00FFFFFF)) { pErrorMsg = smbErrorMsg[i]; break; } } switch (SMBerr) { case 0x000000: /* Non-domain connected XP and 2003 hosts map non-existant accounts to the anonymous user and return SUCCESS during password checks. Medusa will check the value of the ACTION flag in the target's response to determine if the account is a legitimate or anonymous success. */ if (SMBaction == 0x01) { (*psLogin)->pErrorMsg = malloc( 40 + 1 ); memset((*psLogin)->pErrorMsg, 0, 40 + 1 ); sprintf((*psLogin)->pErrorMsg, "Non-existant account. Anonymous success."); (*psLogin)->iResult = LOGIN_RESULT_ERROR; } else { (*psLogin)->pErrorMsg = malloc( 23 + 1 ); memset((*psLogin)->pErrorMsg, 0, 23 + 1 ); sprintf((*psLogin)->pErrorMsg, "ADMIN$ - Access Allowed"); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; } iRet = MSTATE_EXITING; break; case 0x00006F: /* STATUS_INVALID_LOGON_HOURS - Valid password */ case 0xC10002: /* STATUS_INVALID_LOGON_HOURS - Valid password (LM) */ case 0x000064: /* Valid password, "The machine you are logging onto is protected by an authentication firewall. The specificed account is not allowed to authenticate to the machine." */ case 0x000070: /* STATUS_INVALID_WORKSTATION - Valid password */ case 0xC00002: /* STATUS_INVALID_WORKSTATION - Valid password (LM) */ // TODO: Verify whether we can determine password validity from DISABLED. Win7 doesn't seem to tell us... //case 0x000072: /* STATUS_ACCOUNT_DISABLED - Valid password */ case 0x000193: /* STATUS_ACCOUNT_EXPIRED - Valid password */ case 0xBF0002: /* STATUS_ACCOUNT_DISABLED or STATUS_ACCOUNT_EXPIRED - Valid password (LM) */ case 0x000224: /* STATUS_PASSWORD_MUST_CHANGE - Valid password */ case 0xC20002: /* STATUS_PASSWORD_MUST_CHANGE - Valid password (LM) */ // TODO: Verify whether we can determine password validity from STATUS_ACCOUNT_RESTRICTION. Win7 doesn't seem to tell us... //case 0x00006E: /* Valid password, GPO Disabling Remote Connections Using NULL Passwords */ // TODO: Verify whether we can determine password validity from STATUS_ACCOUNT_RESTRICTION. Win7 doesn't seem to tell us... //case 0x00015B: /* Valid password, GPO "Deny access to this computer from the network" */ case 0x000071: /* Valid password, password expired and must be changed on next logon */ (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; sprintf(ErrorCode, "0x%6.6X:", SMBerr); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strcpy((*psLogin)->pErrorMsg, ErrorCode); strcat((*psLogin)->pErrorMsg, pErrorMsg); iRet = MSTATE_EXITING; break; case 0x000022: /* Valid password, no access to ADMIN$ (non-administative account) */ (*psLogin)->pErrorMsg = malloc( 22 + 1 ); memset((*psLogin)->pErrorMsg, 0, 22 + 1 ); sprintf((*psLogin)->pErrorMsg, "ADMIN$ - Access Denied"); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; break; case 0x0000CC: /* Valid password, but ADMIN$ not found (STATUS_BAD_NETWORK_NAME) */ (*psLogin)->pErrorMsg = malloc( 26 + 1 ); memset((*psLogin)->pErrorMsg, 0, 26 + 1 ); sprintf((*psLogin)->pErrorMsg, "ADMIN$ - Share Unavailable"); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; break; case 0x050001: /* AS/400 -- Incorrect password */ writeError(ERR_DEBUG_MODULE, "[%s] AS/400 Access is Denied. Incorrect password or disabled account.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; break; case 0x00006D: /* Incorrect password */ (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; break; default: sprintf(ErrorCode, "0x%6.6X:", SMBerr); (*psLogin)->pErrorMsg = malloc( strlen(ErrorCode) + strlen(pErrorMsg) + 1); memset((*psLogin)->pErrorMsg, 0, strlen(ErrorCode) + strlen(pErrorMsg) + 1); strcpy((*psLogin)->pErrorMsg, ErrorCode); strcat((*psLogin)->pErrorMsg, pErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; break; } if (_psSessionData->hashFlag == MACHINE_NAME) { setPassResult((*psLogin), (char *)_psSessionData->machine_name); iRet = MSTATE_EXITING; } else { setPassResult((*psLogin), szPassword); } return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/smbnt.h000066400000000000000000000074561460263104500207750ustar00rootroot00000000000000/* ** SMB LAN Manager Password/HASH Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2024 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** */ #include #include #include #include #include #include #include "module.h" #include "hmacmd5.h" #define MODULE_NAME "smbnt.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for SMB (SMBv1-3, Signing, LM/NTLM/LMv2/NTLMv2) sessions" #define MODULE_VERSION "3.0" #define MODULE_VERSION_SVN "$Id: smbnt.c 9239 2015-05-22 15:03:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include #endif #ifdef HAVE_LIBSMB2 #include #include //#include //#include #endif #define PORT_NBNS 137 #define PORT_SMB 139 #define PORT_SMBNT 445 #define WIN2000_NATIVEMODE 1 #define WIN_NETBIOSMODE 2 #define PASSWORD 3 #define HASH 4 #define MACHINE_NAME 5 #define LOCAL 6 #define NTDOMAIN 7 #define BOTH 8 #define OTHER 9 #define PLAINTEXT 10 #define ENCRYPTED 11 #define AUTH_LM 12 #define AUTH_NTLM 13 #define AUTH_LMv2 14 #define AUTH_NTLMv2 15 #define SMBv2 16 #ifndef CHAR_BIT #define CHAR_BIT 8 #endif #ifndef TIME_T_MIN #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \ : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) #endif #ifndef TIME_T_MAX #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) #endif #define IVAL_NC(buf,pos) (*(unsigned int *)((char *)(buf) + (pos))) /* Non const version of above. */ #define SIVAL(buf,pos,val) IVAL_NC(buf,pos)=((unsigned int)(val)) #if (SIZEOF_LONG == 8) #define TIME_FIXUP_CONSTANT_INT 11644473600L #elif (SIZEOF_LONG_LONG == 8) #define TIME_FIXUP_CONSTANT_INT 11644473600LL #endif typedef struct __SMBNT_DATA { #ifdef HAVE_LIBSMB2 struct smb2_context *smb2; #endif unsigned char challenge[8]; char workgroup[16]; char workgroup_other[16]; unsigned char machine_name[16]; int security_mode; int authLevel; int hashFlag; int accntFlag; int protoFlag; int smbVersion; } _SMBNT_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; int tryLogin(int hSocket, sLogin** login, _SMBNT_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _SMBNT_DATA *_psSessionData); char* parseFullyQualifiedUsername(_SMBNT_DATA *_psSessionData, char* szLogin); int NBSSessionRequest(int hSocket, _SMBNT_DATA* _psSessionData); int NBSTATQuery(sLogin *_psLogin,_SMBNT_DATA* _psSessionData); int SMBNegProt(int hSocket, _SMBNT_DATA* _psSessionData); unsigned long SMBSessionSetup(int hSocket, sLogin** psLogin, _SMBNT_DATA *_psSessionData, char* szLogin, char* szPassword); int SMB2NegProt(int hSocket, _SMBNT_DATA* _psSessionData); unsigned long SMB2SessionSetup(int hSocket, sLogin** psLogin, _SMBNT_DATA *_psSessionData, char* szLogin, char* szPassword); jmk-foofus-medusa-dd62069/src/modsrc/smtp-vrfy.c000066400000000000000000000476061460263104500216150ustar00rootroot00000000000000/* ** SMTP Verification (VRFY/EXPN/RCPT TO) Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2015 JoMo-Kun ** JoMo-Kun ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "smtp-vrfy.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for verifying SMTP accounts (VRFY/EXPN/RCPT TO)" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: smtp-vrfy.c 9261 2015-05-28 14:18:21Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_SMTP 25 #define PORT_SMTPS 465 #define BUF_SIZE 600 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define HELO_NONE 0 #define HELO_HELO 1 #define HELO_EHLO 2 #define VERB_NONE 0 #define VERB_VRFY 1 #define VERB_EXPN 2 #define VERB_RCPT 3 typedef struct __MODULE_DATA { int nHELO; char *szHELO; char *szMAILFROM; int nVerb; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " HELO [optional] "); writeVerbose(VB_NONE, " Use HELO command. Default: EHLO"); writeVerbose(VB_NONE, " HELODOMAIN:? [optional] "); writeVerbose(VB_NONE, " Specify the HELO/EHLO domain. Default: server.domain"); writeVerbose(VB_NONE, " MAILFROM:? [optional] "); writeVerbose(VB_NONE, " Specify the MAIL FROM address. Default: doesnotexist@foofus.net"); writeVerbose(VB_NONE, " VERB:? (Verb/Command: VRFY/EXPN/RCPT TO. Default: RCPT TO"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "*** NOTE: Target address domain should be specified within password field. ***"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: "); writeVerbose(VB_NONE, " \"medusa -M smtp-vrfy -m VERB:VRFY -U accounts.txt -p domain.com\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _MODULE_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 4)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inHELO = HELO_HELO; } else if (strcmp(pOpt, "VERB") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method VERB requires value to be set."); else if (strcmp(pOpt, "VRFY") == 0) psSessionData->nVerb = VERB_VRFY; else if (strcmp(pOpt, "EXPN") == 0) psSessionData->nVerb = VERB_EXPN; else if (strcmp(pOpt, "RCPT") == 0) psSessionData->nVerb = VERB_RCPT; else writeError(ERR_WARNING, "Invalid value for method VERB."); } else if (strcmp(pOpt, "HELODOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szHELO =strdup(pOpt); } else writeError(ERR_WARNING, "Method HELODOMAIN requires value to be set."); } else if (strcmp(pOpt, "MAILFROM") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szMAILFROM = strdup(pOpt); } else writeError(ERR_WARNING, "Method MAILFROM requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_SMTPS; else params.nPort = PORT_SMTP; initConnectionParams(psLogin, ¶ms); /* set EHLO, if not specified by user */ if (_psSessionData->nHELO == 0) _psSessionData->nHELO = HELO_EHLO; /* set HELO domain, if not specified by user */ if (_psSessionData->szHELO == NULL) { _psSessionData->szHELO = malloc(14); memset(_psSessionData->szHELO, 0, 14); sprintf(_psSessionData->szHELO, "server.domain"); } /* set MAILFROM, if not specified by user */ if (_psSessionData->szMAILFROM == NULL) { _psSessionData->szMAILFROM = malloc(24); memset(_psSessionData->szMAILFROM, 0, 24); sprintf(_psSessionData->szMAILFROM, "doesnotexist@foofus.net"); } /* Default verb/command is RCPT TO */ if (_psSessionData->nVerb == VERB_NONE) { _psSessionData->nVerb = VERB_RCPT; } while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(_psSessionData, hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params) { unsigned char *bufSend = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* Retrieve SMTP banner */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving SMTP banner.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server did not respond with '220'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Send greeting to SMTP server */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP HELO greeting.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szHELO) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); if (_psSessionData->nHELO == HELO_HELO) sprintf((char *)bufSend, "HELO %s\r\n", _psSessionData->szHELO); else sprintf((char *)bufSend, "EHLO %s\r\n", _psSessionData->szHELO); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "250 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* If server supports STARTTLS and we are not already within a SSL connection, let's use it. */ if ((params->nUseSSL == 0) && (strstr((char *)bufReceive, "STARTTLS") != NULL)) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Initiating STARTTLS session.", MODULE_NAME); bufSend = malloc(10 + 1); memset(bufSend, 0, 10 + 1); sprintf((char *)bufSend, "STARTTLS\r\n"); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '220'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { FREE(bufReceive); if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); return FAILURE; } /* Resend HELO greeting as the AUTH types may have changed. */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP HELO greeting.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szHELO) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char *)bufSend, "HELO %s\r\n", _psSessionData->szHELO); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "250 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } } } /* Process SMTP supported verbs */ if (strstr((char *)bufReceive, "VRFY") != NULL) writeError(ERR_DEBUG_MODULE, "Detected verb: VFRY"); else if (strstr((char *)bufReceive, "RCPT") != NULL) writeError(ERR_DEBUG_MODULE, "Detected verb: RCPT"); FREE(bufReceive); /* Send MAIL FROM to SMTP server (required for RCPT TO) */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP MAIL FROM command.", MODULE_NAME); nSendBufferSize = 12 + strlen(_psSessionData->szMAILFROM) + 3; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char *)bufSend, "MAIL FROM: <%s>\r\n", _psSessionData->szMAILFROM); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "250 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szAccount, char* szDomain) { int nRet = FAILURE; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; unsigned char bufSend[BUF_SIZE]; char szVerb[9]; memset(szVerb, 0, 9); switch(_psSessionData->nVerb) { case VERB_VRFY: writeError(ERR_DEBUG_MODULE, "[%s] Using VRFY command.", MODULE_NAME); strncpy(szVerb, "VRFY", 4); break; case VERB_EXPN: writeError(ERR_DEBUG_MODULE, "[%s] Using EXPN command.", MODULE_NAME); strncpy(szVerb, "EXPN", 4); break; case VERB_RCPT: writeError(ERR_DEBUG_MODULE, "[%s] Using RCPT command.", MODULE_NAME); strncpy(szVerb, "RCPT TO:", 8); break; default: break; } if (strlen(szDomain) > 0) { sprintf((char *)bufSend, "%s %.250s@%.250s\r\n", szVerb, szAccount, szDomain); } else { sprintf((char *)bufSend, "%s %.250s\r\n", szVerb, szAccount); } if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szDomain); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Unknown SMTP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } if (strstr((char *)bufReceive, "250 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Found valid account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_RUNNING; } else if (strstr((char *)bufReceive, "252 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Found valid account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_RUNNING; } else if (strstr((char *)bufReceive, "550 Too many invalid recipients") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Too many invalid recipients: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else if (strstr((char *)bufReceive, "550 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Non-existant account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } else if (strstr((char *)bufReceive, "557 ") != NULL) /* 557 5.5.2 String does not match anything. */ { writeError(ERR_DEBUG_MODULE, "[%s] Non-existant account: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } else if (strstr((char *)bufReceive, "554 ") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Invalid domain name: %s", MODULE_NAME, szAccount); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } else { writeError(ERR_ERROR, "[%s] Unknown SMTP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } /* check if more data is waiting */ if (medusaDataReadyTimed(hSocket, 0, 20000) > 0) bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (strstr((char *)bufReceive, "421 Error: too many errors")) { writeError(ERR_DEBUG_MODULE, "[%s] Too many errors. Restarting connection.", MODULE_NAME); nRet = MSTATE_NEW; } FREE(bufReceive); setPassResult((*psLogin), szDomain); return(nRet); } jmk-foofus-medusa-dd62069/src/modsrc/smtp.c000066400000000000000000000705501460263104500206230ustar00rootroot00000000000000/* ** SMTP Authentication Daemon Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 pMonkey ** pMonkey ** ** Copyright (C) 2008 JoMo-Kun ** JoMo-Kun ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #include "ntlm.h" #define MODULE_NAME "smtp.mod" #define MODULE_AUTHOR "pmonkey@foofus.net" #define MODULE_SUMMARY_USAGE "Brute force module for SMTP Authentication with TLS" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: smtp.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_SMTP 25 #define PORT_SMTPS 465 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define AUTH_UNKNOWN 0 #define AUTH_PLAIN 1 #define AUTH_LOGIN 2 #define AUTH_NTLM 3 typedef struct __MODULE_DATA { char *szEHLO; int nAuthType; char* szDomain; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params); int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " EHLO:? [optional] "); writeVerbose(VB_NONE, " Specify the EHLO greeting."); writeVerbose(VB_NONE, " AUTH:? (Authentication Type (PLAIN/LOGIN/NTLM). Default: automatic)"); writeVerbose(VB_NONE, " Module will query service for accepted methods via an \"AUTH\" request."); writeVerbose(VB_NONE, " PLAIN, LOGIN, and NTLM authentication methods are supported."); writeVerbose(VB_NONE, " DOMAIN:? [optional]"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "The DOMAIN option should supply the specified domain appropriately,"); writeVerbose(VB_NONE, "regardless of authentication type. The domain can also be supplied "); writeVerbose(VB_NONE, "via the username field, but the format appears to differ by auth type."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: "); writeVerbose(VB_NONE, " \"medusa -M smtp -m AUTH:NTLM -U accounts.txt -p password\""); writeVerbose(VB_NONE, " \"medusa -M smtp -m EHLO:world -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr = NULL, *pOpt = NULL, *pOptTmp = NULL; _MODULE_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 3)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d).", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inAuthType = AUTH_PLAIN; else if (strcmp(pOpt, "LOGIN") == 0) psSessionData->nAuthType = AUTH_LOGIN; else if (strcmp(pOpt, "NTLM") == 0) psSessionData->nAuthType = AUTH_NTLM; else writeError(ERR_WARNING, "Invalid value for method AUTH."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = strdup(pOpt); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else if (strcmp(pOpt, "EHLO") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szEHLO = strdup(pOpt); } else writeError(ERR_WARNING, "Method EHLO requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else if (psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_SMTPS; else params.nPort = PORT_SMTP; initConnectionParams(psLogin, ¶ms); /* set EHLO, if not specified by user */ if (_psSessionData->szEHLO == NULL) { _psSessionData->szEHLO = malloc(5); memset(_psSessionData->szEHLO, 0, 5); sprintf(_psSessionData->szEHLO, "gerg"); } while (nState != MSTATE_COMPLETE) { switch(nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); if (psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(_psSessionData, hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: if ( medusaCheckSocket(hSocket, psLogin->psServer->psAudit->iSocketWait) ) { nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } } else { writeError(ERR_NOTICE, "[%s] Socket is no longer valid. Server likely dropped connection. Establishing new session.", MODULE_NAME); nState = MSTATE_NEW; if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initConnection(_MODULE_DATA *_psSessionData, int hSocket, sConnectParams *params) { unsigned char *bufSend = NULL; unsigned char *bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; /* Retrieve SMTP banner */ writeError(ERR_DEBUG_MODULE, "[%s] Retrieving SMTP banner.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] failed: Server did not respond with '220'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Send greeting to SMTP server */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP EHLO greeting.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szEHLO) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char *)bufSend, "EHLO %s\r\n", _psSessionData->szEHLO); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "250[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* If server supports STARTTLS and we are not already within a SSL connection, let's use it. */ if ((params->nUseSSL == 0) && (strstr((char *)bufReceive, "STARTTLS") != NULL)) { FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] Initiating STARTTLS session.", MODULE_NAME); bufSend = malloc(10 + 1); memset(bufSend, 0, 10 + 1); sprintf((char *)bufSend, "STARTTLS\r\n"); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '220'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } else { FREE(bufReceive); if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); return FAILURE; } /* Resend EHLO greeting as the AUTH types may have changed. */ writeError(ERR_DEBUG_MODULE, "[%s] Sending SMTP EHLO greeting.", MODULE_NAME); nSendBufferSize = 5 + strlen(_psSessionData->szEHLO) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char *)bufSend, "EHLO %s\r\n", _psSessionData->szEHLO); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "250[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] failed: Server did not respond with '250'. Exiting...", MODULE_NAME); FREE(bufReceive); return FAILURE; } } } /* Process SMTP supported authentication types */ if (_psSessionData->nAuthType != AUTH_UNKNOWN) { writeError(ERR_DEBUG_MODULE, "[%s] Ignoring server requested AUTH type and using user-specified value.", MODULE_NAME); } else if ((strstr((char *)bufReceive, "AUTH=LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr((char *)bufReceive, "AUTH=PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr((char *)bufReceive, "AUTH ") != NULL)) { if ((strstr((char *)bufReceive, "LOGIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: LOGIN"); _psSessionData->nAuthType = AUTH_LOGIN; } else if ((strstr((char *)bufReceive, "PLAIN") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: PLAIN"); _psSessionData->nAuthType = AUTH_PLAIN; } else if ((strstr((char *)bufReceive, "NTLM") != NULL)) { writeError(ERR_DEBUG_MODULE, "Detected authentication type: NTLM"); _psSessionData->nAuthType = AUTH_NTLM; } } else { writeError(ERR_ERROR, "%s failed: Server did not respond that it supported LOGIN, PLAIN or NTLM as an authentication type. Use the AUTH module option to force the use of an authentication type.", MODULE_NAME); return FAILURE; } FREE(bufReceive); return SUCCESS; } /* http://www.technoids.org/saslmech.html C: AUTH PLAIN S: 334 C: AHdlbGRvbgB3M2xkMG4= S: 235 2.0.0 OK Authenticated */ int sendAuthPLAIN(int hSocket, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; int nSendBufferSize = 0; int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "[%s] Initiating PLAIN Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTH PLAIN command --- */ bufSend = malloc(12 + 1); memset(bufSend, 0, 12 + 1); sprintf((char *)bufSend, "AUTH PLAIN\r\n"); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with a 334 response code */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server did not respond with \"334\" to AUTH PLAIN request.", MODULE_NAME); FREE(bufReceive); return FAILURE; } /* Send logon credentials: B64(USERNAME\0USERNAME\0PASSWORD) */ nSendBufferSize = strlen(szLogin) + 1 + strlen(szLogin) + 1 + strlen(szPassword); szTmpBuf = malloc(nSendBufferSize + 1); memset(szTmpBuf, 0, nSendBufferSize + 1); strcpy((char *)szTmpBuf, szLogin); strcpy((char *)szTmpBuf + strlen(szLogin) + 1, szLogin); strcpy((char *)szTmpBuf + strlen(szLogin) + 1 + strlen(szLogin) + 1, szPassword); szTmpBuf64 = malloc((2 * nSendBufferSize + 2) + 1); memset(szTmpBuf64, 0, (2 * nSendBufferSize + 2) + 1); base64_encode((char *)szTmpBuf, nSendBufferSize, (char *)szTmpBuf64); FREE(szTmpBuf); bufSend = malloc(strlen((char *)szTmpBuf64) + 2 + 1); memset(bufSend, 0, strlen((char *)szTmpBuf64) + 2 + 1); sprintf((char *)bufSend, "%s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); return SUCCESS; } /* http://www.technoids.org/saslmech.html C: AUTH LOGIN S: 334 VXNlcm5hbWU6 (Username:) C: d2VsZG9u (weldon) S: 334 UGFzc3dvcmQ6 (Password:) C: dzNsZDBu (w3ld0n) S: 235 2.0.0 OK Authenticated */ int sendAuthLOGIN(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufReceive = NULL; unsigned char* bufSend = NULL; unsigned char* szPrompt = NULL; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf2 = NULL; unsigned char* szLoginDomain = NULL; int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "[%s] Initiating LOGIN Authentication Attempt.", MODULE_NAME); /* --- Send initial AUTH LOGIN command --- */ bufSend = malloc(12 + 1); memset(bufSend, 0, 12 + 1); sprintf((char *)bufSend, "AUTH LOGIN\r\n"); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } FREE(bufSend); /* Server should respond with a base64-encoded username prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server did not respond with \"334\" to AUTH LOGIN request.", MODULE_NAME); FREE(bufReceive); return FAILURE; } if (((szTmpBuf = (unsigned char *)strstr((char *)bufReceive, "334")) == NULL) || ((szTmpBuf2 = (unsigned char *)index((char *)szTmpBuf, '\r')) == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server sent unexpected response to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } szTmpBuf2[0] = '\0'; szTmpBuf += 4; szPrompt = malloc(strlen((char *)szTmpBuf) + 1); memset(szPrompt, 0, strlen((char *)szTmpBuf) + 1); base64_decode((char *)szTmpBuf, (char *)szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] SMTP server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send username --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ if (_psSessionData->szDomain) { /* DOMAIN\USERNAME */ szLoginDomain = malloc(strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); memset(szLoginDomain, 0, strlen(_psSessionData->szDomain) + 1 + strlen(szLogin) + 1); sprintf((char *)szLoginDomain, "%s\\%s", _psSessionData->szDomain, szLogin); } else szLoginDomain = (unsigned char *)szLogin; writeError(ERR_DEBUG_MODULE, "[%s] Sending authenticate login value: %s %s", MODULE_NAME, szLoginDomain, szPassword); bufSend = malloc((2 * strlen((char *)szLoginDomain) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen((char *)szLoginDomain) + 2) + 2 + 1); base64_encode((char *)szLoginDomain, strlen((char *)szLoginDomain), (char *)bufSend); strcat((char *)bufSend, "\r\n"); if (_psSessionData->szDomain) FREE(szLoginDomain); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } /* Server should respond with a base64-encoded password prompt */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server did not respond with \"334\" to AUTH LOGIN request.", MODULE_NAME); FREE(bufReceive); return FAILURE; } if (((szTmpBuf = (unsigned char *)strstr((char *)bufReceive, "334")) == NULL) || ((szTmpBuf2 = (unsigned char *)index((char *)szTmpBuf, '\r')) == NULL)) { writeError(ERR_ERROR, "[%s] SMTP server sent unexpected response to AUTH LOGIN request.", MODULE_NAME); return FAILURE; } szTmpBuf2[0] = '\0'; szTmpBuf += 4; szPrompt = malloc(strlen((char *)szTmpBuf) + 1); memset(szPrompt, 0, strlen((char *)szTmpBuf) + 1); base64_decode((char *)szTmpBuf, (char *)szPrompt); FREE(bufReceive); writeError(ERR_DEBUG_MODULE, "[%s] SMTP server sent the following prompt: %s", MODULE_NAME, szPrompt); FREE(szPrompt); /* --- Send password --- */ /* Base64 encoded value can be up to 2x+2 original text. Leave additional space for "\r\n" and NULL */ bufSend = malloc((2 * strlen(szPassword) + 2) + 2 + 1); memset(bufSend, 0, (2 * strlen(szPassword) + 2) + 2 + 1); base64_encode((char *)szPassword, strlen((char *)szPassword), (char *)bufSend); strcat((char *)bufSend, "\r\n"); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] Failed: medusaSend was not successful", MODULE_NAME); } return SUCCESS; } /* http://davenport.sourceforge.net/ntlm.html#ntlmSmtpAuthentication */ int sendAuthNTLM(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; int nSendBufferSize = 0; tSmbNtlmAuthRequest sTmpReq; tSmbNtlmAuthChallenge sTmpChall; tSmbNtlmAuthResponse sTmpResp; unsigned char* szTmpBuf = NULL; unsigned char* szTmpBuf64 = NULL; writeError(ERR_DEBUG_MODULE, "[%s] Initiating NTLM Authentication Attempt.", MODULE_NAME); /* --- Send Base-64 encoded Type-1 message --- */ buildAuthRequest(&sTmpReq, 0, NULL, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpReq) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpReq) + 2); base64_encode((char *)&sTmpReq, SmbLength(&sTmpReq), (char *)szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] Sending initial challenge (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen((char *)szTmpBuf64) + 2; bufSend = malloc(10 + nSendBufferSize + 1); memset(bufSend, 0, 10 + nSendBufferSize + 1); sprintf((char *)bufSend, "AUTH NTLM %s\r\n", szTmpBuf64); FREE(szTmpBuf64); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(bufSend); /* Server should respond with a Base-64 encoded Type-2 challenge message. The challenge response format is "334", followed by a space, followed by the challenge message. */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^334[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Server did not send valid Type-2 challenge response.", MODULE_NAME); FREE(bufReceive); return FAILURE; } szTmpBuf = (unsigned char *)index((char *)bufReceive, '\r'); szTmpBuf[0] = '\0'; writeError(ERR_DEBUG_MODULE, "[%s] NTLM Challenge (B64 Encoded): %s", MODULE_NAME, bufReceive + 4); base64_decode((char *)bufReceive + 4, (char *)&sTmpChall); FREE(bufReceive); /* --- Calculate and send Base-64 encoded Type 3 response --- */ buildAuthResponse(&sTmpChall, &sTmpResp, 0, szLogin, szPassword, _psSessionData->szDomain, NULL); szTmpBuf64 = malloc(2 * SmbLength(&sTmpResp) + 2); memset(szTmpBuf64, 0, 2 * SmbLength(&sTmpResp) + 2); base64_encode((char *)&sTmpResp, SmbLength(&sTmpResp), (char *)szTmpBuf64); writeError(ERR_DEBUG_MODULE, "[%s] NTLM Response (B64 Encoded): %s", MODULE_NAME, szTmpBuf64); nSendBufferSize = strlen((char *)szTmpBuf64) + 2; bufSend = malloc(nSendBufferSize + 1); memset(bufSend, 0, nSendBufferSize + 1); sprintf((char *)bufSend, "%s\r\n", szTmpBuf64); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } FREE(szTmpBuf64); FREE(bufSend); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { int nRet = FAILURE; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; switch(_psSessionData->nAuthType) { case AUTH_PLAIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending PLAIN Authentication.", MODULE_NAME); nRet = sendAuthPLAIN(hSocket, szLogin, szPassword); break; case AUTH_LOGIN: writeError(ERR_DEBUG_MODULE, "[%s] Sending LOGIN Authentication.", MODULE_NAME); nRet = sendAuthLOGIN(hSocket, _psSessionData, szLogin, szPassword); break; case AUTH_NTLM: writeError(ERR_DEBUG_MODULE, "[%s] Sending NTLM Authentication.", MODULE_NAME); nRet = sendAuthNTLM(hSocket, _psSessionData, szLogin, szPassword); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3}[ -].*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Unknown SMTP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } if (strstr((char *)bufReceive, "235") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; nRet = MSTATE_EXITING; } /* 435 Unable to authenticate at present: Authentication Failure */ else if (strstr((char *)bufReceive, "435") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed (435).", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } /* GroupWise - 501 Authentication failed! */ else if (strstr((char *)bufReceive, "501") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed (501).", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } else if (strstr((char *)bufReceive, "535") != NULL) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed (535).", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; nRet = MSTATE_RUNNING; } else { writeError(ERR_ERROR, "[%s] Unknown SMTP server response: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; nRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(nRet); } jmk-foofus-medusa-dd62069/src/modsrc/snmp.c000066400000000000000000000652511460263104500206170ustar00rootroot00000000000000/* ** SNMPv1/2C Community String Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on ideas from: ** Hydra 5.2 [van Hauser ] ** onesixtyone [solareclipse@phreedom.org] ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "snmp.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for SNMP Community Strings" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: snmp.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_SNMP 161 #define SNMP_VER_V1 1 #define SNMP_VER_V2C 2 #define SNMP_READ 1 #define SNMP_WRITE 2 #define SNMP_SUCCESS_READ 1 #define SNMP_SUCCESS_WRITE 2 #define SEND_DELAY 200 /* Delay between sending SNMP requests (usec) */ #define RECEIVE_DELAY 5*1000000 /* Response wait time (usec) */ typedef struct __SNMP_DATA { int nVersion; int nReadWrite; int nReadTimeout; int nSendDelay; } _SNMP_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE, MSTATE_FAILURE }; // Forward declarations int sendRead(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword); int sendWrite(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword, char* szLocation); int receiveRequest(int hSocket, _SNMP_DATA* _psSessionData, int* nPassCount, char*** arrszPassList, char** szLocation); int initModule(sLogin* login, _SNMP_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " TIMEOUT:? "); writeVerbose(VB_NONE, " Sets the number of seconds to wait for the UDP responses (default: 5 sec)."); writeVerbose(VB_NONE, " SEND_DELAY:? "); writeVerbose(VB_NONE, " Sets the number of microseconds to wait between sending queries (default: 200 usec)."); writeVerbose(VB_NONE, " VERSION:? (1*, 2C)"); writeVerbose(VB_NONE, " Set the SNMP client version."); writeVerbose(VB_NONE, " ACCESS:? (READ*, WRITE)"); writeVerbose(VB_NONE, " Set level of access to test for with the community string."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "(*) Default value"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "It should be noted that when testing for WRITE capability, the module will read"); writeVerbose(VB_NONE, "the current value of sysLocation and then write that same value back to the system."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Since SNMP is a UDP-based protocol, there is no handshaking between sending and "); writeVerbose(VB_NONE, "receiving transport-layer entities. Due to this connectionless communication, about"); writeVerbose(VB_NONE, "the only time we know a SNMP service exists, is if we send the correct community"); writeVerbose(VB_NONE, "string and the server sends a response. All other queries result in no response"); writeVerbose(VB_NONE, "whatsoever. The approach we use here is to initially just send all of our SNMP GET"); writeVerbose(VB_NONE, "requests. After that completes, we wait TIMEOUT seconds for any responses. If we"); writeVerbose(VB_NONE, "get any responses back, we examine them to see which community strings were successful."); writeVerbose(VB_NONE, "If ACCESS:WRITE was specified, we check for write access on each of the previously"); writeVerbose(VB_NONE, "successful values. This techique should allow for quick brute forcing. However, one"); writeVerbose(VB_NONE, "should take care with the TIMEOUT and SEND_DELAY values as to avoid causing issues"); writeVerbose(VB_NONE, "with the target service or missing response data."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M snmp -m TIMEOUT:2 -m ACCESS:WRITE\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _SNMP_DATA *psSessionData; psSessionData = malloc(sizeof(_SNMP_DATA)); memset(psSessionData, 0, sizeof(_SNMP_DATA)); psSessionData->nVersion = SNMP_VER_V1; psSessionData->nReadWrite = SNMP_READ; psSessionData->nReadTimeout = RECEIVE_DELAY; psSessionData->nSendDelay = SEND_DELAY; if ((argc < 0) || (argc > 4)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inReadTimeout = atoi(pOpt) * 1000000; else writeError(ERR_WARNING, "Method TIMEOUT requires value to be set."); } else if (strcmp(pOpt, "SEND_DELAY") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) psSessionData->nSendDelay = atoi(pOpt); else writeError(ERR_WARNING, "Method TIMEOUT requires value to be set."); } else if (strcmp(pOpt, "VERSION") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method VERSION requires value to be set."); else if ( strcmp(pOpt, "1") == 0 ) psSessionData->nVersion = SNMP_VER_V1; else if ( strcmp(pOpt, "2C") == 0 ) psSessionData->nVersion = SNMP_VER_V2C; else writeError(ERR_WARNING, "Method VERSION requires a value of either \"1\" or \"2C\" to be set."); } else if (strcmp(pOpt, "ACCESS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if (pOpt == NULL) writeError(ERR_WARNING, "Method ACCESS requires value to be set."); else if ( strcmp(pOpt, "READ") == 0 ) psSessionData->nReadWrite = SNMP_READ; else if ( strcmp(pOpt, "WRITE") == 0 ) psSessionData->nReadWrite = SNMP_WRITE; else writeError(ERR_WARNING, "Method ACCESS requires value of \"READ\" or \"WRITE\" to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SNMP_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int i = 0, nPassCount, nPassCountWrite; char **arrszPassList = NULL; char **arrszPassListWrite = NULL; char *szLocation = NULL; sCredentialSet *psCredSet = NULL; sUser *psUser = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_SNMP; initConnectionParams(psLogin, ¶ms); writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s", MODULE_NAME, psLogin->psServer->pHostIP); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnectUDP(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = sendRead(hSocket, _psSessionData, psCredSet->pPass); if (nState == MSTATE_FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* don't want to overwhelm the device being tested */ writeError(ERR_DEBUG_MODULE, "Delaying %d microseconds before sending next query.", _psSessionData->nSendDelay); usleep(_psSessionData->nSendDelay); /* initially set all passwords as invalid -- we don't know their validity yet */ psLogin->iResult = LOGIN_RESULT_FAIL; setPassResult(psLogin, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); /* Medusa has exhausted all credential sets and reset psLogin->psUser to NULL. This creates issues as we haven't actually received the responses yet from our SNMP queries. Our solution is to create a temporary sUser structure, which allows us to report on successful community strings via normal methods. */ psUser = malloc(sizeof(sUser)); memset(psUser, 0, sizeof(sUser)); psLogin->psUser = psUser; nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_RUNNING; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } /* check if server responded to GET queries */ writeError(ERR_DEBUG_MODULE, "[%s] Checking for server responses.", MODULE_NAME); if (receiveRequest(hSocket, _psSessionData, &nPassCount, &arrszPassList, &szLocation) == FAILURE) { writeError(ERR_DEBUG_MODULE, "[%s] Failed to find valid READ community string.", MODULE_NAME); return SUCCESS; } for (i=0; i < nPassCount; i++) { writeError(ERR_DEBUG_MODULE, "[%s] Located valid community string (%d/%d): %s.", MODULE_NAME, i+1, nPassCount, arrszPassList[i]); if (_psSessionData->nReadWrite == SNMP_WRITE) { writeError(ERR_DEBUG_MODULE, "[%s] Checking if community string has WRITE access.", MODULE_NAME); /* send SET request to server */ if (sendWrite(hSocket, _psSessionData, arrszPassList[i], szLocation)) { writeError(ERR_ERROR, "[%s] Failed to send SET request.", MODULE_NAME); return FAILURE; } FREE(szLocation); /* check if community string has WRITE access */ if (receiveRequest(hSocket, _psSessionData, &nPassCountWrite, &arrszPassListWrite, &szLocation) == SUCCESS) { writeError(ERR_DEBUG_MODULE, "[%s] Located valid WRITE community string: %s.", MODULE_NAME, arrszPassList[i]); psLogin->iResult = LOGIN_RESULT_SUCCESS; setPassResult(psLogin, arrszPassList[i]); } else { writeError(ERR_ERROR, "[%s] Community string appears to have only READ access.", MODULE_NAME); psLogin->iResult = LOGIN_RESULT_ERROR; setPassResult(psLogin, arrszPassList[i]); } FREE(arrszPassListWrite); } else { writeError(ERR_DEBUG_MODULE, "[%s] Located valid READ community string: %s.", MODULE_NAME, arrszPassList[i]); psLogin->iResult = LOGIN_RESULT_SUCCESS; setPassResult(psLogin, arrszPassList[i]); } FREE(arrszPassList[i]); FREE(szLocation); } if (hSocket > 0) medusaDisconnect(hSocket); FREE(psUser); FREE(psCredSet); FREE(arrszPassList); FREE(arrszPassListWrite); return SUCCESS; } /* Module Specific Functions */ /* http://book.opensourceproject.org.cn/embedded/tcpipembedded/opensource/0061.html The first TLV in the request is called sequence and is used to identify the length of the following TLVs. The sequence type is 0x30 and the next octet is used to decode the length of this TLV. If the length octet has the high-order bit set (0x80), then the length octet masked with 0x7f yields the number of bytes that follow that will make up the value length (in big-endian order). If the high-order bit is not set, then this octet is the length (no length octets follow). Example: 0x30 0x2f 0x02 0x01 0x00 Sequence: 0x30 0x2f Version: 0x02 0x01 0x00 Example: 0x30 0x82 0x00 0x2f 0x02 0x01 0x00 Sequence: 0x30 0x82 0x00 0x2f Version: 0x02 0x01 0x00 */ int parseLength(unsigned char* bufReceive) { int nLength = 0; int nOctets = 0; if (bufReceive[0] == 0x30) { if (bufReceive[1] & 0x80) /* multi-octet mode */ { nOctets = bufReceive[1] & 0x7f; /* limited to 4 octets worth of length data */ if (nOctets == 1) nLength = bufReceive[2]; else if (nOctets == 2) nLength = (bufReceive[2] << 8) + bufReceive[3]; else if (nOctets == 3) nLength = (bufReceive[2] << 16) + (bufReceive[3] << 8) + bufReceive[4]; else if (nOctets == 4) nLength = (bufReceive[2] << 24) + (bufReceive[3] << 16) + (bufReceive[4] << 8) + bufReceive[5]; if ((nLength > 0) && ((bufReceive[2+nOctets] == 0x02) && (bufReceive[2+nOctets+1] == 0x01))) writeError(ERR_DEBUG_MODULE, "[%s] Multi-octet mode length: %d", MODULE_NAME, nLength); else { writeError(ERR_ERROR, "[%s] Failed to parse length or SNMP version (multi-octet mode).", MODULE_NAME); nLength = -1; } } else if ((bufReceive[2] == 0x02) && (bufReceive[3] == 0x01)) /* single octet mode, version check */ { nLength = bufReceive[1]; writeError(ERR_DEBUG_MODULE, "[%s] Single octet mode length: %d", MODULE_NAME, nLength); } else { writeError(ERR_ERROR, "[%s] Failed to parse length or SNMP version.", MODULE_NAME); nLength = -1; } } return nLength; } int countResponses(int nReceiveBufferSize, unsigned char* bufReceive) { int i = 0; int nLength = 0; int nResponseCount = 0; for (i = 0; i < nReceiveBufferSize; i++) { if (bufReceive[i] == 0x30) { nLength = parseLength(&bufReceive[i]); if (nLength > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Located start of SNMP response (%d bytes).", MODULE_NAME, nLength); nResponseCount++; i += nLength; } } } return nResponseCount; } int processResponse(int nReceiveBufferSize, unsigned char* bufReceive, int *nSNMPLength, char** szPassword, char** szLocation) { int i; writeError(ERR_DEBUG_MODULE, "[%s] Parsing SNMP response data.", MODULE_NAME); for (i = 0; i < nReceiveBufferSize; i++) { *nSNMPLength = parseLength(&bufReceive[i]); if (*nSNMPLength > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Located start of SNMP response (%d bytes).", MODULE_NAME, *nSNMPLength); for (; i < nReceiveBufferSize; i++) { if (bufReceive[i] == 0x04) { writeError(ERR_DEBUG_MODULE, "[%s] Located start of SNMP community string.", MODULE_NAME); if (bufReceive[i+1] > 0) { writeError(ERR_DEBUG_MODULE, "[%s] Located SNMP community string size: %d.", MODULE_NAME, bufReceive[i+1]); *szPassword = malloc(bufReceive[i+1] + 1); memset(*szPassword, 0, bufReceive[i+1] + 1); memcpy(*szPassword, bufReceive + i + 2, bufReceive[i+1]); writeError(ERR_DEBUG_MODULE, "[%s] Located community string: %s.", MODULE_NAME, *szPassword); } else { writeError(ERR_DEBUG_MODULE, "[%s] Failed to locate community string.", MODULE_NAME); return FAILURE; } for (i = i + bufReceive[i + 1]; i + 2 < nReceiveBufferSize; i++) { /* skip community string */ if (bufReceive[i] == 0xa2) { writeError(ERR_DEBUG_MODULE, "[%s] Located PDU Response.", MODULE_NAME); for (; i + 2 < nReceiveBufferSize; i++) { if (bufReceive[i] == 0x02) { writeError(ERR_DEBUG_MODULE, "[%s] Located ID.", MODULE_NAME); for (i = i + (bufReceive[i + 1]); i + 2 < nReceiveBufferSize; i++) { /* skip Request ID */ if ((bufReceive[i] == 0x02) && (bufReceive[i + 1] == 0x01) && (bufReceive[i + 2] == 0x00)) { writeError(ERR_DEBUG_MODULE, "[%s] Located success status flag.", MODULE_NAME); *szLocation = malloc(bufReceive[i + 6 + 14 + 1] + 1); memset(*szLocation, 0, bufReceive[i + 6 + 14 + 1] + 1); memcpy(*szLocation, bufReceive + i + 6 + 14 + 2, bufReceive[i + 6 + 14 + 1]); writeError(ERR_DEBUG_MODULE, "[%s] sysLocation: %s.", MODULE_NAME, *szLocation); return(SUCCESS); } } } } } } } } } } return FAILURE; } int sendRead(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword) { unsigned char* bufSend; int nSendBufferSize = 0; struct _SNMPV1_A { char ID; char len; char ver[3]; char comid; char comlen; } snmpv1_a = { .ID = '\x30', .len = '\x00', .ver = "\x02\x01\x00", /* \x02\x01\x01 for snmp v2c */ .comid = '\x04', .comlen = '\x00' }; struct _SNMPV1_R { char type[2]; char identid[2]; char ident[4]; char errstat[3]; char errind[3]; char objectid[2]; char object[12]; char value[3]; } snmpv1_r = { .type = "\xa0\x1c", /* GET */ .identid = "\x02\x04", .ident = "\x6f\x67\x4e\xe1", /* request id - doesn't matter */ .errstat = "\x02\x01\x00", /* no error */ .errind = "\x02\x01\x00", /* error index 0 */ .objectid = "\x30\x0e", .object = "\x30\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x06\x00", /* sysLocation */ .value = "\x05\x00" /* we just read, so value = 0 */ }; if (_psSessionData->nVersion == SNMP_VER_V2C) snmpv1_a.ver[2] = '\x01'; /* GET system.sysLocation */ nSendBufferSize = sizeof(snmpv1_a) + sizeof(snmpv1_r) + strlen(szPassword); snmpv1_a.comlen = (char) strlen(szPassword); snmpv1_a.len = nSendBufferSize - 3; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend, &snmpv1_a, sizeof(snmpv1_a)); memcpy(bufSend + sizeof(snmpv1_a), szPassword, strlen(szPassword)); memcpy(bufSend + sizeof(snmpv1_a) + strlen(szPassword), &snmpv1_r, sizeof(snmpv1_r)); writeError(ERR_DEBUG_MODULE, "[%s] Sending GET request for system.sysLocation.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize - 1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); free(bufSend); return(MSTATE_FAILURE); } free(bufSend); return(MSTATE_RUNNING); } int sendWrite(int hSocket, _SNMP_DATA* _psSessionData, char* szPassword, char* szLocation) { unsigned char* bufSend; int nSendBufferSize = 0; struct _SNMPV1_A { char ID; char len; char ver[3]; char comid; char comlen; } snmpv1_a = { .ID = '\x30', .len = '\x00', .ver = "\x02\x01\x00", /* \x02\x01\x01 for snmp v2c */ .comid = '\x04', .comlen = '\x00' }; struct _SNMPV1_W { char type[2]; char identid[2]; char ident[4]; char errstat[3]; char errind[3]; char objectid[2]; char object[12]; char value[2]; } snmpv1_w = { .type = "\xa3\x20", /* SET */ .identid = "\x02\x04", .ident = "\x6f\x67\x4e\xe1", /* request id - doesn't matter */ .errstat = "\x02\x01\x00", /* no error */ .errind = "\x02\x01\x00", /* error index 0 */ .objectid = "\x30\x0c", .object = "\x30\x0c\x06\x08\x2b\x06\x01\x02\x01\x01\x06\x00", /* sysLocation */ .value = "\x04\x00" /* write value */ }; if (_psSessionData->nVersion == SNMP_VER_V2C) snmpv1_a.ver[2] = '\x01'; if (szLocation == NULL) szLocation = ""; nSendBufferSize = sizeof(snmpv1_a) + sizeof(snmpv1_w) + strlen(szPassword) + strlen(szLocation) + 1; snmpv1_a.comlen = (char) strlen(szPassword); snmpv1_a.len = nSendBufferSize - 3; bufSend = malloc(nSendBufferSize); memset(bufSend, 0, nSendBufferSize); memcpy(bufSend, &snmpv1_a, sizeof(snmpv1_a)); memcpy(bufSend + sizeof(snmpv1_a), szPassword, strlen(szPassword)); memcpy(bufSend + sizeof(snmpv1_a) + strlen(szPassword), &snmpv1_w, sizeof(snmpv1_w)); memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + 1, 28 + strlen(szLocation), 1); /* set length remaining */ memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + 15, 14 + strlen(szLocation), 1); /* set length remaining */ memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + 17, 12 + strlen(szLocation), 1); /* set length remaining */ memset(bufSend + sizeof(snmpv1_a) + strlen(szPassword) + sizeof(snmpv1_w) - 1, strlen(szLocation), 1); strcpy((char *)bufSend + sizeof(snmpv1_a) + strlen(szPassword) + sizeof(snmpv1_w), szLocation); writeError(ERR_DEBUG_MODULE, "[%s] Sending SET request for system.sysLocation.", MODULE_NAME); if (medusaSend(hSocket, bufSend, nSendBufferSize - 1, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); free(bufSend); return(FAILURE); } free(bufSend); return(SUCCESS); } int receiveRequest(int hSocket, _SNMP_DATA* _psSessionData, int* nPassCount, char*** arrszPassList, char** szLocation) { unsigned char *bufReceive = NULL; unsigned char *bufReceiveTmp = NULL; int i, nReceiveBufferSize, nReceiveBufferSizeTmp; int nResponse = FAILURE; int nSNMPLength; nReceiveBufferSize = 0; bufReceive = medusaReceiveRawDelay(hSocket, &nReceiveBufferSize, _psSessionData->nReadTimeout, _psSessionData->nReadTimeout); if (bufReceive == NULL) { writeError(ERR_DEBUG_MODULE, "[%s] No data received. Possible incorrect community string.", MODULE_NAME); return(FAILURE); } *nPassCount = countResponses(nReceiveBufferSize, bufReceive); if (*nPassCount <= 0) { writeError(ERR_ERROR, "[%s] Responses received, however, no community strings were located.", MODULE_NAME); return(FAILURE); } else { writeError(ERR_DEBUG_MODULE, "[%s] Creating password array for %d entries.", MODULE_NAME, *nPassCount); *arrszPassList = malloc(*nPassCount * sizeof(char*)); memset(*arrszPassList, 0, *nPassCount * sizeof(char*)); } bufReceiveTmp = bufReceive; nReceiveBufferSizeTmp = nReceiveBufferSize; for (i = 0; i < *nPassCount; i++) { writeError(ERR_DEBUG_MODULE, "[%s] Retrieving data for response: %d.", MODULE_NAME, i+1); nResponse = processResponse(nReceiveBufferSizeTmp, bufReceiveTmp, &nSNMPLength, &(*arrszPassList)[i], szLocation); if (nResponse == SUCCESS) { writeError(ERR_DEBUG_MODULE, "[%s] Retrieved SNMP data (%d bytes). Community String: %s Location: %s.", MODULE_NAME, nSNMPLength, (*arrszPassList)[i], *szLocation); } else writeError(ERR_ERROR, "[%s] Error processing SNMP response (%d).", MODULE_NAME, i+1); bufReceiveTmp += (nSNMPLength + 2); nReceiveBufferSizeTmp -= (nSNMPLength + 2); } free(bufReceive); return(nResponse); } jmk-foofus-medusa-dd62069/src/modsrc/ssh.c000066400000000000000000000502101460263104500204240ustar00rootroot00000000000000/* ** SSH v2 Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** This module requires libssh2 (www.libssh2.org). ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "ssh.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for SSH v2 sessions" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: ssh.c 9260 2015-05-27 21:52:57Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBSSH2_WARNING "No usable LIBSSH2. Module disabled." #ifdef HAVE_LIBSSH2 #include #define PORT_SSH 22 #define SSH_AUTH_UNDEFINED 1 #define SSH_AUTH_KBDINT 2 #define SSH_AUTH_PASSWORD 3 #define SSH_AUTH_ERROR 4 #define SSH_CONN_UNKNOWN 1 #define SSH_CONN_ESTABLISHED 2 typedef struct __SSH2_DATA { char *szBannerMsg; int iConnectionStatus; } _SSH2_DATA; typedef struct __ssh2_session_data { char *pPass; int iAnswerCount; } _ssh2_session_data; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(_SSH2_DATA* _psSessionData, LIBSSH2_SESSION *session, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login, _SSH2_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " BANNER:? (Libssh client banner. Default SSH-2.0-MEDUSA.)"); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M ssh -m BANNER:SSH-2.0-FOOBAR\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _SSH2_DATA *psSessionData = NULL; psSessionData = malloc(sizeof(_SSH2_DATA)); memset(psSessionData, 0, sizeof(_SSH2_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszBannerMsg = strdup(pOpt); } else { writeError(ERR_WARNING, "Method BANNER requires value to be set."); } } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SSH2_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int i = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; LIBSSH2_SESSION *session = NULL; char *pErrorMsg; int iErrorMsg; _psSessionData->iConnectionStatus = SSH_CONN_UNKNOWN; _ssh2_session_data ssh2_session_data; ssh2_session_data.pPass = NULL; ssh2_session_data.iAnswerCount = 0; memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_SSH; initConnectionParams(psLogin, ¶ms); /* Retrieve next available credential set to test */ psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME, psLogin->psServer->pHostIP); nState = MSTATE_COMPLETE; } /* libssh2_init uses a global state, and is not thread safe */ pthread_mutex_lock(&psLogin->psServer->psAudit->ptmMutex); if (libssh2_init(0)) { writeError(ERR_ERROR, "%s: Failed initiating SSH library: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); psLogin->iResult = LOGIN_RESULT_UNKNOWN; pthread_mutex_unlock(&psLogin->psServer->psAudit->ptmMutex); return FAILURE; } pthread_mutex_unlock(&psLogin->psServer->psAudit->ptmMutex); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* Create a session instance and start it up This will trade welcome banners, exchange keys, and setup crypto, compression, and MAC layers */ if (session) { writeError(ERR_DEBUG_MODULE, "%s: Destroying previous SSH session structure: Host: %s User: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } session = libssh2_session_init_ex(NULL, NULL, NULL, &ssh2_session_data); if (!session) { writeError(ERR_ERROR, "%s: Failed initiating SSH session: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* Set client SSH banner */ if (_psSessionData->szBannerMsg) { if ((strncmp(_psSessionData->szBannerMsg, "SSH-2.0-", 8) != 0) || (strlen(_psSessionData->szBannerMsg) > 253)) { writeError(ERR_ERROR, "[%s] The selected banner could be rejected be some SSH servers. The banner should begin with \"SSH-2.0-\" and be shorter than 253 characters.", MODULE_NAME); } } else { _psSessionData->szBannerMsg = malloc(20); memset(_psSessionData->szBannerMsg, 0, 20); sprintf(_psSessionData->szBannerMsg, "SSH-2.0-MEDUSA_1.0"); } writeError(ERR_DEBUG_MODULE, "Attempting to set banner: %s", _psSessionData->szBannerMsg); if ( libssh2_banner_set(session, _psSessionData->szBannerMsg) ) { writeError(ERR_DEBUG_MODULE, "Failed to set libssh banner."); } /* Initiate SSH session connection - retry if necessary */ writeError(ERR_DEBUG_MODULE, "Attempting to initiate SSH session."); for (i = 1; i <= psLogin->psServer->psHost->iRetries + 1; i++) { if (hSocket > 0) { medusaDisconnect(hSocket); } hSocket = medusaConnect(¶ms); if ( hSocket < 0 ) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (libssh2_session_startup(session, hSocket)) { writeError(ERR_ERROR, "%s: Failed establishing SSH session (%d/%d): Host: %s User: %s Pass: %s", MODULE_NAME, i, psLogin->psServer->psHost->iRetries + 1, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); libssh2_session_last_error(session, &pErrorMsg, &iErrorMsg, 1); if ( (pErrorMsg) && (strstr(pErrorMsg, "Unable to exchange encryption keys")) ) { writeError(ERR_ERROR, "[%s] Failed to exchange encryption keys. Are you sure this is a SSHv2 server?", MODULE_NAME); i = psLogin->psServer->psHost->iRetries + 1; } else if (pErrorMsg) { writeError(ERR_DEBUG_MODULE, "libssh2 Error Message: %s", pErrorMsg); } if (i == psLogin->psServer->psHost->iRetries + 1) { if (addMissedCredSet(psLogin, psCredSet) == SUCCESS) writeError(ERR_ERROR, "%s: Failed establishing SSH session. The following credentials have been added to the missed queue for later testing: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); else writeError(ERR_ERROR, "%s: Failed establishing SSH session. The following credentials were NOT tested: Host: %s User: %s Pass: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser, psCredSet->pPass); if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } sleep(psLogin->psServer->psHost->iRetryWait); } else { break; } } writeError(ERR_DEBUG_MODULE, "Id: %d successfully established connection.", psLogin->iId); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: ssh2_session_data.pPass = psCredSet->pPass; ssh2_session_data.iAnswerCount = 0; nState = tryLogin(_psSessionData, session, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } if (hSocket > 0) { medusaDisconnect(hSocket); hSocket = -1; } nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (session) { libssh2_session_disconnect(session, ""); libssh2_session_free(session); session = NULL; } if (hSocket > 0) { medusaDisconnect(hSocket); hSocket = -1; } psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } void response_callback(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract) { (void) name; (void) name_len; (void) instruction; (void) instruction_len; int i; char *pPass = ((_ssh2_session_data*)(*abstract))->pPass; if (((_ssh2_session_data*)(*abstract))->iAnswerCount > 0) { writeError(ERR_DEBUG_MODULE, "libssh2 response_callback: sshd asked a question, but we've already given out answer."); } else { for (i=0; iiAnswerCount++; } else { writeError(ERR_ERROR, "%s received an unknown SSH prompt: %s", MODULE_NAME, prompts[i].text); } } } } int tryLogin(_SSH2_DATA* _psSessionData, LIBSSH2_SESSION *session, sLogin** psLogin, char* szLogin, char* szPassword) { char *pErrorMsg = NULL; int iErrorMsg, iAuthMode, iRet; void (*pResponseCallback) (); char *strtok_ptr = NULL; char *pAuth = NULL; pResponseCallback = response_callback; /* Password authentication failure delay: 2 Password authentication maximum tries: 3 Keyboard-interactive authentication failure delay: 2 Keyboard-interactive authentication maximum tries: 3 */ /* libssh2 supports: none, password, publickey, hostbased, keyboard-interactive */ iAuthMode = SSH_AUTH_UNDEFINED; /* libssh2_userauth_list returns session->userauth_list_data libssh2_session_free() call will handle releasing all session data, including userauth_list_data */ pErrorMsg = libssh2_userauth_list(session, szLogin, strlen(szLogin)); if (pErrorMsg) { writeError(ERR_DEBUG_MODULE, "Supported user-auth modes: %s.", pErrorMsg); pAuth = strtok_r(pErrorMsg, ",", &strtok_ptr); while (pAuth) { if (strcmp(pAuth, "password") == 0) { writeError(ERR_DEBUG_MODULE, "Server supports user-auth type: password"); iAuthMode = SSH_AUTH_PASSWORD; _psSessionData->iConnectionStatus = SSH_CONN_ESTABLISHED; break; } else if (strcmp(pAuth, "keyboard-interactive") == 0) { writeError(ERR_DEBUG_MODULE, "Server supports user-auth type: keyboard-interactive"); iAuthMode = SSH_AUTH_KBDINT; _psSessionData->iConnectionStatus = SSH_CONN_ESTABLISHED; break; } pAuth = strtok_r(NULL, ",", &strtok_ptr); } } else if (_psSessionData->iConnectionStatus == SSH_CONN_ESTABLISHED) { writeError(ERR_DEBUG_MODULE, "Failed to retrieve supported authentication modes. Since previous connections worked, restarting entire session and attempting again."); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_NEW; return(iRet); } else { writeError(ERR_ERROR, "Failed to retrieve supported authentication modes. Aborting..."); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_EXITING; } switch (iAuthMode) { case SSH_AUTH_KBDINT: if (libssh2_userauth_keyboard_interactive(session, szLogin, pResponseCallback) ) { writeError(ERR_DEBUG_MODULE, "Keyboard-Interactive authentication failed: Host: %s User: %s Pass: %s", (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_DEBUG_MODULE, "Keyboard-Interactive authentication succeeded: Host: %s User: %s Pass: %s", (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } break; case SSH_AUTH_PASSWORD: if (libssh2_userauth_password(session, szLogin, szPassword)) { libssh2_session_last_error(session, &pErrorMsg, &iErrorMsg, 1); writeError(ERR_DEBUG_MODULE, "Password-based authentication failed: %s: Host: %s User: %s Pass: %s", pErrorMsg, (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_RUNNING; } else { writeError(ERR_DEBUG_MODULE, "Password-based authentication succeeded: Host: %s User: %s Pass: %s", (*psLogin)->psServer->pHostIP, szLogin, szPassword); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } break; default: writeError(ERR_ERROR, "No supported authentication methods located."); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; iRet = MSTATE_EXITING; break; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBSSH2_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBSSH2_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is libssh2 (www.libssh2.org) installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is libssh2 (www.libssh2.org) installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/svn.c000066400000000000000000000354031460263104500204440ustar00rootroot00000000000000/* ** Subversion Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Subversion (1.2.3):/tools/examples/minimal_client.c ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "svn.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for Subversion sessions" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: svn.c 9235 2015-05-18 22:07:45Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define LIBSVN_WARNING "No usable LIBSVN. Module disabled." #ifdef HAVE_LIBSVN_CLIENT_1 #include "subversion-1/svn_client.h" #include "subversion-1/svn_pools.h" #include "subversion-1/svn_config.h" #include "subversion-1/svn_cmdline.h" #include "subversion-1/svn_dirent_uri.h" #define PORT_SVN 3690 typedef struct __SVN_DATA { char *szURL; char *szBranch; } _SVN_DATA; /* Tells us whether we are to continue processing or not */ enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; /* Forward declarations */ int tryLogin(sLogin** login, _SVN_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _SVN_DATA *_psSessionData); /* Tell medusa how many parameters this module allows */ int getParamNumber() { return 0; // we don't need no stinking parameters } /* Displays information about the module and how it must be used */ void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " BRANCH:? "); writeVerbose(VB_NONE, " Sets URL branch to authenticate against. For example, svn://host/branch."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M svn -m BRANCH:test_project\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _SVN_DATA *psSessionData; psSessionData = malloc(sizeof(_SVN_DATA)); memset(psSessionData, 0, sizeof(_SVN_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszBranch = strdup(pOpt); } else writeError(ERR_WARNING, "Method BRANCH requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _SVN_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); params.nPort = PORT_SVN; initConnectionParams(psLogin, ¶ms); /* set URL - branch, if not specified by user */ if (_psSessionData->szBranch == NULL) { //_psSessionData->szBranch = malloc(6); //memset(_psSessionData->szBranch, 0, 6); //sprintf(_psSessionData->szBranch, "trunk"); _psSessionData->szBranch = malloc(2); memset(_psSessionData->szBranch, 0, 2); sprintf(_psSessionData->szBranch, "/"); } _psSessionData->szURL = malloc(strlen(psLogin->psServer->pHostIP) + log(params.nPort) + strlen(_psSessionData->szBranch) + 10); memset(_psSessionData->szURL, 0, strlen(psLogin->psServer->pHostIP) + log(params.nPort) + strlen(_psSessionData->szBranch) + 10); sprintf(_psSessionData->szURL, "svn://%s:%d/%s", psLogin->psServer->pHostIP, params.nPort, _psSessionData->szBranch); writeError(ERR_DEBUG_MODULE, "[%s] Set URL: %s", MODULE_NAME, _psSessionData->szURL); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* simply check if server exists */ if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } /* close the connection since libsvn does its own thing */ medusaDisconnect(hSocket); hSocket = -1; writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(&psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(_psSessionData->szURL); FREE(_psSessionData->szBranch); FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ static svn_error_t * svn_prompt_callback (svn_auth_cred_simple_t **cred, void *baton __attribute__((unused)), const char *realm __attribute__((unused)), const char *username __attribute__((unused)), svn_boolean_t may_save __attribute__((unused)), apr_pool_t *pool) { svn_auth_cred_simple_t *ret = apr_pcalloc (pool, sizeof (*ret)); *cred = ret; return SVN_NO_ERROR; } static svn_error_t * print_dirent(void *baton __attribute__((unused)), const char *path __attribute__((unused)), const svn_dirent_t *dirent __attribute__((unused)), const svn_lock_t *lock __attribute__((unused)), const char *abs_path __attribute__((unused)), const char *external_parent_url __attribute__((unused)), const char *external_target __attribute__((unused)), apr_pool_t *pool __attribute__((unused))) { return SVN_NO_ERROR; } int tryLogin(sLogin** psLogin, _SVN_DATA* _psSessionData, char* szLogin, char* szPassword) { int iRet; apr_pool_t *pool; svn_error_t *err; svn_opt_revision_t revision; svn_client_ctx_t *ctx; const char *canonical; /* Initialize the application. Send all error messages to 'stderr'. */ if (svn_cmdline_init("MEDUSA", stderr) != EXIT_SUCCESS) { writeError(ERR_ERROR, "[%s] LIBSVN svn_cmdline_init() Function Failed.", MODULE_NAME); return(FAILURE); } /* Create top-level memory pool. -- must this be thread-safe??? */ pool = svn_pool_create(NULL); /* Initialize and allocate the client_ctx object. */ #ifdef HAVE_SVN_CLIENT_LIST3 if ((err = svn_client_create_context2(&ctx, NULL, pool))) #else if ((err = svn_client_create_context (&ctx, pool))) #endif { writeError(ERR_ERROR, "[%s] LIBSVN svn_client_create_context() Function Failed.", MODULE_NAME); //svn_handle_error2 (err, stderr, FALSE, "MEDUSA: "); return(FAILURE); } svn_auth_provider_object_t *provider; apr_array_header_t *providers = apr_array_make(pool, 1, sizeof (svn_auth_provider_object_t *)); /* Set callback to not retry authentication */ svn_auth_get_simple_prompt_provider(&provider, svn_prompt_callback, NULL, 0, pool); APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider; /* Register the auth-providers into the context's auth_baton. */ svn_auth_open (&ctx->auth_baton, providers, pool); /* Set logon credentials using the auth_baton's run-time parameter hash */ svn_auth_set_parameter(ctx->auth_baton, SVN_AUTH_PARAM_DEFAULT_USERNAME, szLogin); svn_auth_set_parameter(ctx->auth_baton, SVN_AUTH_PARAM_DEFAULT_PASSWORD, szPassword); /* Set revision to be the HEAD revision. */ revision.kind = svn_opt_revision_head; /* Main call into libsvn_client does all the work. */ #ifdef HAVE_SVN_CLIENT_LIST4 canonical = svn_uri_canonicalize(_psSessionData->szURL, pool); writeError(ERR_DEBUG_MODULE, "[%s] Canonicalized URL: %s", MODULE_NAME, canonical); err = svn_client_list4(canonical, &revision, &revision, NULL, svn_depth_empty, SVN_DIRENT_ALL, FALSE, FALSE, print_dirent, &ctx->auth_baton, ctx, pool); #elif HAVE_SVN_CLIENT_LIST3 canonical = svn_uri_canonicalize(_psSessionData->szURL, pool); writeError(ERR_DEBUG_MODULE, "[%s] Canonicalized URL: %s", MODULE_NAME, canonical); err = svn_client_list3(canonical, &revision, &revision, svn_depth_empty, SVN_DIRENT_ALL, FALSE, FALSE, print_dirent, &ctx->auth_baton, ctx, pool); #else err = svn_client_list2(_psSessionData->szURL, &revision, &revision, svn_depth_empty, SVN_DIRENT_ALL, FALSE, NULL, &ctx->auth_baton, ctx, pool); #endif if ((err !=NULL) && err->apr_err == 170001) { if (strstr(err->message, "Username not found")) { writeError(ERR_ERROR, "[%s] The following SVN user does not appear to exist: %s", MODULE_NAME, szLogin); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr(err->message, "Password incorrect")) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_DEBUG_MODULE, "[%s] Access refused. Unknown error: %s", MODULE_NAME, err->message); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } } else if (err != NULL) { writeError(ERR_ERROR, "[%s] Authentication Error (%d): %s.", MODULE_NAME, err->apr_err, err->message); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "%s : Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPassword); svn_pool_clear(pool); svn_pool_destroy(pool); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(LIBSVN_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, LIBSVN_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBSVN installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is LIBSVN installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/telnet.c000066400000000000000000000745701460263104500211410ustar00rootroot00000000000000/*************************************************************************** * telnet.c * * Copyright (C) 2009 by fizzgig * * fizzgig@foofus.net * * * * Implementation of a telnet brute force module for * * medusa. Module concept by the one-and-only Foofus. * * Protocol stuff based on the original hydra telnet code by * * VanHauser and the good folks at thc (vh@thc.org) * * * * * * CHANGE LOG * * 04/05/2005 - Created by fizzgig (fizzgig@foofus.net) * * All other changes are in the Subversion comments * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * * Tested on so far: * * Jetdirect cards (woo!) * * HP switches using basic auth * * Cisco switches using vty auth * * * * Support for hosts w/o username prompt added by pMonkey/JoMo-Kun * * * ***************************************************************************/ #include #include #include #include #include #include #include "module.h" #define MODULE_NAME "telnet.mod" #define MODULE_AUTHOR "fizzgig " #define MODULE_SUMMARY_USAGE "Brute force module for telnet sessions" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: telnet.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define PORT_TELNET 23 #define PORT_TELNETS 992 #define PROMPT_UNKNOWN 0 #define PROMPT_LOGIN_PASSWORD 1 #define PROMPT_PASSWORD 2 #define RECEIVE_DELAY_1 20 * 1000000 #define RECEIVE_DELAY_2 0.5 * 1000000 #define MODE_NORMAL 0 #define MODE_AS400 1 typedef struct __MODULE_DATA { int nMode; } _MODULE_DATA; const unsigned int BUFFER_SIZE = 300; const char* KNOWN_PROMPTS = ">#$%/?"; // Each character represents a known telnet prompt - feel free to add a new one if desired const int KNOWN_PWD_SIZE = 4; // Make sure to keep this in sync with the size of the array below!! const char* KNOWN_PWD_PROMPTS[] = { "assword", "asscode", "ennwort", "ASSWORD" }; // Complete/partial lines that indicate a password request const int KNOWN_LOGIN_SIZE = 3; // Make sure to keep this in sync with the size of the array below!! const char* KNOWN_LOGIN_PROMPTS[] = { "login:", "sername:", "User" }; // Complete/partial lines that request a user name // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword, int nFoundPrompt); int tryLoginAS400(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login, _MODULE_DATA* _psSessionData); int processIAClogout(int hSocket, _MODULE_DATA* _psSessionData); void processIAC(int hSocket, _MODULE_DATA* _psSessionData, unsigned char** buffer, int* nBufferSize); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " MODE:? (NORMAL, AS400) [optional]"); writeVerbose(VB_NONE, " Sets the mode for error detection."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " Usage example: \"-M telnet -m MODE:AS400 -U accounts.txt -p password\""); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 1)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inMode = MODE_AS400; else writeError(ERR_WARNING, "Invalid value for method MODE."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* _psLogin, _MODULE_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; unsigned char* bufReceive; int nReceiveBufferSize = 0, nFoundPrompt = PROMPT_UNKNOWN; int i = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, _psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else if (_psLogin->psServer->psHost->iUseSSL > 0) params.nPort = PORT_TELNETS; else params.nPort = PORT_TELNET; initConnectionParams(_psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (_psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket <= 0) { writeError(ERR_ERROR, "[%s] Failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); // Examine the first line returned nReceiveBufferSize = 0; bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) return FAILURE; bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] null response was unexpected from a telnet server (is one running?)", MODULE_NAME); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } // Telnet protocol negotiation do { nFoundPrompt = PROMPT_UNKNOWN; processIAC(hSocket, _psSessionData, &bufReceive, &nReceiveBufferSize); if (bufReceive != NULL && bufReceive[0] != 0 && (unsigned char)bufReceive[0] != IAC) makeToLower((char *)bufReceive); if (bufReceive != NULL) { writeError(ERR_DEBUG_MODULE, "Looking for login prompts"); if (_psSessionData->nMode == MODE_AS400) { if (strcasestr((char *)bufReceive, (char *)"Sign On") != NULL) { writeError(ERR_INFO, "[%s] Detected AS/400 Sign On Screen.", MODULE_NAME); nFoundPrompt = PROMPT_LOGIN_PASSWORD; FREE(bufReceive); if (medusaDataReadyTimed(hSocket, 0, 20000) > 0) { // More data waiting bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive != NULL) bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated } break; } /* Sign On System . . . . . : TSTDBS16 Subsystem . . . . : QINTER Display . . . . . : QPADEV0001 */ } else { // Look for known login prompts for (i = 0; i < KNOWN_LOGIN_SIZE; i++) { if (strcasestr((char *)bufReceive, KNOWN_LOGIN_PROMPTS[i]) != NULL) { // Do we have a prompt? writeError(ERR_DEBUG_MODULE, "Found login prompt..."); nFoundPrompt = PROMPT_LOGIN_PASSWORD; break; } } /* Some systems do not provide a login prompt and go right to password */ for (i = 0; i < KNOWN_PWD_SIZE; i++) { if (strcasestr((char *)bufReceive, KNOWN_PWD_PROMPTS[i]) != NULL) { // Do we have a prompt? writeError(ERR_DEBUG_MODULE, "Found a password prompt already..."); nFoundPrompt = PROMPT_PASSWORD; if (_psLogin->psServer->iLoginsDone < 1 && _psLogin->iId == 0) writeVerbose(VB_NONE_FILE, "Password Prompt Only: %s\n", _psLogin->psServer->pHostIP); break; } } if (nFoundPrompt == PROMPT_UNKNOWN) { FREE(bufReceive); if (medusaDataReadyTimed(hSocket, 0, 20000) > 0) { // More data waiting bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive != NULL) bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated } } } } } while (bufReceive != NULL && (unsigned char)bufReceive[0] == IAC && nFoundPrompt == PROMPT_UNKNOWN); FREE(bufReceive); if (nFoundPrompt == PROMPT_UNKNOWN) { writeError(ERR_ERROR, "[%s] Failed to identify logon prompt.", MODULE_NAME); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } else nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: if (_psSessionData->nMode == MODE_AS400) nState = tryLoginAS400(hSocket, &_psLogin, psCredSet->psUser->pUser, psCredSet->pPass); else nState = tryLogin(hSocket, &_psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass, nFoundPrompt); if (_psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (processIAClogout(hSocket, _psSessionData) == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to close existing Telnet session.", MODULE_NAME); } medusaDisconnect(hSocket); hSocket = -1; /* Cisco devices appear to keep sessions open for a brief time after we terminate the connection. They also seem to ignore "IAC DO LOGOUT" commands. Adding a sleep() hack here, to give them some time to clean-up. */ sleep(3); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module (%d) state %d host: %s", MODULE_NAME, _psLogin->iId, nState, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; } } FREE(psCredSet); return SUCCESS; } int tryLogin(int hSocket, sLogin** login, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword, int nFoundPrompt) { // This function should return MSTATE_RUNNING to continue or MSTATE_EXITING to terminate the module unsigned char bufSend[BUFFER_SIZE]; unsigned char* bufReceive; int nSendBufferSize = 0, nReceiveBufferSize = 0; int nContinue = 0, i = 0; // Check the socket and such if (hSocket <= 0) { writeError(ERR_ERROR, "%s failed: socket was invalid", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; // No good socket } if (nFoundPrompt == PROMPT_LOGIN_PASSWORD) { // Set up the send buffer memset(bufSend, 0, BUFFER_SIZE); sprintf((char *)bufSend, "%s\r", szLogin); nSendBufferSize = strlen((char *)bufSend) + 1; // Count the null terminator if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } do { // Look for a return bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { // Found a prompt - telnet appears to be alive, keep going writeError(ERR_ERROR, "%s: Telnet did not respond to the sending of the user name '%s' in a timely fashion - is it down or refusing connections?", MODULE_NAME, szLogin); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated // Do we have a prompt? if (strcspn((char *)bufReceive, KNOWN_PROMPTS) != strlen((char *)bufReceive)) { (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); free(bufReceive); return MSTATE_EXITING; } makeToLower((char *)bufReceive); // Are we at a known password prompt? for (i = 0; i < KNOWN_PWD_SIZE; i++) { if (strcasestr((char *)bufReceive, KNOWN_PWD_PROMPTS[i]) != NULL) { nContinue = 1; break; } } // Look for known login prompts if (nContinue == 0) { for (i = 0; i < KNOWN_LOGIN_SIZE; i++) { if (strcasestr((char *)bufReceive, KNOWN_LOGIN_PROMPTS[i]) != NULL) { free(bufReceive); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_RUNNING; } } } free(bufReceive); } while(nContinue == 0); } else if (nFoundPrompt == PROMPT_PASSWORD) { writeError(ERR_DEBUG_MODULE, "[%s] we are skipping a username", MODULE_NAME); } else { writeError(ERR_ERROR, "[%s] No login prompt detected.", MODULE_NAME); return FAILURE; } // Send the password memset(bufSend, 0, BUFFER_SIZE); sprintf((char *)bufSend, "%s\r", szPassword); nSendBufferSize = strlen((char *)bufSend) + 1; // Count the null terminator if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } // Look for a return bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { writeError(ERR_ERROR, "timeout waiting for response from server after sending password"); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } bufReceive[nReceiveBufferSize] = 0; // Make certain buffer is null-terminated // It's possible that some telnet servers (like Microsoft's) may send some more IAC commands at this point // Take care of zem! processIAC(hSocket, _psSessionData, &bufReceive, &nReceiveBufferSize); if (bufReceive == NULL) bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); // Do we have a prompt? while (bufReceive != NULL) { /* check for known failures */ if (strstr((char *)bufReceive, "Authentication failed")) { writeError(ERR_DEBUG_MODULE, "Server responded with Cisco \"Authentication failed.\" message."); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } if (strstr((char *)bufReceive, "Login invalid")) { writeError(ERR_DEBUG_MODULE, "Server responded with Cisco \"Login invalid\" message."); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } else if (strcspn((char *)bufReceive, KNOWN_PROMPTS) != strlen((char *)bufReceive)) { // Found a prompt - telnet appears to be alive free(bufReceive); (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); return MSTATE_EXITING; } else { if (nFoundPrompt == PROMPT_LOGIN_PASSWORD) { // If we have a login prompt, we have failed for (i = 0; i < KNOWN_LOGIN_SIZE; i++) { if (strcasestr((char *)bufReceive, KNOWN_LOGIN_PROMPTS[i]) != NULL) { free(bufReceive); writeError(ERR_DEBUG_MODULE, "unsuccessful login - user '%s' with a password of '%s'", szLogin, szPassword); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } } } else { // We are operating on a non-login telnet setup for (i = 0; i < KNOWN_PWD_SIZE; i++) { if (strcasestr((char *)bufReceive, KNOWN_PWD_PROMPTS[i]) != NULL) { free(bufReceive); writeError(ERR_DEBUG_MODULE, "unsuccessful login with a password of '%s'", szPassword); (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } } } } free(bufReceive); bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); } (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } int tryLoginAS400(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { unsigned char bufSend[BUFFER_SIZE]; unsigned char* bufReceive; int nSendBufferSize = 0, nReceiveBufferSize = 0; int iRet = FAILURE; char szUser[10 + 1]; char szPass[128 + 1]; char szErrorMsg[100]; if (hSocket <= 0) { writeError(ERR_ERROR, "%s failed: socket was invalid", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } /* Send username and password */ /* USERNAME \t (0x09) PASSWORD \r (0x0D) \0 (0x00) */ /* Password Policy Information http://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/rzakz/rzakzqpwdlvl.htm Short passwords: The AS/400 "short" passwords are 0-10 characters in length. They allow the following characters: A-Z 0-9 $ @ # _ Long passwords: The AS/400 "long" passwords are 0-128 characters in length. Upper and lower case passwords consisting of any characters are allowed. Usernames appear to be limited to 10 characters in length and use upper-case. ** This has not been fully verified. ** http://download.oracle.com/docs/html/B10256_01/ch2.htm IBM DB2/400 V4R5 object names can be up to 10 alphanumeric characters in length, beginning with a letter or a national character. */ memset(bufSend, 0, BUFFER_SIZE); memset(szUser, 0, 10 + 1); memset(szPass, 0, 128 + 1); strncpy(szUser, szLogin, 10); strncpy(szPass, szPassword, 128); sprintf((char *)bufSend, "%s\t%s\r", szUser, szPass); nSendBufferSize = strlen((char *)bufSend) + 1; if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } /* Process server response */ bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) { writeError(ERR_ERROR, "[%s] Timeout waiting for response from server after sending password", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*psLogin, szPassword); return MSTATE_EXITING; } if (strstr((char *)bufReceive, "CPF1120") != NULL) { sprintf(szErrorMsg, "CPF1120 - User %s does not exist.", szUser); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr((char *)bufReceive, "CPF1116") != NULL) { strcpy(szErrorMsg, "CPF1116 - Next not valid sign-on attempt varies off device."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if (strstr((char *)bufReceive, "CPF1392") != NULL) { strcpy(szErrorMsg, "CPF1392 - Next not valid sign-on disables user profile."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } /* http://archive.midrange.com/midrange-l/200507/msg01092.html Cause . . . . . : User profile &1 has reached the maximum number of sign-on attempts and has been disabled, or the STATUS parameter has been changed to *DISABLED on the Create User Profile (CRTUSRPRF) or Change User Profile (CHGUSRPRF) command. Recovery . . . : To enable the user profile, have the security officer change the STATUS parameter to *ENABLED on the Change User Profile (CHGUSRPRF) command. */ else if (strstr((char *)bufReceive, "CPF1394") != NULL) { sprintf(szErrorMsg, "CPF1394 - User profile %s cannot sign on.", szUser); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } else if (strstr((char *)bufReceive, "CPF1118") != NULL) { sprintf(szErrorMsg, "CPF1118 - No password associated with user %s.", szUser); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr((char *)bufReceive, "CPF1109") != NULL) { strcpy(szErrorMsg, "CPF1109 - Not authorized to subsystem."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr((char *)bufReceive, "CPF1110") != NULL) { strcpy(szErrorMsg, "CPF1110 - Not authorized to work station."); writeError(ERR_ERROR, "[%s] %s", MODULE_NAME, szErrorMsg); (*psLogin)->pErrorMsg = strdup(szErrorMsg); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else if (strstr((char *)bufReceive, "CPF1107") != NULL) { writeError(ERR_INFO, "[%s] CPF1107 - Password not correct for user profile.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if (strstr((char *)bufReceive, "Access Denied") != NULL) { writeError(ERR_INFO, "[%s] Access Denied", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPass); return iRet; } /* The sender of this command REQUESTS that the receiver forcibly log off the user process at the receiver's end, or confirms that the receiver has its permission to do so. */ int processIAClogout(int hSocket, _MODULE_DATA* _psSessionData __attribute__((unused))) { unsigned char bufSend[] = { 0xFF, 0xFD, 0x12 }; /* IAC DO LOGOUT */ //char* bufReceive = NULL; //int nReceiveBufferSize = 0; writeError(ERR_DEBUG_MODULE, "[%s] Sending IAC DO LOGOUT command.", MODULE_NAME); if (medusaSend(hSocket, bufSend, 3, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } /* Receive any remaining IAC commands */ /* bufReceive = medusaReceiveLineDelay(hSocket, &nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (bufReceive == NULL) return FAILURE; processIAC(hSocket, _psSessionData, &bufReceive, &nReceiveBufferSize); */ return SUCCESS; } void processIAC(int hSocket, _MODULE_DATA* _psSessionData, unsigned char** buffer, int* nReceiveBufferSize) { unsigned char* bufTemp = *buffer; /* We're not that friendly. Refuse to do anything asked of us. */ while (*bufTemp == IAC) /* IAC (0xFF) */ { writeError(ERR_DEBUG_MODULE, "Handling IAC Command..."); if ((bufTemp[1] == 0xfc || bufTemp[1] == 0xfe) && bufTemp[2] == 0x22) { writeError(ERR_DEBUG_MODULE, "TELNETD peer does not like linemode"); } if (bufTemp[1] == WILL) /* WILL (0xFB), WONT (0xFC) */ { /* AS/400 devices appear to request and require "Echo" and "Suppress Go Ahead" */ if (_psSessionData->nMode == MODE_AS400) if ((bufTemp[2] == TELOPT_ECHO) || (bufTemp[2] == TELOPT_SGA)) bufTemp[1] = DO; else bufTemp[1] = DONT; else bufTemp[1] = DONT; medusaSend(hSocket, bufTemp, 3, 0); } else if (bufTemp[1] == DO) /* DO (0xFD), DONT (0xFE) */ { bufTemp[1] = WONT; medusaSend(hSocket, bufTemp, 3, 0); } bufTemp += 3; /* Process three bytes at a time */ } if (*bufTemp == 0) { writeError(ERR_DEBUG_MODULE, "Getting more data"); free(*buffer); *nReceiveBufferSize = 0; *buffer = medusaReceiveLineDelay(hSocket, nReceiveBufferSize, RECEIVE_DELAY_1, RECEIVE_DELAY_2); if (*buffer != NULL) (*buffer)[*nReceiveBufferSize] = 0; // Make certain buffer is null-terminated else { // No data *buffer = NULL; return; } writeError(ERR_DEBUG_MODULE, "Next pass buffer: %s", *buffer); if ((unsigned char)*buffer[0] == IAC) { writeError(ERR_DEBUG_MODULE, "More commands waiting..."); } } } jmk-foofus-medusa-dd62069/src/modsrc/vmauthd.c000066400000000000000000000245631460263104500213130ustar00rootroot00000000000000/* ** VMware Authentication Daemon Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** Hydra 5.2 [van Hauser / David Maciejak ] ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "vmauthd.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for the VMware Authentication Daemon" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: vmauthd.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PORT_VMAUTHD 902 // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int initConnection(int hSocket, sConnectParams *params); int tryLogin(int hSocket, sLogin** login, char* szLogin, char* szPassword); int initModule(sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "The VMware Authentication Daemon listens on TCP port 902 and may or may not"); writeVerbose(VB_NONE, "require a SSL-encrypted connection. This module connects to the service using"); writeVerbose(VB_NONE, "non-SSL and will automatically switch to SSL if required."); writeVerbose(VB_NONE, ""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[] __attribute__((unused))) { if (argc != 0) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); initModule(logins); } return SUCCESS; } int initModule(sLogin* psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_VMAUTHD; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "[%s] failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } if (initConnection(hSocket, ¶ms) == FAILURE) { psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* Module specific functions */ /* 220 VMware Authentication Daemon Version 1.00 220 VMware Authentication Daemon Version 1.10: SSL Required */ int initConnection(int hSocket, sConnectParams *params) { unsigned char* bufReceive = NULL; int nReceiveBufferSize; nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^220 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] Incorrect VMware authentication protocol or service shutdown: %s.", MODULE_NAME, bufReceive); FREE(bufReceive); return FAILURE; } if (strstr((char *)bufReceive, "SSL Required")) { writeError(ERR_INFO, "[%s] SSL Required for VMware authentication. Proceeding using SSL.", MODULE_NAME); if (medusaConnectSocketSSL(params, hSocket) < 0) { writeError(ERR_ERROR, "[%s] Failed to establish SSLv3 connection.", MODULE_NAME); FREE(bufReceive); return FAILURE; } } FREE(bufReceive); return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, char* szLogin, char* szPassword) { int iRet; unsigned char* bufSend = NULL; unsigned char* bufReceive = NULL; int nReceiveBufferSize = 0; bufSend = malloc(strlen(szLogin) + 7 + 1); memset(bufSend, 0, strlen(szLogin) + 7 + 1); sprintf((char *)bufSend, "USER %s\r\n", szLogin); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); /* 331 Password required for USERNAME.[0D][0A] */ nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^331 .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] VMware authentication protocol error or service shutdown: %s.\n", MODULE_NAME, bufReceive); FREE(bufReceive); return FAILURE; } FREE(bufReceive); bufSend = malloc(strlen(szPassword) + 7 + 1); memset(bufSend, 0, strlen(szPassword) + 7 + 1); sprintf((char *)bufSend, "PASS %s\r\n", szPassword); if (medusaSend(hSocket, bufSend, strlen((char *)bufSend), 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); FREE(bufSend); return FAILURE; } FREE(bufSend); nReceiveBufferSize = 0; if ((medusaReceiveRegex(hSocket, &bufReceive, &nReceiveBufferSize, "^[0-9]{3,3} .*\r\n") == FAILURE) || (bufReceive == NULL)) { writeError(ERR_ERROR, "[%s] VMware authentication protocol error or service shutdown: %s.\n", MODULE_NAME, bufReceive); FREE(bufReceive); return FAILURE; } /* 230 User USERNAME logged in.[0D][0A] */ if (strncmp((char *)bufReceive, "230 ", 4) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt successful.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } /* 530 Login incorrect.[0D][0A] */ else if (strncmp((char *)bufReceive, "530 ", 4) == 0) { writeError(ERR_DEBUG_MODULE, "[%s] Login attempt failed.", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else { writeError(ERR_ERROR, "[%s] Unknown error occurred during authentication: %s", MODULE_NAME, bufReceive); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } FREE(bufReceive); setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/vnc.c000066400000000000000000001004421460263104500204200ustar00rootroot00000000000000/* ** VNC Password Checking Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2011 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** Based on code from: ** VNCrack [FX/Phenolite] ** RealVNC (VNC Server 4 -- FREE) ** UltraVNC 1.0.9.6.1 ** ** Supports: password-less VNC, password-only VNC and UltraVNC MS-Logon */ #include #include #include #include #include #include "module.h" #include "d3des.h" #define MODULE_NAME "vnc.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Brute force module for VNC sessions" #define MODULE_VERSION "2.2" #define MODULE_VERSION_SVN "$Id: vnc.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #include #define PORT_VNC 5900 #define CHALLENGE_SIZE 16 #define SESSION_SUCCESS 1 #define SESSION_FAILURE 2 #define SESSION_SUCCESS_NO_AUTH 3 #define SESSION_MAX_AUTH_REALVNC 4 #define SESSION_MAX_AUTH_ULTRAVNC 5 #define AUTH_VNC 1 #define AUTH_UVNC_MSLOGIN 2 typedef struct __VNC_DATA { int nMaxAuthSleep; int nAuthType; unsigned char* szChallenge; char* szDomain; } _VNC_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, sLogin** login, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword); int initModule(sLogin* login, _VNC_DATA *_psSessionData); int vncSessionSetup(int hSocket, _VNC_DATA *_psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " MAXSLEEP:?"); writeVerbose(VB_NONE, " Sets the maximum allowed sleep time when the VNC RealVNC anti-brute force delay"); writeVerbose(VB_NONE, " is encountered. This value is in seconds and, if left unset, defaults to 60."); writeVerbose(VB_NONE, " DOMAIN:?"); writeVerbose(VB_NONE, " Sets the domain value when authenticating against UltraVNC's MS-Logon feature."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Some versions of VNC have built-in anti-brute force functionality. RealVNC, for example,"); writeVerbose(VB_NONE, "allows 5 failed attempts and then enforces a 10 second delay. For each subsequent"); writeVerbose(VB_NONE, "attempt that delay is doubled. UltraVNC appears to allow 6 invalid attempts and then forces"); writeVerbose(VB_NONE, "a 10 second delay between each following attempt. This module attempts to identify these"); writeVerbose(VB_NONE, "situations and react appropriately by invoking sleep(). The user can set a sleep limit when"); writeVerbose(VB_NONE, "brute forcing RealVNC using the MAXSLEEP parameter. Once this value has been reached, the"); writeVerbose(VB_NONE, "module will exit."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "It should be noted that this module currently supports password-less and password-only VNC"); writeVerbose(VB_NONE, "servers. In addition, it supports UltraVNC's MS-Logon feature that can be used to provide"); writeVerbose(VB_NONE, "pass-through authentication against local and domain Windows accounts. In the case of basic"); writeVerbose(VB_NONE, "password-only VNC, provide any arbitrary username value."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M vnc -m MAXSLEEP:120 -m DOMAIN:FOOFUSDOM\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _VNC_DATA *psSessionData; psSessionData = malloc(sizeof(_VNC_DATA)); memset(psSessionData, 0, sizeof(_VNC_DATA)); psSessionData->nMaxAuthSleep = 60; if ((argc < 0) || (argc > 2)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inMaxAuthSleep = atoi(pOpt); else writeError(ERR_WARNING, "Method MAXSLEEP requires value to be set."); } else if (strcmp(pOpt, "DOMAIN") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDomain = strdup(pOpt); } else writeError(ERR_WARNING, "Method DOMAIN requires value to be set."); } else writeError(ERR_WARNING, "Invalid method: %s.", pOpt); free(pOptTmp); } initModule(logins, psSessionData); } FREE(psSessionData); return SUCCESS; } int initModule(sLogin* psLogin, _VNC_DATA *_psSessionData) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; int iRet; sConnectParams params; int nAngrySleep = 10; int bAuthAllowed = FALSE; sCredentialSet *psCredSet = NULL; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = psLogin->psServer->psAudit->iPortOverride; else params.nPort = PORT_VNC; initConnectionParams(psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: while (!bAuthAllowed) { if (hSocket > 0) medusaDisconnect(hSocket); hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } writeError(ERR_DEBUG_MODULE, "Connected"); iRet = vncSessionSetup(hSocket, _psSessionData); switch( iRet ) { case SESSION_SUCCESS: writeError(ERR_DEBUG_MODULE, "VNC Session Initialized."); bAuthAllowed = TRUE; nState = MSTATE_RUNNING; break; case SESSION_SUCCESS_NO_AUTH: writeError(ERR_DEBUG_MODULE, "VNC Server Does Not Require Authentication."); psLogin->iResult = LOGIN_RESULT_SUCCESS; setPassResult(psLogin, "[NO AUTH REQUIRED]"); bAuthAllowed = TRUE; nState = MSTATE_EXITING; break; case SESSION_MAX_AUTH_REALVNC: writeError(ERR_ALERT, "[%s] Host %s reported too many security failures. Sleeping %d seconds before next attempt.", MODULE_NAME, psLogin->psServer->pHostIP, nAngrySleep); if (nAngrySleep > _psSessionData->nMaxAuthSleep) { writeError(ERR_ERROR, "[%s] Host %s exceeded maximum allowed sleep. Terminating connection.", MODULE_NAME, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; bAuthAllowed = TRUE; nState = MSTATE_EXITING; } else { sleep(nAngrySleep + 1); nAngrySleep = 2 * nAngrySleep; } break; case SESSION_MAX_AUTH_ULTRAVNC: writeError(ERR_ALERT, "[%s] Host %s has rejected the connection. Sleeping 10 seconds before next attempt.", MODULE_NAME, psLogin->psServer->pHostIP); if (nAngrySleep > _psSessionData->nMaxAuthSleep) { writeError(ERR_ERROR, "[%s] Host %s exceeded maximum allowed sleep. Terminating connection.", MODULE_NAME, psLogin->psServer->pHostIP); psLogin->iResult = LOGIN_RESULT_UNKNOWN; bAuthAllowed = TRUE; nState = MSTATE_EXITING; } else { sleep(10 + 1); nAngrySleep = nAngrySleep + 10; } break; default: writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failed."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; bAuthAllowed = TRUE; nState = MSTATE_EXITING; break; } } bAuthAllowed = FALSE; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, &psLogin, _psSessionData, psCredSet->psUser->pUser, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } FREE(psCredSet); return SUCCESS; } /* VNC Specific Functions */ /* ** Encrypt CHALLENGE_SIZE bytes in memory using a password. ** Ripped from vncauth.c */ void vncEncryptBytes(unsigned char *bytes, char *passwd) { unsigned char key[8]; unsigned int i; /* key is simply password padded with nulls */ for (i = 0; i < 8; i++) { if (i < strlen(passwd)) { key[i] = passwd[i]; } else { key[i] = 0; } } deskey(key, EN0); for (i = 0; i < CHALLENGE_SIZE; i += 8) { des(bytes + i, bytes + i); } } void vncEncryptPasswdMs( unsigned char *encryptedPasswd, char *passwd ) { unsigned char key[8]; unsigned int i; /* pad password with nulls */ for (i = 0; i < 32; i++) { if (i < strlen(passwd)) { encryptedPasswd[i] = passwd[i]; } else { encryptedPasswd[i] = 0; } } /* Do encryption in-place - this way we overwrite our copy of the plaintext password */ deskey(key, EN0); des(encryptedPasswd, encryptedPasswd); } /* [UltraVNC/rfb/dh.cpp] */ uint64_t bytesToInt64(const unsigned char* const bytes) { uint64_t result = 0; int i; for (i = 0; i < 8; i++) { result <<= 8; result += bytes[i]; } return result; } int int64ToBytes(const uint64_t integer, char* const bytes) { int i; for (i = 0; i < 8; i++) { bytes[i] = (unsigned char) (integer >> (8 * (7 - i))); } return SUCCESS; } /* [UltraVNC/vncviewer/vncauth.c] */ void vncEncryptBytes2(unsigned char *where, const int length, unsigned char *key) { int i, j; deskey(key, EN0); for (i = 0; i< 8; i++) where[i] ^= key[i]; des(where, where); for (i = 8; i < length; i += 8) { for (j = 0; j < 8; j++) where[i + j] ^= where[i + j - 8]; des(where + i, where + i); } } int vncSessionSetup(int hSocket, _VNC_DATA* _psSessionData) { unsigned char ProtocolVersion[13]; int iServerProtocolVersion; unsigned char* bufReceive; int nReceiveBufferSize = 0; int i = 0; int nSecurityTypes = 0; unsigned char* szSecurityTypes = NULL; memset(ProtocolVersion, 0, 13); /* --- VNC Protocol Handshake --- */ /* Retrieve server VNC protocol version */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return SESSION_FAILURE; writeError(ERR_DEBUG_MODULE, "VNC Server Protocol Version: %s", bufReceive); /* The following message is triggered by 5 failed authentication attempts, at which ** point a 10 second lockout is applied before the next attempt is permitted. Each ** subsequent failed attempt causes the timeout to be doubled. ** ** RealVNC: Too many security failures ** WinVNC (<=3.3.3r2): Too many authentication failures */ if ((strncmp((char *)bufReceive + 20, "Too many security failures", 26) == 0) || (strncmp((char *)bufReceive + 20, "Too many authentication failures", 32) == 0)) { writeError(ERR_DEBUG_MODULE, "[%s] Host reported too many security failures.", MODULE_NAME); return SESSION_MAX_AUTH_REALVNC; } /* 3.3, 3.7 and 3.8 are the only published protocol versions (RFB Protocol v3.8 11/26/2010) */ else if (strncmp((char *)bufReceive, "RFB 003.003", 11) == 0) { memcpy(ProtocolVersion, "RFB 003.003\n", 12); iServerProtocolVersion = 3; } else if (strncmp((char *)bufReceive, "RFB 003.007", 11) == 0) { memcpy(ProtocolVersion, "RFB 003.007\n", 12); iServerProtocolVersion = 7; } else if (strncmp((char *)bufReceive, "RFB 003.008", 11) == 0) { memcpy(ProtocolVersion, "RFB 003.008\n", 12); iServerProtocolVersion = 8; } /* RealVNC - VNC Server Enterprise Edition E4.6.3 (r66752) */ else if (strncmp((char *)bufReceive, "RFB 004.001", 11) == 0) { memcpy(ProtocolVersion, "RFB 004.001\n", 12); iServerProtocolVersion = 8; } else { writeError(ERR_DEBUG_MODULE, "[%s] Unknown session setup response: %s. Setting client response to version 3.3.", MODULE_NAME, bufReceive); memcpy(ProtocolVersion, "RFB 003.003\n", 12); iServerProtocolVersion = 3; } /* Send client VNC protocol version */ writeError(ERR_DEBUG_MODULE, "VNC Client Protocol Version: %s", ProtocolVersion); if (medusaSend(hSocket, ProtocolVersion, 12, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); } /* Some VNC servers seem to get upset if we go too fast. Sleeping 1/2 second seems to help. */ usleep(0.5 * 1000000); /* --- VNC Security Type Handshake --- */ /* Retrieve VNC protocol authentication scheme response */ nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if ((bufReceive == NULL) || (nReceiveBufferSize == 0)) { writeError(ERR_ERROR, "No security type response received from server."); return SESSION_FAILURE; } /* RFB Protocol 3.3 - Security Type ** ** Server: U32 [security type] ** ** if the security types is 0, response is followed by: ** Server: U32 [reason-length] ** U8 array [reason for connection failure] */ else if (iServerProtocolVersion == 3) { writeErrorBin(ERR_DEBUG_MODULE, "Supported Security Types (version 3.3): ", bufReceive, nReceiveBufferSize); switch (bufReceive[3]) { case 0x00: /* connection failure */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Failed."); if (nReceiveBufferSize > 16) writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failure Message: %s", bufReceive + 8); /* Server is probably in anti-brute force mode (UltraVNC) */ if ((nReceiveBufferSize == 42) && (strncmp((char *)bufReceive + 8, "Your connection has been rejected.", 34) == 0)) return SESSION_MAX_AUTH_ULTRAVNC; else return SESSION_FAILURE; break; case 0x01: /* no authentication required */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Successful - No Authentication Required."); return SESSION_SUCCESS_NO_AUTH; break; case 0x02: /* authentication required -- set authentication challenge */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Successful."); if (nReceiveBufferSize == 20) { _psSessionData->szChallenge = malloc(17); memset(_psSessionData->szChallenge, 0, 17); memcpy(_psSessionData->szChallenge, bufReceive + 4, 16); writeError(ERR_DEBUG_MODULE, "VNC authentication challenge: %s", _psSessionData->szChallenge); _psSessionData->nAuthType = AUTH_VNC; return SESSION_SUCCESS; } else { writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME); return SESSION_FAILURE; } break; case 0xFA: /* UltaVNC MS-Logon */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC MS-Logon."); if (nReceiveBufferSize == 28) { _psSessionData->szChallenge = malloc(25); memset(_psSessionData->szChallenge, 0, 25); memcpy(_psSessionData->szChallenge, bufReceive + 4, 24); writeErrorBin(ERR_DEBUG_MODULE, "VNC authentication challenge: ", bufReceive + 4, 24); _psSessionData->nAuthType = AUTH_UVNC_MSLOGIN; return SESSION_SUCCESS; } else { writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME); return SESSION_FAILURE; } break; default: /* unknown response */ writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response (3.3): %d", MODULE_NAME, bufReceive[3]); return SESSION_FAILURE; break; } } /* RFB Protocol 3.7, 3.8 - Security Type ** ** Server: U8 [number of security types] ** U8 array [security type] ** ** If the number of security types is 0, response is followed by: ** Server: U32 [reason-length] ** U8 array [reason for connection failure] */ else if ((iServerProtocolVersion == 7) || (iServerProtocolVersion == 8)) { writeErrorBin(ERR_DEBUG_MODULE, "Supported Security Types (> version 3.7): ", bufReceive, nReceiveBufferSize); /* connection failure */ if (bufReceive[0] == 0) { writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Failed."); //memcpy(nReasonLength + sizeof(int), bufReceive + 1, 4); if (nReceiveBufferSize > 8) writeError(ERR_DEBUG_MODULE, "VNC Session Setup Failure Message: %s", bufReceive + 5); /* Server is probably in anti-brute force mode (UltraVNC) */ if (strncmp((char *)bufReceive + 5, "Your connection has been rejected.", 34) == 0) return SESSION_MAX_AUTH_ULTRAVNC; else return SESSION_FAILURE; } /* verify response length */ else if (nReceiveBufferSize == 1 + (int)bufReceive[0]) { nSecurityTypes = (int)bufReceive[0]; szSecurityTypes = malloc(nSecurityTypes + 1); memset(szSecurityTypes, 0, nSecurityTypes + 1); memcpy(szSecurityTypes, bufReceive + 1, nSecurityTypes); for (i = 0; i <= nSecurityTypes; i++) { writeError(ERR_DEBUG_MODULE, "Processing server security type: %d (%d/%d). We will select the first supported type encountered.", szSecurityTypes[i], i + 1, nSecurityTypes); switch (szSecurityTypes[i]) { case 0x01: /* no authentication required */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Password-only VNC - No Authentication Required"); if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; else if (bufReceive[3] == 0) return SESSION_SUCCESS_NO_AUTH; else return FAILURE; break; case 0x02: /* authentication required -- set authentication challenge */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - Password-only VNC"); if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (nReceiveBufferSize == 16) { _psSessionData->szChallenge = malloc(17); memset(_psSessionData->szChallenge, 0, 17); memcpy(_psSessionData->szChallenge, bufReceive, 16); writeError(ERR_DEBUG_MODULE, "VNC authentication challenge: %s", _psSessionData->szChallenge); _psSessionData->nAuthType = AUTH_VNC; return SESSION_SUCCESS; } else { writeError(ERR_ERROR, "[%s] Unknown session challenge. Possible unsupported authentication type.", MODULE_NAME); return SESSION_FAILURE; } break; case 0x05: /* 5: RealVNC RA2 */ case 0x06: /* 6: RealVNC RA2ne */ case 0x81: /* 129: UNIX Logon Authentication */ case 0x82: /* 130: External Authentication */ writeError(ERR_ERROR, "[%s] VNC Session Setup - RealVNC (Type %d). RealVNC native authentication mode is NOT currently supported.", MODULE_NAME, szSecurityTypes[i]); break; case 0x11: /* 17: UltraVNC */ /* http://www.uvnc.com/features/authentication.html */ /* [rfb/rfbproto.h] rfbUltraVNC 0x17 - after rfbUltraVNC, auth repeats via rfbVncAuthContinue rfbUltraVNC_SCPrompt 0x68 rfbUltraVNC_SessionSelect 0x69 rfbUltraVNC_MsLogonIAuth 0x70 rfbUltraVNC_MsLogonIIAuth 0x71 rfbUltraVNC_SecureVNCPluginAuth 0x72 */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC"); /* 0x11 UltraVNC contains multiple sub-types. If we respond with 0x11, the server should send us a list. For example, 0xffffffff 0x0171 (UltraVNC MS-Logon II). This appears to be sent sometimes as a single packet, sometimes as two. It seems that any sub-types we would enumerate here, however, were also listed in the initial supported security type response. As such, let's just skip this type and move on to the next in the list. If this assumption turns out to be incorrect, we should continue the security type negotiation here. */ break; case 0x70: /* 17: UltraVNC MS-Logon I */ case 0x71: /* 17: UltraVNC MS-Logon II */ writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC (Type %d)", szSecurityTypes[i]); if (medusaSend(hSocket, &szSecurityTypes[i], 1, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (nReceiveBufferSize == 24) { writeError(ERR_DEBUG_MODULE, "VNC Session Setup - UltraVNC MS-Logon II - Process authentication challenge"); _psSessionData->szChallenge = malloc(25); memset(_psSessionData->szChallenge, 0, 25); memcpy(_psSessionData->szChallenge, bufReceive, 24); writeErrorBin(ERR_DEBUG_MODULE, "VNC authentication challenge: ", _psSessionData->szChallenge, 24); _psSessionData->nAuthType = AUTH_UVNC_MSLOGIN; return SESSION_SUCCESS; } break; default: /* unknown response - skip and see if we find a supported type */ writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response (3.7/3.8): %d", MODULE_NAME, szSecurityTypes[i]); break; } } } else { writeError(ERR_ERROR, "[%s] VNC Session Setup - Unknown Response", MODULE_NAME); return SESSION_FAILURE; } } FREE(szSecurityTypes); return SESSION_FAILURE; } int sendAuthVNC(int hSocket, _VNC_DATA* _psSessionData, char* szPassword) { writeError(ERR_DEBUG_MODULE, "[%s] VNC authentication challenge: %s", MODULE_NAME, _psSessionData->szChallenge); vncEncryptBytes(_psSessionData->szChallenge, szPassword); writeError(ERR_DEBUG_MODULE, "[%s] VNC authentication response: %s", MODULE_NAME, _psSessionData->szChallenge); if (medusaSend(hSocket, _psSessionData->szChallenge, 16, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } /* Based on ClientConnection::AuthMsLogonII() [UltraVNC/vncviewer/ClientConnection.cpp] MS Logon authentication supports "domain\user", "user" and "user@domain" logins */ int sendAuthMSLogin(int hSocket, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword) { /* 2024/03/16 - Functions previously used have been deprecated in OpenSSL v3.0. - New EVP_PKEY* function do not appear to support 64-bit modulus used by UltraVNC (too small). - Removing code until someone finds new solution. */ writeError(ERR_FATAL, "[%s] UltraVNC MS-Logon I/II support removed (OpenSSL functions deprecated).", MODULE_NAME); } int sendExit(int hSocket) { unsigned char szExit[] = { 0x00, 0x00, 0x00, 0x00, 0x05, 0x1D, 0x03, 0x20 }; writeError(ERR_DEBUG_MODULE, "[%s] Send VNC connection termination command.", MODULE_NAME); if (medusaSend(hSocket, szExit, 8, 0) < 0) { writeError(ERR_ERROR, "[%s] failed: medusaSend was not successful", MODULE_NAME); return FAILURE; } return SUCCESS; } int tryLogin(int hSocket, sLogin** psLogin, _VNC_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufReceive; int nReceiveBufferSize = 0; int iRet; /* perform authentication */ switch(_psSessionData->nAuthType) { case AUTH_VNC: sendAuthVNC(hSocket, _psSessionData, szPassword); break; case AUTH_UVNC_MSLOGIN: sendAuthMSLogin(hSocket, _psSessionData, szLogin, szPassword); break; default: writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - blah", MODULE_NAME); break; } writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Waiting for authentication result", MODULE_NAME); nReceiveBufferSize = 0; bufReceive = medusaReceiveRaw(hSocket, &nReceiveBufferSize); if (bufReceive == NULL) return FAILURE; else if (nReceiveBufferSize == 0) { /* Some VNC servers (e.g. TightVNC 2.0 Beta) simply drop the connection on a bad password */ writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Failed (no response from server)", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } else if (nReceiveBufferSize >= 4) { switch (bufReceive[3]) { case 0x00: writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Success", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; // TODO: Is this only for UltraVNC? sendExit(hSocket); break; case 0x01: if ((nReceiveBufferSize > 8) && (strstr((char *)bufReceive + 8, "Connection rejected by user") != NULL)) { writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Success (User rejected connection)", MODULE_NAME); (*psLogin)->pErrorMsg = malloc( 40 + 1 ); memset((*psLogin)->pErrorMsg, 0, 40 + 1 ); sprintf((*psLogin)->pErrorMsg, "User rejected connection request."); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; } else { writeError(ERR_DEBUG_MODULE, "[%s] VNC Authentication - Failed", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_FAIL; iRet = MSTATE_NEW; } break; default: writeError(ERR_ERROR, "[%s] VNC Authentication - Unknown Response: %d", MODULE_NAME, bufReceive[3]); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; break; } } else { writeError(ERR_ERROR, "[%s] VNC Authentication - Unknown Response", MODULE_NAME); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; } setPassResult((*psLogin), szPassword); return(iRet); } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/web-form.c000066400000000000000000000575531460263104500213660ustar00rootroot00000000000000/*************************************************************************** * web-form.c * * Copyright (C) 2007 by Luciano Bello * * luciano@debian.org.ar * * * * Implementation of a web form brute force module for * * medusa. Module concept by the one-and-only Foofus. * * Protocol stuff based on the original medusa http code by * * fizzgig (fizzgig@foofus.net). * * * * * * CHANGE LOG * * 08/10/2007 - Created by Luciano Bello (luciano@debian.org) * * 08/24/2007 - Minor modification by JoMo-Kun * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2, * * as published by the Free Software Foundation * * * * 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. * * * * http://www.gnu.org/licenses/gpl.txt * * * * This program is released under the GPL with the additional exemption * * that compiling, linking, and/or using OpenSSL is allowed. * * * ***************************************************************************/ #include "module.h" #define MODULE_NAME "web-form.mod" #define MODULE_AUTHOR "Luciano Bello " #define MODULE_SUMMARY_USAGE "Brute force module for web forms" #define MODULE_VERSION "2.1" #define MODULE_VERSION_SVN "$Id: web-form.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define OPENSSL_WARNING "No usable OPENSSL. Module disabled." #ifdef HAVE_LIBSSL #define HTTP_PORT 80 #define HTTPS_PORT 443 #define FORM_UNKNOWN 0 #define FORM_GET 1 #define FORM_POST 2 typedef struct __MODULE_DATA { char *szDir; char *szHostHeader; char *szUserAgent; int nFormType; char *szDenySignal; char *szFormData; char *szFormRest; char *szFormUser; char *szFormPass; char *szCustomHeader; int nCustomHeaders; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " USER-AGENT:? User-agent value. Default: \"I'm not Mozilla, I'm Ming Mong\"."); writeVerbose(VB_NONE, " FORM:? Target form to request. Default: \"/\""); writeVerbose(VB_NONE, " DENY-SIGNAL:? Authentication failure message. Attempt flagged as successful if text is not present in"); writeVerbose(VB_NONE, " server response. Default: \"Login incorrect\""); writeVerbose(VB_NONE, " CUSTOM-HEADER:? Custom HTTP header."); writeVerbose(VB_NONE, " More headers can be defined by using this option several times."); writeVerbose(VB_NONE, " FORM-DATA:?"); writeVerbose(VB_NONE, " Methods and fields to send to web service. Valid methods are GET and POST. The actual form"); writeVerbose(VB_NONE, " data to be submitted should also be defined here. Specifically, the fields: username and"); writeVerbose(VB_NONE, " password. The username field must be the first, followed by the password field."); writeVerbose(VB_NONE, " Default: \"post?username=&password=\""); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \"-M web-form -m USER-AGENT:\"g3rg3 gerg\" -m FORM:\"webmail/index.php\" -m DENY-SIGNAL:\"deny!\""); writeVerbose(VB_NONE, " -m FORM-DATA:\"post?user=&pass=&submit=True\" -m CUSTOM-HEADER:\"Cookie: name=value\""); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 5)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { // Parameters are good - make module go now writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; iszDir = strdup(pOpt); } else writeError(ERR_WARNING, "Method FORM requires value to be set."); } else if (strcmp(pOpt, "DENY-SIGNAL") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szDenySignal= strdup(pOpt); } else writeError(ERR_WARNING, "Method DENY-SIGNAL requires value to be set."); } else if (strcmp(pOpt, "FORM-DATA") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szFormData = strdup(pOpt); } else writeError(ERR_WARNING, "Method FORM-DATA requires value to be set."); } else if (strcmp(pOpt, "USER-AGENT") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szUserAgent = strdup(pOpt); } else writeError(ERR_WARNING, "Method USER-AGENT requires value to be set."); } else if (strcmp(pOpt, "CUSTOM-HEADER") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { if ( psSessionData->nCustomHeaders == 0 ) { psSessionData->szCustomHeader = malloc(strlen(pOpt) + 1); memset(psSessionData->szCustomHeader, 0, strlen(pOpt) + 3); strcpy(psSessionData->szCustomHeader, pOpt); strncpy(psSessionData->szCustomHeader + strlen(pOpt), "\r\n", 2); psSessionData->nCustomHeaders = 1; } else { int oldSize = strlen(psSessionData->szCustomHeader); psSessionData->szCustomHeader = realloc(psSessionData->szCustomHeader, oldSize + strlen(pOpt) + 3); memset(psSessionData->szCustomHeader + oldSize, 0, strlen(pOpt) + 3); strcpy(psSessionData->szCustomHeader + oldSize, pOpt); strncpy(psSessionData->szCustomHeader + oldSize + strlen(pOpt), "\r\n", 2); psSessionData->nCustomHeaders += 1; } } else writeError(ERR_WARNING, "Method CUSTOM-HEADER requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(psSessionData, logins); } FREE(psSessionData); return SUCCESS; } int initModule(_MODULE_DATA *_psSessionData, sLogin* _psLogin) { int hSocket = -1; enum MODULE_STATE nState = MSTATE_NEW; char *pStrtokSavePtr = NULL; char *pTemp; int nBufLength = 0; sCredentialSet *psCredSet = NULL; sConnectParams params; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, _psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } memset(¶ms, 0, sizeof(sConnectParams)); if (_psLogin->psServer->psAudit->iPortOverride > 0) params.nPort = _psLogin->psServer->psAudit->iPortOverride; else if (_psLogin->psServer->psHost->iUseSSL > 0) params.nPort = HTTPS_PORT; else params.nPort = HTTP_PORT; initConnectionParams(_psLogin, ¶ms); while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: // Already have an open socket - close it if (hSocket > 0) medusaDisconnect(hSocket); if (_psLogin->psServer->psHost->iUseSSL > 0) hSocket = medusaConnectSSL(¶ms); else hSocket = medusaConnect(¶ms); if (hSocket < 0) { writeError(ERR_NOTICE, "%s: failed to connect, port %d was not open on %s", MODULE_NAME, params.nPort, _psLogin->psServer->pHostIP); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(_psLogin, psCredSet->pPass); return FAILURE; } /* Set request parameters */ if (!_psSessionData->szDir) { _psSessionData->szDir = malloc(2); memset(_psSessionData->szDir, 0, 2); sprintf(_psSessionData->szDir, "/"); } if (!_psSessionData->szHostHeader) { nBufLength = strlen(_psLogin->psServer->psHost->pHost) + 1 + log(params.nPort) + 1; _psSessionData->szHostHeader = malloc(nBufLength + 1); memset(_psSessionData->szHostHeader, 0, nBufLength + 1); sprintf(_psSessionData->szHostHeader, "%s:%d", _psLogin->psServer->psHost->pHost, params.nPort); } if (!_psSessionData->szFormData) { _psSessionData->szFormRest = malloc(1); memset(_psSessionData->szFormRest, 0, 1); _psSessionData->szFormUser = malloc(10); memset(_psSessionData->szFormUser, 0, 10); sprintf(_psSessionData->szFormUser, "username="); _psSessionData->szFormPass = malloc(10); memset(_psSessionData->szFormPass, 0, 10); sprintf(_psSessionData->szFormPass, "password="); _psSessionData->nFormType = FORM_POST; } else { /* Only set user-supplied form data on first pass */ if (_psSessionData->szFormUser == NULL) { pTemp = strtok_r(_psSessionData->szFormData, "?", &pStrtokSavePtr); writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form Action Method: %s", MODULE_NAME, pTemp); if(strncasecmp(pTemp, "POST", 4) == 0) _psSessionData->nFormType=FORM_POST; else if(strncasecmp(pTemp, "GET", 3) == 0) _psSessionData->nFormType=FORM_GET; else _psSessionData->nFormType=FORM_UNKNOWN; pTemp = strtok_r(NULL, "&", &pStrtokSavePtr); if (pTemp != NULL) { _psSessionData->szFormUser = strdup(pTemp); } pTemp = strtok_r(NULL, "&", &pStrtokSavePtr); if (pTemp != NULL) { _psSessionData->szFormPass = strdup(pTemp); } pTemp = strtok_r(NULL, "", &pStrtokSavePtr); if (pTemp != NULL) { _psSessionData->szFormRest = strdup(pTemp); } } writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form User Field: %s", MODULE_NAME, _psSessionData->szFormUser); writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form Pass Field: %s", MODULE_NAME, _psSessionData->szFormPass); writeError(ERR_DEBUG_MODULE, "[%s] User-supplied Form Rest Field: %s", MODULE_NAME, _psSessionData->szFormRest); if ((_psSessionData->nFormType == FORM_UNKNOWN) || (_psSessionData->szFormUser == NULL) || (_psSessionData->szFormPass == NULL)) { writeError(ERR_WARNING, "Invalid FORM-DATA format. Using default format: \"post?username=&password=\""); _psSessionData->szFormRest = malloc(1); memset(_psSessionData->szFormRest, 0, 1); _psSessionData->szFormUser = malloc(10); memset(_psSessionData->szFormUser, 0, 10); sprintf(_psSessionData->szFormUser, "username="); _psSessionData->szFormPass = malloc(10); memset(_psSessionData->szFormPass, 0, 10); sprintf(_psSessionData->szFormPass, "password="); _psSessionData->nFormType=FORM_POST; } } if (!_psSessionData->szUserAgent) { _psSessionData->szUserAgent = malloc(31); memset(_psSessionData->szUserAgent, 0, 31); sprintf(_psSessionData->szUserAgent, "I'm not Mozilla, I'm Ming Mong"); } if (!_psSessionData->szDenySignal) { _psSessionData->szDenySignal = malloc(19); memset(_psSessionData->szDenySignal, 0, 19); sprintf(_psSessionData->szDenySignal, "Login Incorrect"); } if (!_psSessionData->szCustomHeader) { _psSessionData->szCustomHeader = malloc(1); memset(_psSessionData->szCustomHeader, 0, 1); } nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(hSocket, _psSessionData, &_psLogin, psCredSet->psUser->pUser, psCredSet->pPass); if (_psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(_psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: if (hSocket > 0) medusaDisconnect(hSocket); hSocket = -1; nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown HTTP module state (%d). Exiting...", nState); _psLogin->iResult = LOGIN_RESULT_UNKNOWN; break; } } /* clean up memory */ FREE(_psSessionData->szDir); FREE(_psSessionData->szHostHeader); FREE(_psSessionData->szUserAgent); FREE(_psSessionData->szDenySignal); FREE(_psSessionData->szFormData); FREE(_psSessionData->szFormRest); FREE(_psSessionData->szFormUser); FREE(_psSessionData->szFormPass); FREE(_psSessionData->szCustomHeader); FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ char *urlencodeup(char* szStr){ unsigned int i=0,j=0; size_t iLen=strlen(szStr); char * szRet = (char*)malloc(sizeof(char)*((iLen*3) + 1)); static char safechars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; for(i=0;iszFormRest == NULL) || (_psSessionData->szFormRest[0] == 0)) nFormBufferSize = asprintf(&bufForm, "%s%s&%s%s", _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword); else nFormBufferSize = asprintf(&bufForm, "%s%s&%s%s&%s", _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword, _psSessionData->szFormRest); nSendBufferSize = asprintf((char **)&bufSend, "POST /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n%sConnection: close\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: %i\r\n\r\n%s", _psSessionData->szDir, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader, nFormBufferSize, bufForm); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } free(bufSend); free(bufForm); return nRet; } int sendGet(int hSocket, _MODULE_DATA* _psSessionData, char* szLogin, char* szPassword) { unsigned char* bufSend = NULL; int nSendBufferSize = 0; int nRet = SUCCESS; if ((_psSessionData->szFormRest == NULL) || (_psSessionData->szFormRest[0] == 0)) nSendBufferSize = asprintf((char **)&bufSend, "GET /%s?%s%s&%s%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n%sConnection: close\r\n\r\n", _psSessionData->szDir, _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader); else nSendBufferSize = asprintf((char **)&bufSend, "GET /%s?%s%s&%s%s&%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n%sConnection: close\r\n\r\n", _psSessionData->szDir, _psSessionData->szFormUser, szLogin, _psSessionData->szFormPass, szPassword, _psSessionData->szFormRest, _psSessionData->szHostHeader, _psSessionData->szUserAgent, _psSessionData->szCustomHeader); if (medusaSend(hSocket, bufSend, nSendBufferSize, 0) < 0) { writeError(ERR_ERROR, "%s failed: medusaSend was not successful", MODULE_NAME); nRet = FAILURE; } free(bufSend); return nRet; } int tryLogin(int hSocket, _MODULE_DATA* _psSessionData, sLogin** login, char* szLogin, char* szPassword) { unsigned char* pReceiveBuffer = NULL; int nReceiveBufferSize; int nRet = FAILURE; char* pTemp = NULL; char* szPasswordEncoded = NULL; szPasswordEncoded = urlencodeup(szPassword); switch(_psSessionData->nFormType) { case FORM_GET: writeError(ERR_DEBUG_MODULE, "[%s] Sending Web Form Authentication (GET).", MODULE_NAME); nRet = sendGet(hSocket, _psSessionData, szLogin, szPasswordEncoded); break; case FORM_POST: writeError(ERR_DEBUG_MODULE, "[%s] Sending Web Form Authentication (POST).", MODULE_NAME); nRet = sendPost(hSocket, _psSessionData, szLogin, szPasswordEncoded); break; default: break; } if (nRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed during sending of authentication data.", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } writeError(ERR_DEBUG_MODULE, "[%s] Retrieving server response.", MODULE_NAME); pReceiveBuffer = medusaReceiveLine(hSocket, &nReceiveBufferSize); if ((pReceiveBuffer == NULL) || (pReceiveBuffer[0] == '\0')) { writeError(ERR_ERROR, "[%s] No data received", MODULE_NAME); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } pTemp = (char*)index((char *)pReceiveBuffer, ' '); if ( !pTemp || strncmp(pTemp + 1, "200 OK", 6) != 0 ) { writeError(ERR_ERROR, "The answer was NOT successfully received, understood, and accepted while trying %s %s: error code %.4s", szLogin, szPassword, pTemp); (*login)->iResult = LOGIN_RESULT_UNKNOWN; setPassResult(*login, szPassword); return MSTATE_EXITING; } while (pReceiveBuffer != NULL && (strcasestr((char *)pReceiveBuffer, _psSessionData->szDenySignal) == NULL) && (pReceiveBuffer[0] != '\0')) { free(pReceiveBuffer); pReceiveBuffer = medusaReceiveLine(hSocket, &nReceiveBufferSize); } if(pReceiveBuffer != NULL && strcasestr((char *)pReceiveBuffer, _psSessionData->szDenySignal) != NULL) { (*login)->iResult = LOGIN_RESULT_FAIL; setPassResult(*login, szPassword); return MSTATE_NEW; } writeError(ERR_DEBUG_MODULE, "Login Successful"); (*login)->iResult = LOGIN_RESULT_SUCCESS; setPassResult(*login, szPassword); return MSTATE_NEW; } #else void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + strlen(OPENSSL_WARNING) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT_WARN, MODULE_SUMMARY_USAGE, MODULE_VERSION, OPENSSL_WARNING); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); } int go(sLogin* logins, int argc, char *argv[]) { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "** Module was not properly built. Is OPENSSL installed correctly? **"); writeVerbose(VB_NONE, ""); return FAILURE; } #endif jmk-foofus-medusa-dd62069/src/modsrc/wrapper.c000066400000000000000000000504741460263104500213230ustar00rootroot00000000000000/* ** Generic Wrapper Medusa Module ** ** ------------------------------------------------------------------------ ** Copyright (C) 2009 Joe Mondloch ** JoMo-Kun / jmk@foofus.net ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License version 2, ** as published by the Free Software Foundation ** ** 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. ** ** http://www.gnu.org/licenses/gpl.txt ** ** This program is released under the GPL with the additional exemption ** that compiling, linking, and/or using OpenSSL is allowed. ** ** ------------------------------------------------------------------------ ** ** */ #include #include #include #include #include #include "module.h" #define MODULE_NAME "wrapper.mod" #define MODULE_AUTHOR "JoMo-Kun " #define MODULE_SUMMARY_USAGE "Generic Wrapper Module" #define MODULE_VERSION "2.0" #define MODULE_VERSION_SVN "$Id: wrapper.c 9217 2015-05-07 18:07:03Z jmk $" #define MODULE_SUMMARY_FORMAT "%s : version %s" #define MODULE_SUMMARY_FORMAT_WARN "%s : version %s (%s)" #define PARENT_READ iReadPipe[0] #define CHILD_WRITE iReadPipe[1] #define CHILD_READ iWritePipe[0] #define PARENT_WRITE iWritePipe[1] #define TYPE_SINGLE 1 #define TYPE_STDIN 2 typedef struct __MODULE_DATA { char *szCmd; char *szCmdFull; char *szCmdParam; char *szCmdParamFull; int iReadPipe[2]; int iWritePipe[2]; int nType; } _MODULE_DATA; // Tells us whether we are to continue processing or not enum MODULE_STATE { MSTATE_NEW, MSTATE_RUNNING, MSTATE_EXITING, MSTATE_COMPLETE }; // Forward declarations int tryLogin(_MODULE_DATA* _psSessionData, sLogin** login, char* szPassword); int initModule(_MODULE_DATA* _psSessionData, sLogin* login); int initProcess(_MODULE_DATA* _psSessionData); int closeProcess(_MODULE_DATA* _psSessionData); // Tell medusa how many parameters this module allows int getParamNumber() { return 0; // we don't need no stinking parameters } // Displays information about the module and how it must be used void summaryUsage(char **ppszSummary) { // Memory for ppszSummary will be allocated here - caller is responsible for freeing it int iLength = 0; if (*ppszSummary == NULL) { iLength = strlen(MODULE_SUMMARY_USAGE) + strlen(MODULE_VERSION) + strlen(MODULE_SUMMARY_FORMAT) + 1; *ppszSummary = (char*)malloc(iLength); memset(*ppszSummary, 0, iLength); snprintf(*ppszSummary, iLength, MODULE_SUMMARY_FORMAT, MODULE_SUMMARY_USAGE, MODULE_VERSION); } else { writeError(ERR_ERROR, "%s reports an error in summaryUsage() : ppszSummary must be NULL when called", MODULE_NAME); } } /* Display module usage information */ void showUsage() { writeVerbose(VB_NONE, "%s (%s) %s :: %s\n", MODULE_NAME, MODULE_VERSION, MODULE_AUTHOR, MODULE_SUMMARY_USAGE); writeVerbose(VB_NONE, "Available module options:"); writeVerbose(VB_NONE, " TYPE:? (SINGLE, STDIN)"); writeVerbose(VB_NONE, " Option sets type of script being called by module. See included sample scripts"); writeVerbose(VB_NONE, " for ideas how to use this module."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " SINGLE: Script expects all user input comes from original command line."); writeVerbose(VB_NONE, " STDIN: Host and user information passed to script via command line."); writeVerbose(VB_NONE, " Passwords to test are passed via STDIN to script."); writeVerbose(VB_NONE, " "); writeVerbose(VB_NONE, " PROG:? "); writeVerbose(VB_NONE, " Option for setting path to executable file."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, " ARGS:? "); writeVerbose(VB_NONE, " Option for setting executable parameters. The following substitutions can be used:"); writeVerbose(VB_NONE, " %H: Replaced with target IP address."); writeVerbose(VB_NONE, " %U: Replaced with username to test."); writeVerbose(VB_NONE, " %P: Replaced with password to test."); writeVerbose(VB_NONE, ""); writeVerbose(VB_NONE, "Usage example: \'-M wrapper -m TYPE:SINGLE -m PROG:./foo.pl -m ARGS:\"-h %H -u %U -p %P\"\'"); writeVerbose(VB_NONE, "Usage example: \'-M wrapper -m TYPE:STDIN -m PROG:./bar.pl -m ARGS:\"--host %H --user %U\"\'"); } // The "main" of the medusa module world - this is what gets called to actually do the work int go(sLogin* logins, int argc, char *argv[]) { int i, iRet; char *strtok_ptr, *pOpt, *pOptTmp; _MODULE_DATA *psSessionData; psSessionData = malloc(sizeof(_MODULE_DATA)); memset(psSessionData, 0, sizeof(_MODULE_DATA)); if ((argc < 0) || (argc > 3)) { writeError(ERR_ERROR, "%s: Incorrect number of parameters passed to module (%d). Use \"-q\" option to display module usage.", MODULE_NAME, argc); return FAILURE; } else { writeError(ERR_DEBUG_MODULE, "OMG teh %s module has been called!!", MODULE_NAME); for (i=0; inType = TYPE_SINGLE; else if (strcmp(pOpt, "STDIN") == 0) psSessionData->nType = TYPE_STDIN; else writeError(ERR_WARNING, "Invalid value for method TYPE."); } else if (strcmp(pOpt, "PROG") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szCmd = strdup(pOpt); } else writeError(ERR_WARNING, "Method PROG requires value to be set."); } else if (strcmp(pOpt, "ARGS") == 0) { pOpt = strtok_r(NULL, "\0", &strtok_ptr); writeError(ERR_DEBUG_MODULE, "Processing option parameter: %s", pOpt); if ( pOpt ) { psSessionData->szCmdParam = strdup(pOpt); } else writeError(ERR_WARNING, "Method ARGS requires value to be set."); } else { writeError(ERR_WARNING, "Invalid method: %s.", pOpt); } free(pOptTmp); } initModule(psSessionData, logins); iRet = SUCCESS; } FREE(psSessionData); return iRet; } int initModule(_MODULE_DATA *_psSessionData, sLogin* psLogin) { enum MODULE_STATE nState = MSTATE_NEW; char *szTmp = NULL; char *szCmdTmp = NULL; int iRet, nCmdLength; int64_t nCmdPartLength; sCredentialSet *psCredSet = NULL; psCredSet = malloc( sizeof(sCredentialSet) ); memset(psCredSet, 0, sizeof(sCredentialSet)); if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } else if (psCredSet->psUser) { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s user: %s", MODULE_NAME, psLogin->psServer->pHostIP, psCredSet->psUser->pUser); } else { writeError(ERR_DEBUG_MODULE, "[%s] module started for host: %s - no more available users to test.", MODULE_NAME); nState = MSTATE_COMPLETE; } while (nState != MSTATE_COMPLETE) { switch (nState) { case MSTATE_NEW: /* perform parameter substitution -- this is messy... */ writeError(ERR_DEBUG_MODULE, "User-supplied parameters: %s", _psSessionData->szCmdParam); /* --host %H --user %U --pass %P */ if (_psSessionData->nType == TYPE_SINGLE) { nCmdLength = strlen(_psSessionData->szCmdParam); nCmdLength -= 6; nCmdLength += strlen(psLogin->psServer->pHostIP); nCmdLength += strlen(psCredSet->psUser->pUser); nCmdLength += strlen(psCredSet->pPass); } /* --host %H --user %U */ else { nCmdLength = strlen(_psSessionData->szCmdParam); nCmdLength -= 4; nCmdLength += strlen(psLogin->psServer->pHostIP); nCmdLength += strlen(psCredSet->psUser->pUser); } /* adding in 6 characters to temporarily account for %H %U %P values - needed if username/password are shorter than 2 characters each */ _psSessionData->szCmdParamFull = malloc(nCmdLength + 6 + 1); memset(_psSessionData->szCmdParamFull, 0, nCmdLength + 6 + 1); szCmdTmp = malloc(nCmdLength + 6 + 1); memset(szCmdTmp, 0, nCmdLength + 6 + 1); if ((szTmp = strstr(_psSessionData->szCmdParam, "%H")) != NULL) { nCmdPartLength = (int64_t) szTmp - (int64_t) _psSessionData->szCmdParam; writeError(ERR_DEBUG_MODULE, "Processing \%H... Copying (%d) parameter characters.", nCmdPartLength); strncpy(szCmdTmp, _psSessionData->szCmdParam, nCmdPartLength); strcpy(szCmdTmp + nCmdPartLength, psLogin->psServer->pHostIP); strncpy(szCmdTmp + nCmdPartLength + strlen(psLogin->psServer->pHostIP), szTmp + 2, strlen(szTmp) - 2); } else { writeError(ERR_ERROR, "Invalid command parameter format. Missing %H format."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; FREE(szCmdTmp); nState = MSTATE_EXITING; break; } writeError(ERR_DEBUG_MODULE, "Parameters (pass 1): %s", szCmdTmp); if ((szTmp = strstr(szCmdTmp, "%U")) != NULL) { nCmdPartLength = (int64_t) szTmp - (int64_t) szCmdTmp; writeError(ERR_DEBUG_MODULE, "Processing \%U... Copying (%d) parameter characters.", nCmdPartLength); strncpy(_psSessionData->szCmdParamFull, szCmdTmp, nCmdPartLength); strcpy(_psSessionData->szCmdParamFull + nCmdPartLength, psCredSet->psUser->pUser); strncpy(_psSessionData->szCmdParamFull + nCmdPartLength + strlen(psCredSet->psUser->pUser), szTmp + 2, strlen(szTmp) - 2); } else { writeError(ERR_ERROR, "Invalid command parameter format. Missing %U format."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; FREE(szCmdTmp); break; } writeError(ERR_DEBUG_MODULE, "Parameters (pass 2): %s", _psSessionData->szCmdParamFull); if ((_psSessionData->nType == TYPE_SINGLE) && (szTmp = strstr(_psSessionData->szCmdParamFull, "%P"))) { nCmdPartLength = (int64_t) szTmp - (int64_t) _psSessionData->szCmdParamFull; writeError(ERR_DEBUG_MODULE, "Processing \%P... Copying (%d) parameter characters.", nCmdPartLength); strncpy(szCmdTmp, _psSessionData->szCmdParamFull, nCmdPartLength); strcpy(szCmdTmp + nCmdPartLength, psCredSet->pPass); strncpy(szCmdTmp + nCmdPartLength + strlen(psCredSet->pPass), szTmp + 2, strlen(szTmp) - 2); strncpy(_psSessionData->szCmdParamFull, szCmdTmp, nCmdLength + 1); } else if (_psSessionData->nType == TYPE_SINGLE) { writeError(ERR_ERROR, "Invalid command parameter format. Missing %P format."); psLogin->iResult = LOGIN_RESULT_UNKNOWN; nState = MSTATE_EXITING; FREE(szCmdTmp); break; } /* clean-up any extra characters left over from %H %U %P */ memset(_psSessionData->szCmdParamFull + nCmdLength, 0, 6 + 1); FREE(szCmdTmp); writeError(ERR_DEBUG_MODULE, "Parameters (pass 3): %s", _psSessionData->szCmdParamFull); _psSessionData->szCmdFull = malloc(strlen(_psSessionData->szCmd) + strlen(_psSessionData->szCmdParamFull) + 7); memset(_psSessionData->szCmdFull, 0, strlen(_psSessionData->szCmd) + strlen(_psSessionData->szCmdParamFull) + 7); strcpy(_psSessionData->szCmdFull, _psSessionData->szCmd); strcat(_psSessionData->szCmdFull, " "); strcat(_psSessionData->szCmdFull, _psSessionData->szCmdParamFull); strcat(_psSessionData->szCmdFull, " 1>&2"); writeError(ERR_DEBUG_MODULE, "Command line: %s", _psSessionData->szCmdFull); /* end command-line argument parsing */ iRet = initProcess(_psSessionData); if (iRet == FAILURE) { writeError(ERR_ERROR, "[%s] Failed to initialize process.", MODULE_NAME); nState = MSTATE_EXITING; } else nState = MSTATE_RUNNING; break; case MSTATE_RUNNING: nState = tryLogin(_psSessionData, &psLogin, psCredSet->pPass); if (psLogin->iResult != LOGIN_RESULT_UNKNOWN) { if (getNextCredSet(psLogin, psCredSet) == FAILURE) { writeError(ERR_ERROR, "[%s] Error retrieving next credential set to test.", MODULE_NAME); nState = MSTATE_EXITING; } else { if (psCredSet->iStatus == CREDENTIAL_DONE) { writeError(ERR_DEBUG_MODULE, "[%s] No more available credential sets to test.", MODULE_NAME); nState = MSTATE_EXITING; } else if (psCredSet->iStatus == CREDENTIAL_NEW_USER) { writeError(ERR_DEBUG_MODULE, "[%s] Starting testing for new user: %s.", MODULE_NAME, psCredSet->psUser->pUser); nState = MSTATE_NEW; } else writeError(ERR_DEBUG_MODULE, "[%s] Next credential set - user: %s password: %s", MODULE_NAME, psCredSet->psUser->pUser, psCredSet->pPass); } } break; case MSTATE_EXITING: iRet = closeProcess(_psSessionData); nState = MSTATE_COMPLETE; break; default: writeError(ERR_CRITICAL, "Unknown %s module state %d", MODULE_NAME, nState); psLogin->iResult = LOGIN_RESULT_UNKNOWN; return FAILURE; } } closeProcess(_psSessionData); /* clean up memory */ FREE(_psSessionData->szCmd); FREE(_psSessionData->szCmdFull); FREE(_psSessionData->szCmdParam); FREE(_psSessionData->szCmdParamFull); FREE(psCredSet); return SUCCESS; } /* Module Specific Functions */ int initProcess(_MODULE_DATA* _psSessionData) { pid_t fork_result; if ((pipe(_psSessionData->iReadPipe) == 0) && (pipe(_psSessionData->iWritePipe) == 0)) { fork_result = fork(); if (fork_result == (pid_t)-1) { writeError(ERR_ERROR, "Failed to fork management process."); return(FAILURE); } if (fork_result == (pid_t)0) { writeError(ERR_DEBUG_MODULE, "Child process successfully forked"); /* connect parent pipes */ close(_psSessionData->PARENT_WRITE); close(_psSessionData->PARENT_READ); /* connect pipes to STDIN/STDOUT */ if (dup2(_psSessionData->CHILD_READ, STDIN_FILENO) < 0) { writeError(ERR_ERROR, "dup2() Mapping pipe to child's STDIN failed."); exit(EXIT_FAILURE); } if (dup2(_psSessionData->CHILD_WRITE, STDERR_FILENO) < 0) { writeError(ERR_ERROR, "dup2() Mapping pipe to child's STDOUT failed."); exit(EXIT_FAILURE); } if (dup2(_psSessionData->CHILD_WRITE, STDOUT_FILENO) < 0) { writeError(ERR_ERROR, "dup2() Mapping pipe to child's STDOUT failed."); exit(EXIT_FAILURE); } /* STDOUT issue: STDOUT is buffered, while STDERR is not. The child process doesn't send any of its STDOUT down the pipe until it terminates. How does one get rid of this buffering? The following doesn't seem to work like one would think it should: setlinebuf(stdout); writeError() below does not function since STDOUT is directed through the pipe. No real way to tell the user that the child failed... */ /* close old pipes */ close(_psSessionData->CHILD_READ); close(_psSessionData->CHILD_WRITE); /* check if file exists */ if ((fopen(_psSessionData->szCmd, "r")) == NULL) { //writeError(ERR_DEBUG_MODULE, "Failed to open file %s - %s", _psSessionData->szCmd, strerror( errno ) ); fprintf(stderr, "LOGIN_CHILD_FILE_ERROR\n"); } else { /* launch application */ //execlp(_psSessionData->szCmd, _psSessionData->szCmd, _psSessionData->szCmdParamFull, (char *)0); if (system(_psSessionData->szCmdFull) < 0) writeError(ERR_ERROR, "[%s] system() call return error", MODULE_NAME); } /* give the parent a chance to read the error message */ sleep(5); exit(0); } else { writeError(ERR_DEBUG_MODULE, "Parent process successfully forked"); /* connect child pipes */ close(_psSessionData->CHILD_WRITE); close(_psSessionData->CHILD_READ); } } else { writeError(ERR_FATAL, "Failed to create communication pipes."); } return(SUCCESS); } int closeProcess(_MODULE_DATA* _psSessionData) { writeError(ERR_DEBUG_MODULE, "Parent process completed. Closing communication pipes."); close(_psSessionData->PARENT_WRITE); close(_psSessionData->PARENT_READ); return SUCCESS; } int tryLogin(_MODULE_DATA* _psSessionData, sLogin** psLogin, char* szPassword) { int iRet, iDataProcessed; int nDone = 0; char buffer[BUFSIZ + 1]; char *bufSend; char *strtok_ptr, *pBuf, *pBufTmp; if (_psSessionData->nType == TYPE_STDIN) { bufSend = malloc(strlen(szPassword) + 2); memset(bufSend, 0, strlen(szPassword) + 2); sprintf(bufSend, "%s\n", szPassword); iDataProcessed = write(_psSessionData->PARENT_WRITE, bufSend, strlen(bufSend)); writeError(ERR_DEBUG_MODULE, "Sending account login credentials to child process: %s (%d)", bufSend, iDataProcessed); if (iDataProcessed < 0) { writeError(ERR_ERROR, "Error writing to child process buffer."); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } } writeError(ERR_DEBUG_MODULE, "Reading data from child process."); while (!nDone) { iDataProcessed = read(_psSessionData->PARENT_READ, buffer, BUFSIZ); if (iDataProcessed <= 0) { writeError(ERR_ERROR, "Error reading from child process buffer."); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } else { writeError(ERR_DEBUG_MODULE, "Processing child process buffer."); if (strstr(buffer, "LOGIN_RESULT_FAIL")) { writeError(ERR_DEBUG_MODULE, "Child process responded with: LOGIN_RESULT_FAIL."); (*psLogin)->iResult = LOGIN_RESULT_FAIL; if (_psSessionData->nType == TYPE_STDIN) iRet = MSTATE_RUNNING; else iRet = MSTATE_NEW; nDone = 1; } else if (strstr(buffer, "LOGIN_RESULT_SUCCESS")) { writeError(ERR_DEBUG_MODULE, "Child process responded with: LOGIN_RESULT_SUCCESS."); (*psLogin)->iResult = LOGIN_RESULT_SUCCESS; iRet = MSTATE_EXITING; nDone = 1; } else if (strstr(buffer, "LOGIN_RESULT_ERROR")) { /* Allow simple error messages to be passed back to Medusa */ pBufTmp = malloc( sizeof(buffer) ); memset(pBufTmp, 0, sizeof(buffer)); strncpy(pBufTmp, buffer, sizeof(buffer)); pBuf = strtok_r(pBufTmp, ":", &strtok_ptr); pBuf = strtok_r(NULL, "\n", &strtok_ptr); writeError(ERR_ERROR, "Child process responded with: LOGIN_RESULT_ERROR (%s).", pBuf); FREE(pBufTmp); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } else if (strstr(buffer, "LOGIN_CHILD_FILE_ERROR")) { writeError(ERR_ERROR, "Child process failed to execute file: %s", _psSessionData->szCmd); (*psLogin)->iResult = LOGIN_RESULT_ERROR; iRet = MSTATE_EXITING; nDone = 1; } else { writeError(ERR_DEBUG_MODULE, "Child process: %s", buffer); } } } setPassResult((*psLogin), szPassword); return(iRet); } jmk-foofus-medusa-dd62069/src/modsrc/wrapper/000077500000000000000000000000001460263104500211455ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/src/modsrc/wrapper/apache-userdir.pl000077500000000000000000000017551460263104500244110ustar00rootroot00000000000000#!/usr/bin/perl # # # apache-userdir.pl 192.168.0.1 USER PASS 0 [NO SSL] # apache-userdir.pl 192.168.0.1 USER PASS 1 [SSL] # # PASS is ignored... # # HEAD /~username HTTP/1.0 # # medusa -M wrapper -h 192.168.0.1 -U users.txt -p DOESNOTMATTER -m TYPE:SINGLE -m ARGS:"%H %U %P 1" -m PROG:./apache-userdir.pl use LWP::UserAgent; $host = $ARGV[0]; $user = $ARGV[1]; $pass = $ARGV[2]; # ignored $ssl = $ARGV[3]; pop(@ARGV); pop(@ARGV); pop(@ARGV); pop(@ARGV); my $ua = LWP::UserAgent->new(env_proxy => 1, keep_alive => 1, timeout => 3); #$ua->proxy(['http', 'https'], 'http://localhost:8008/'); if ($ssl) { $req = new HTTP::Request GET => "https://$host/~$user"; } else { $req = new HTTP::Request GET => "http://$host/~$user"; } $req->user_agent('MS Internet Exploder/4.0'); my $res = $ua->request($req); if ($res->is_success) { print STDERR "LOGIN_RESULT_SUCCESS\n"; } elsif ($res->code==403) { print STDERR "LOGIN_RESULT_SUCCESS\n"; } else { print STDERR "LOGIN_RESULT_FAIL\n"; } jmk-foofus-medusa-dd62069/src/modsrc/wrapper/null-session.pl000077500000000000000000000034101460263104500241360ustar00rootroot00000000000000#!/usr/bin/perl # # medusa -M wrapper -m TYPE:SINGLE -m PROG:./null-session.pl -m ARGS:"%H %U %P" -u 'foo' -p 'bar' -h 192.168.4.128 # foo.pl -h 192.168.0.20 -u foo -p bar # # W2K - RA=0 enumusers, lsaquery, lookupsids # W2K - RA=1 lsaquery, lookupsids # W2K - RA=2 # XP SP1a lsaquery # 2K3 # 2K3 DC (Pre-W2K Comp.) enumusers, lsaquery, lookupsids # 2K3 DC lsaquery, lookupsids # # other useful commands: # wksinfo, srvinfo, samgroupmem "Domain admins", samaliasmem BUILTIN\administrators $host = $ARGV[0]; $user = $ARGV[1]; $pass = $ARGV[2]; #my $cmd = 'rpcclient -U "' . $user . '%' . $pass . '" -c "enumdomusers" ' . $host; my $cmd = 'rpcclient -U "%" -c "enumdomusers" ' . $host; open(HAND, "$cmd 2>&1|"); @results = ; close(HAND); #print "Results:\n----\n@results\n----\n"; if ( grep(/Error was NT_STATUS_ACCESS_DENIED/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/error: NT_STATUS_ACCESS_DENIED/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/Error was NT_STATUS_BAD_NETWORK_NAME/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/Error was NT_STATUS_CONNECTION_REFUSED/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/error: ERRnosupport/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/Error was NT_STATUS_UNSUCCESSFUL/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/failed session setup with NT_STATUS_LOGON_FAILURE/, @results) ) { print "LOGIN_RESULT_FAIL\n"; } elsif ( grep(/user:/, @results) ) { print "LOGIN_RESULT_SUCCESS\n"; } elsif ( grep(/result was NT_STATUS_ACCESS_DENIED/, @results) ) { print "LOGIN_RESULT_ERROR:Check lsaquery/lookupsids.\n"; } else { print "LOGIN_RESULT_ERROR:Unknown error.\n"; } jmk-foofus-medusa-dd62069/src/modsrc/wrapper/oracle.pl000077500000000000000000000034711460263104500227570ustar00rootroot00000000000000#!/usr/bin/perl # # Oracle Brute-Force Medusa Wrapper Script # Copyright (C) 2006 Joe Mondloch # JoMo-Kun / jmk@foofus.net # # Based on bfora.pl # See bfora for SID enumeration command. Not valid on all Oracle installs... # # Requires DBD::Oracle # # Gentoo Installation Notes # [/etc/portage/packages.keywords] # app-admin/eselect-oracle ~x86 # dev-db/oracle-instantclient-basic ~x86 # dev-db/oracle-instantclient-sqlplus ~x86 # # g-cpan -i DBD::Oracle # If install fails looking *.mk: # cd .cpan/build/DBD-Oracle-1.17; su # export ORACLE_HOME=/usr/lib/oracle/10.2.0.2/client/lib # export LDPATH=/usr/lib/oracle/10.2.0.2/client/lib # export C_INCLUDE_PATH=/usr/lib/oracle/10.2.0.2/client/include # perl Makefile.PL # make install # # Verify that permissions were set correctly on installed files. # oracle.pl -h 192.168.0.1 -u foo # # medusa -M wrapper -h 192.168.0.1 -u SYSTEM -P passwords.txt -m TYPE:STDIN -m PROG:oracle.pl -m ARGS:"%H %U ORCL" require DBI; require DBD::Oracle; $host = $ARGV[0]; $user = $ARGV[1]; $sid = $ARGV[2]; pop(@ARGV); pop(@ARGV); pop(@ARGV); my $port = "1521"; #my $port = "15004"; while (<>) { chomp; $pass = $_; my $msg = "", $err = 0; $SIG{__WARN__} = sub { $msg = $_[0]; }; DBI->connect("dbi:Oracle:host=$host;sid=$sid;port=$port", "$user", "$pass", { RaiseError => 0, PrintError => 1}) or $err = "1"; if ($err) { if ($msg) { if ($msg =~ /ORA-01017: invalid username\/password; logon denied/) { print STDERR "LOGIN_RESULT_FAIL\n"; } else { $msg =~ /failed: (.*) \(DBD ERROR/; print STDERR "LOGIN_RESULT_ERROR:$1\n"; } } else { print STDERR "LOGIN_RESULT_FAIL\n"; } } else { print STDERR "LOGIN_RESULT_SUCCESS\n"; } } jmk-foofus-medusa-dd62069/src/modsrc/wrapper/sample-single.pl000077500000000000000000000004551460263104500242510ustar00rootroot00000000000000#!/usr/bin/perl # # # foo.pl -h 192.168.0.20 -u foo -p bar $host = $ARGV[0]; $user = $ARGV[1]; $pass = $ARGV[2]; sleep(1); if ($pass eq "CORRECT_PASS") { print "LOGIN_RESULT_SUCCESS\n"; } elsif ($pass eq "ERROR_PASS") { print "LOGIN_RESULT_ERROR\n"; } else { print "LOGIN_RESULT_FAIL\n"; } jmk-foofus-medusa-dd62069/src/modsrc/wrapper/sample-stdin.pl000077500000000000000000000006021460263104500241030ustar00rootroot00000000000000#!/usr/bin/perl # # # foo.pl -h 192.168.0.1 -u foo $host = $ARGV[0]; $user = $ARGV[1]; pop(@ARGV); pop(@ARGV); while (<>) { chomp; $pass = $_; sleep(3); if ($pass eq "CORRECT_PASS") { print STDERR "LOGIN_RESULT_SUCCESS\n"; } elsif ($pass eq "ERROR_PASS") { print STDERR "LOGIN_RESULT_ERROR\n"; } else { print STDERR "LOGIN_RESULT_FAIL\n"; } } jmk-foofus-medusa-dd62069/src/test/000077500000000000000000000000001460263104500171555ustar00rootroot00000000000000jmk-foofus-medusa-dd62069/src/test/max_thread_test.c000066400000000000000000000012461460263104500224770ustar00rootroot00000000000000#include #include #include #include void* do_one_thing(void* arg); int main(void) { pthread_t t[500]; int i = 0; for (i = 0; i < 499; i++) { int code = pthread_create(&(t[i]), NULL, do_one_thing, NULL); if (code != 0) { printf("pthread_create error on thread %d, error code = %d\n", i, code); exit(1); } printf("thread %d created.\n", i); } for (i = 0; i < 499; i++) { if (!pthread_join(t[i], NULL)) { printf("pthread_join error on thread %d\n", i+1); } } return 0; } void* do_one_thing(void* arg) { return NULL; } jmk-foofus-medusa-dd62069/src/uthash.h000066400000000000000000001712531460263104500176540ustar00rootroot00000000000000/* Copyright (c) 2003-2009, Troy D. Hanson http://uthash.sourceforge.net All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UTHASH_H #define UTHASH_H #include /* memcmp,strlen */ #include /* ptrdiff_t */ #include /* uint32_t etc */ #define UTHASH_VERSION 1.8 /* C++ requires extra stringent casting */ #if defined __cplusplus #define TYPEOF(x) (typeof(x)) #else #define TYPEOF(x) #endif #define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ #define uthash_malloc(sz) malloc(sz) /* malloc fcn */ #define uthash_free(ptr) free(ptr) /* free fcn */ #define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ #define uthash_expand_fyi(tbl) /* can be defined to log expands */ /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ #define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ #define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ /* calculate the element whose hash handle address is hhe */ #define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)hhp) - (tbl)->hho)) #define HASH_FIND(hh,head,keyptr,keylen,out) \ do { \ unsigned _hf_bkt,_hf_hashv; \ out=TYPEOF(out)NULL; \ if (head) { \ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ keyptr,keylen,out); \ } \ } \ } while (0) #ifdef HASH_BLOOM #define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) #define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) #define HASH_BLOOM_MAKE(tbl) \ do { \ (tbl)->bloom_nbits = HASH_BLOOM; \ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ } while (0); #define HASH_BLOOM_FREE(tbl) \ do { \ uthash_free((tbl)->bloom_bv); \ } while (0); #define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) #define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) #define HASH_BLOOM_ADD(tbl,hashv) \ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #define HASH_BLOOM_TEST(tbl,hashv) \ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #else #define HASH_BLOOM_MAKE(tbl) #define HASH_BLOOM_FREE(tbl) #define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) #endif #define HASH_MAKE_TABLE(hh,head) \ do { \ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ sizeof(UT_hash_table)); \ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ (head)->hh.tbl->tail = &((head)->hh); \ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ memset((head)->hh.tbl->buckets, 0, \ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ HASH_BLOOM_MAKE((head)->hh.tbl); \ (head)->hh.tbl->signature = HASH_SIGNATURE; \ } while(0) #define HASH_ADD(hh,head,fieldname,keylen_in,add) \ HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) #define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ do { \ unsigned _ha_bkt; \ (add)->hh.next = NULL; \ (add)->hh.key = (char*)keyptr; \ (add)->hh.keylen = keylen_in; \ if (!(head)) { \ head = (add); \ (head)->hh.prev = NULL; \ HASH_MAKE_TABLE(hh,head); \ } else { \ (head)->hh.tbl->tail->next = (add); \ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ (head)->hh.tbl->tail = &((add)->hh); \ } \ (head)->hh.tbl->num_items++; \ (add)->hh.tbl = (head)->hh.tbl; \ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ (add)->hh.hashv, _ha_bkt); \ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ HASH_FSCK(hh,head); \ } while(0) #define HASH_TO_BKT( hashv, num_bkts, bkt ) \ do { \ bkt = ((hashv) & ((num_bkts) - 1)); \ } while(0) /* delete "delptr" from the hash table. * "the usual" patch-up process for the app-order doubly-linked-list. * The use of _hd_hh_del below deserves special explanation. * These used to be expressed using (delptr) but that led to a bug * if someone used the same symbol for the head and deletee, like * HASH_DELETE(hh,users,users); * We want that to work, but by changing the head (users) below * we were forfeiting our ability to further refer to the deletee (users) * in the patch-up process. Solution: use scratch space in the table to * copy the deletee pointer, then the latter references are via that * scratch pointer rather than through the repointed (users) symbol. */ #define HASH_DELETE(hh,head,delptr) \ do { \ unsigned _hd_bkt; \ struct UT_hash_handle *_hd_hh_del; \ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ uthash_free((head)->hh.tbl->buckets ); \ HASH_BLOOM_FREE((head)->hh.tbl); \ uthash_free((head)->hh.tbl); \ head = NULL; \ } else { \ _hd_hh_del = &((delptr)->hh); \ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ (head)->hh.tbl->tail = \ (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ (head)->hh.tbl->hho); \ } \ if ((delptr)->hh.prev) { \ ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ } else { \ head = TYPEOF(head)((delptr)->hh.next); \ } \ if (_hd_hh_del->next) { \ ((UT_hash_handle*)((char*)_hd_hh_del->next + \ (head)->hh.tbl->hho))->prev = \ _hd_hh_del->prev; \ } \ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ (head)->hh.tbl->num_items--; \ } \ HASH_FSCK(hh,head); \ } while (0) /* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ #define HASH_FIND_STR(head,findstr,out) \ HASH_FIND(hh,head,findstr,strlen(findstr),out) #define HASH_ADD_STR(head,strfield,add) \ HASH_ADD(hh,head,strfield,strlen(add->strfield),add) #define HASH_FIND_INT(head,findint,out) \ HASH_FIND(hh,head,findint,sizeof(int),out) #define HASH_ADD_INT(head,intfield,add) \ HASH_ADD(hh,head,intfield,sizeof(int),add) #define HASH_DEL(head,delptr) \ HASH_DELETE(hh,head,delptr) /* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. */ #ifdef HASH_DEBUG #define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) #define HASH_FSCK(hh,head) \ do { \ unsigned _bkt_i; \ unsigned _count, _bkt_count; \ char *_prev; \ struct UT_hash_handle *_thh; \ if (head) { \ _count = 0; \ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ _bkt_count = 0; \ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ _prev = NULL; \ while (_thh) { \ if (_prev != (char*)(_thh->hh_prev)) { \ HASH_OOPS("invalid hh_prev %p, actual %p\n", \ _thh->hh_prev, _prev ); \ } \ _bkt_count++; \ _prev = (char*)(_thh); \ _thh = _thh->hh_next; \ } \ _count += _bkt_count; \ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ HASH_OOPS("invalid bucket count %d, actual %d\n", \ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ } \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid hh item count %d, actual %d\n", \ (head)->hh.tbl->num_items, _count ); \ } \ /* traverse hh in app order; check next/prev integrity, count */ \ _count = 0; \ _prev = NULL; \ _thh = &(head)->hh; \ while (_thh) { \ _count++; \ if (_prev !=(char*)(_thh->prev)) { \ HASH_OOPS("invalid prev %p, actual %p\n", \ _thh->prev, _prev ); \ } \ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ (head)->hh.tbl->hho) : NULL ); \ } \ if (_count != (head)->hh.tbl->num_items) { \ HASH_OOPS("invalid app item count %d, actual %d\n", \ (head)->hh.tbl->num_items, _count ); \ } \ } \ } while (0) #else #define HASH_FSCK(hh,head) #endif /* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ do { \ unsigned _klen = fieldlen; \ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); \ } while (0) #else #define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ #ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN #endif /* The Bernstein hash function, used in Perl prior to v5.6 */ #define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hb_keylen=keylen; \ char *_hb_key=(char*)key; \ (hashv) = 0; \ while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ bkt = (hashv) & (num_bkts-1); \ } while (0) /* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _sx_i; \ char *_hs_key=(char*)key; \ hashv = 0; \ for(_sx_i=0; _sx_i < keylen; _sx_i++) \ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ bkt = hashv & (num_bkts-1); \ } while (0) #define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _fn_i; \ char *_hf_key=(char*)key; \ hashv = 2166136261UL; \ for(_fn_i=0; _fn_i < keylen; _fn_i++) \ hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ bkt = hashv & (num_bkts-1); \ } while(0); #define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _ho_i; \ char *_ho_key=(char*)key; \ hashv = 0; \ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ hashv += _ho_key[_ho_i]; \ hashv += (hashv << 10); \ hashv ^= (hashv >> 6); \ } \ hashv += (hashv << 3); \ hashv ^= (hashv >> 11); \ hashv += (hashv << 15); \ bkt = hashv & (num_bkts-1); \ } while(0) #define HASH_JEN_MIX(a,b,c) \ do { \ a -= b; a -= c; a ^= ( c >> 13 ); \ b -= c; b -= a; b ^= ( a << 8 ); \ c -= a; c -= b; c ^= ( b >> 13 ); \ a -= b; a -= c; a ^= ( c >> 12 ); \ b -= c; b -= a; b ^= ( a << 16 ); \ c -= a; c -= b; c ^= ( b >> 5 ); \ a -= b; a -= c; a ^= ( c >> 3 ); \ b -= c; b -= a; b ^= ( a << 10 ); \ c -= a; c -= b; c ^= ( b >> 15 ); \ } while (0) #define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ do { \ unsigned _hj_i,_hj_j,_hj_k; \ char *_hj_key=(char*)key; \ hashv = 0xfeedbeef; \ _hj_i = _hj_j = 0x9e3779b9; \ _hj_k = keylen; \ while (_hj_k >= 12) { \ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + ( (unsigned)_hj_key[2] << 16 ) \ + ( (unsigned)_hj_key[3] << 24 ) ); \ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + ( (unsigned)_hj_key[6] << 16 ) \ + ( (unsigned)_hj_key[7] << 24 ) ); \ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + ( (unsigned)_hj_key[10] << 16 ) \ + ( (unsigned)_hj_key[11] << 24 ) ); \ \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ \ _hj_key += 12; \ _hj_k -= 12; \ } \ hashv += keylen; \ switch ( _hj_k ) { \ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ case 5: _hj_j += _hj_key[4]; \ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ case 1: _hj_i += _hj_key[0]; \ } \ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ bkt = hashv & (num_bkts-1); \ } while(0) /* The Paul Hsieh hash function */ #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) #define get16bits(d) (*((const uint16_t *) (d))) #endif #if !defined (get16bits) #define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ +(uint32_t)(((const uint8_t *)(d))[0]) ) #endif #define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ do { \ char *_sfh_key=(char*)key; \ uint32_t _sfh_tmp, _sfh_len = keylen; \ \ int _sfh_rem = _sfh_len & 3; \ _sfh_len >>= 2; \ hashv = 0xcafebabe; \ \ /* Main loop */ \ for (;_sfh_len > 0; _sfh_len--) { \ hashv += get16bits (_sfh_key); \ _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ hashv = (hashv << 16) ^ _sfh_tmp; \ _sfh_key += 2*sizeof (uint16_t); \ hashv += hashv >> 11; \ } \ \ /* Handle end cases */ \ switch (_sfh_rem) { \ case 3: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 16; \ hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ hashv += hashv >> 11; \ break; \ case 2: hashv += get16bits (_sfh_key); \ hashv ^= hashv << 11; \ hashv += hashv >> 17; \ break; \ case 1: hashv += *_sfh_key; \ hashv ^= hashv << 10; \ hashv += hashv >> 1; \ } \ \ /* Force "avalanching" of final 127 bits */ \ hashv ^= hashv << 3; \ hashv += hashv >> 5; \ hashv ^= hashv << 4; \ hashv += hashv >> 17; \ hashv ^= hashv << 25; \ hashv += hashv >> 6; \ bkt = hashv & (num_bkts-1); \ } while(0); #ifdef HASH_USING_NO_STRICT_ALIASING /* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * So MurmurHash comes in two versions, the faster unaligned one and the slower * aligned one. We only use the faster one on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ #if (defined(__i386__) || defined(__x86_64__)) #define HASH_MUR HASH_MUR_UNALIGNED #else #define HASH_MUR HASH_MUR_ALIGNED #endif /* Appleby's MurmurHash fast version for unaligned-tolerant archs like i386 */ #define HASH_MUR_UNALIGNED(key,keylen,num_bkts,hashv,bkt) \ do { \ const unsigned int _mur_m = 0x5bd1e995; \ const int _mur_r = 24; \ hashv = 0xcafebabe ^ keylen; \ char *_mur_key = (char *)key; \ uint32_t _mur_tmp, _mur_len = keylen; \ \ for (;_mur_len >= 4; _mur_len-=4) { \ _mur_tmp = *(uint32_t *)_mur_key; \ _mur_tmp *= _mur_m; \ _mur_tmp ^= _mur_tmp >> _mur_r; \ _mur_tmp *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_tmp; \ _mur_key += 4; \ } \ \ switch(_mur_len) \ { \ case 3: hashv ^= _mur_key[2] << 16; \ case 2: hashv ^= _mur_key[1] << 8; \ case 1: hashv ^= _mur_key[0]; \ hashv *= _mur_m; \ }; \ \ hashv ^= hashv >> 13; \ hashv *= _mur_m; \ hashv ^= hashv >> 15; \ \ bkt = hashv & (num_bkts-1); \ } while(0) /* Appleby's MurmurHash version for alignment-sensitive archs like Sparc */ #define HASH_MUR_ALIGNED(key,keylen,num_bkts,hashv,bkt) \ do { \ const unsigned int _mur_m = 0x5bd1e995; \ const int _mur_r = 24; \ hashv = 0xcafebabe ^ keylen; \ char *_mur_key = (char *)key; \ uint32_t _mur_len = keylen; \ int _mur_align = (int)_mur_key & 3; \ \ if (_mur_align && (_mur_len >= 4)) { \ unsigned _mur_t = 0, _mur_d = 0; \ switch(_mur_align) { \ case 1: _mur_t |= _mur_key[2] << 16; \ case 2: _mur_t |= _mur_key[1] << 8; \ case 3: _mur_t |= _mur_key[0]; \ } \ _mur_t <<= (8 * _mur_align); \ _mur_key += 4-_mur_align; \ _mur_len -= 4-_mur_align; \ int _mur_sl = 8 * (4-_mur_align); \ int _mur_sr = 8 * _mur_align; \ \ for (;_mur_len >= 4; _mur_len-=4) { \ _mur_d = *(unsigned *)_mur_key; \ _mur_t = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ unsigned _mur_k = _mur_t; \ _mur_k *= _mur_m; \ _mur_k ^= _mur_k >> _mur_r; \ _mur_k *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_k; \ _mur_t = _mur_d; \ _mur_key += 4; \ } \ _mur_d = 0; \ if(_mur_len >= _mur_align) { \ switch(_mur_align) { \ case 3: _mur_d |= _mur_key[2] << 16; \ case 2: _mur_d |= _mur_key[1] << 8; \ case 1: _mur_d |= _mur_key[0]; \ } \ unsigned _mur_k = (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ _mur_k *= _mur_m; \ _mur_k ^= _mur_k >> _mur_r; \ _mur_k *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_k; \ _mur_k += _mur_align; \ _mur_len -= _mur_align; \ \ switch(_mur_len) \ { \ case 3: hashv ^= _mur_key[2] << 16; \ case 2: hashv ^= _mur_key[1] << 8; \ case 1: hashv ^= _mur_key[0]; \ hashv *= _mur_m; \ } \ } else { \ switch(_mur_len) \ { \ case 3: _mur_d ^= _mur_key[2] << 16; \ case 2: _mur_d ^= _mur_key[1] << 8; \ case 1: _mur_d ^= _mur_key[0]; \ case 0: hashv ^= (_mur_t >> _mur_sr) | (_mur_d << _mur_sl); \ hashv *= _mur_m; \ } \ } \ \ hashv ^= hashv >> 13; \ hashv *= _mur_m; \ hashv ^= hashv >> 15; \ } else { \ for (;_mur_len >= 4; _mur_len-=4) { \ unsigned _mur_k = *(unsigned*)_mur_key; \ _mur_k *= _mur_m; \ _mur_k ^= _mur_k >> _mur_r; \ _mur_k *= _mur_m; \ hashv *= _mur_m; \ hashv ^= _mur_k; \ _mur_key += 4; \ } \ switch(_mur_len) \ { \ case 3: hashv ^= _mur_key[2] << 16; \ case 2: hashv ^= _mur_key[1] << 8; \ case 1: hashv ^= _mur_key[0]; \ hashv *= _mur_m; \ } \ \ hashv ^= hashv >> 13; \ hashv *= _mur_m; \ hashv ^= hashv >> 15; \ } \ bkt = hashv & (num_bkts-1); \ } while(0) #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ #define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ out = TYPEOF(out)((head.hh_head) ? ELMT_FROM_HH(tbl,head.hh_head) : NULL); \ while (out) { \ if (out->hh.keylen == keylen_in) { \ if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ } \ out= TYPEOF(out)((out->hh.hh_next) ? \ ELMT_FROM_HH(tbl,out->hh.hh_next) : NULL); \ } /* add an item to a bucket */ #define HASH_ADD_TO_BKT(head,addhh) \ do { \ head.count++; \ (addhh)->hh_next = head.hh_head; \ (addhh)->hh_prev = NULL; \ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ (head).hh_head=addhh; \ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ && (addhh)->tbl->noexpand != 1) { \ HASH_EXPAND_BUCKETS((addhh)->tbl); \ } \ } while(0) /* remove an item from a given bucket */ #define HASH_DEL_IN_BKT(hh,head,hh_del) \ (head).count--; \ if ((head).hh_head == hh_del) { \ (head).hh_head = hh_del->hh_next; \ } \ if (hh_del->hh_prev) { \ hh_del->hh_prev->hh_next = hh_del->hh_next; \ } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of * the hash function as it applies to the key domain). * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write * * ceil(n/b) = (n/b) + ((n%b)?1:0) * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ unsigned _he_bkt; \ unsigned _he_bkt_i; \ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ memset(_he_new_buckets, 0, \ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ tbl->ideal_chain_maxlen = \ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ tbl->nonideal_items = 0; \ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ { \ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ while (_he_thh) { \ _he_hh_nxt = _he_thh->hh_next; \ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ tbl->nonideal_items++; \ _he_newbkt->expand_mult = _he_newbkt->count / \ tbl->ideal_chain_maxlen; \ } \ _he_thh->hh_prev = NULL; \ _he_thh->hh_next = _he_newbkt->hh_head; \ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ _he_thh; \ _he_newbkt->hh_head = _he_thh; \ _he_thh = _he_hh_nxt; \ } \ } \ tbl->num_buckets *= 2; \ tbl->log2_num_buckets++; \ uthash_free( tbl->buckets ); \ tbl->buckets = _he_new_buckets; \ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ (tbl->ineff_expands+1) : 0; \ if (tbl->ineff_expands > 1) { \ tbl->noexpand=1; \ uthash_noexpand_fyi(tbl); \ } \ uthash_expand_fyi(tbl); \ } while(0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ /* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ do { \ unsigned _hs_i; \ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ if (head) { \ _hs_insize = 1; \ _hs_looping = 1; \ _hs_list = &((head)->hh); \ while (_hs_looping) { \ _hs_p = _hs_list; \ _hs_list = NULL; \ _hs_tail = NULL; \ _hs_nmerges = 0; \ while (_hs_p) { \ _hs_nmerges++; \ _hs_q = _hs_p; \ _hs_psize = 0; \ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ _hs_psize++; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ if (! (_hs_q) ) break; \ } \ _hs_qsize = _hs_insize; \ while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ if (_hs_psize == 0) { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else if (( \ cmpfcn(TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ TYPEOF(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ ) <= 0) { \ _hs_e = _hs_p; \ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ ((void*)((char*)(_hs_p->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_psize--; \ } else { \ _hs_e = _hs_q; \ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ ((void*)((char*)(_hs_q->next) + \ (head)->hh.tbl->hho)) : NULL); \ _hs_qsize--; \ } \ if ( _hs_tail ) { \ _hs_tail->next = ((_hs_e) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ } else { \ _hs_list = _hs_e; \ } \ _hs_e->prev = ((_hs_tail) ? \ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ _hs_tail = _hs_e; \ } \ _hs_p = _hs_q; \ } \ _hs_tail->next = NULL; \ if ( _hs_nmerges <= 1 ) { \ _hs_looping=0; \ (head)->hh.tbl->tail = _hs_tail; \ (head) = TYPEOF(head)ELMT_FROM_HH((head)->hh.tbl, _hs_list); \ } \ _hs_insize *= 2; \ } \ HASH_FSCK(hh,head); \ } \ } while (0) /* This function selects items from one hash into another hash. * The end result is that the selected items have dual presence * in both hashes. There is no copy of the items made; rather * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ unsigned _src_bkt, _dst_bkt; \ void *_last_elt=NULL, *_elt; \ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ if (src) { \ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ _src_hh; \ _src_hh = _src_hh->hh_next) { \ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ if (cond(_elt)) { \ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ _dst_hh->key = _src_hh->key; \ _dst_hh->keylen = _src_hh->keylen; \ _dst_hh->hashv = _src_hh->hashv; \ _dst_hh->prev = _last_elt; \ _dst_hh->next = NULL; \ if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ if (!dst) { \ dst = TYPEOF(dst)_elt; \ HASH_MAKE_TABLE(hh_dst,dst); \ } else { \ _dst_hh->tbl = (dst)->hh_dst.tbl; \ } \ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ (dst)->hh_dst.tbl->num_items++; \ _last_elt = _elt; \ _last_elt_hh = _dst_hh; \ } \ } \ } \ } \ HASH_FSCK(hh_dst,dst); \ } while (0) #define HASH_CLEAR(hh,head) \ do { \ if (head) { \ uthash_free((head)->hh.tbl->buckets ); \ uthash_free((head)->hh.tbl); \ (head)=NULL; \ } \ } while(0) /* obtain a count of items in the hash */ #define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) (head?(head->hh.tbl->num_items):0) typedef struct UT_hash_bucket { struct UT_hash_handle *hh_head; unsigned count; /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. * (The multiplier is simply expand_mult+1). The whole idea of this * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; } UT_hash_bucket; /* random signature used only to find hash tables in external analysis */ #define HASH_SIGNATURE 0xa0111fe1 #define HASH_BLOOM_SIGNATURE 0xb12220f2 typedef struct UT_hash_table { UT_hash_bucket *buckets; unsigned num_buckets, log2_num_buckets; unsigned num_items; struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ /* in an ideal situation (all buckets used equally), no bucket would have * more than ceil(#items/#buckets) items. that's the ideal chain length. */ unsigned ideal_chain_maxlen; /* nonideal_items is the number of items in the hash whose chain position * exceeds the ideal chain maxlen. these items pay the penalty for an uneven * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash * function isn't a good fit for the key domain. When expansion is inhibited * the hash will still work, albeit no longer in constant time. */ unsigned ineff_expands, noexpand; uint32_t signature; /* used only to find hash tables in external analysis */ #ifdef HASH_BLOOM uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ uint8_t *bloom_bv; char bloom_nbits; #endif } UT_hash_table; typedef struct UT_hash_handle { struct UT_hash_table *tbl; void *prev; /* prev element in app order */ void *next; /* next element in app order */ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ struct UT_hash_handle *hh_next; /* next hh in bucket order */ void *key; /* ptr to enclosing struct's key */ unsigned keylen; /* enclosing struct's key len */ unsigned hashv; /* result of hash-fcn(key) */ } UT_hash_handle; #endif /* UTHASH_H */