dsbl-testers/0000755000175000017500000000000010520162304011234 5ustar alaldsbl-testers/GPL0000644000175000017500000002776707452667677011665 0ustar alal 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 dsbl-testers/man/0000755000175000017500000000000007776605641012040 5ustar alaldsbl-testers/man/formmailtest.10000644000175000017500000000301307470472316014615 0ustar alal.\" (C) 2002 Ian Gulliver .TH formmailtest 1 2002-04-03 .SH NAME formmailtest \- attempt to use formmail to relay to a DSBL-complaint host .SH SYNOPSIS .BI "formmailtest <" "url" "> [<" "spoof recipient" ">]" .SH DESCRIPTION formmailtest attempts to connect to the specified host and uses several different to attempt to relay through the FormMail script located at .RI < url >. It can do more tests if the normal recipient for that FormMail script is provided as .RI < "spoof recipient" >, but it can quite often relay without. Tests are done with both GET and POST to attempt to bypass any firewall/httpd.conf/.htaccess pseudo-security. In the tests described below, .I DOMAIN is the section of .RI < "spoof recipient" > after the @ sign, .I USER is the section before, and .I DASHDOMAIN is .I DOMAIN after all periods have been replaced by dashes. .HP Tests: .br recipient=listme@dsbl.org .br recipient=dsbl.org!listme .br realname=&email=\\nCc: listme@dsbl.org&recipient=() .br realname=)\\nCc: listme@dsbl.org (&recipient=() .br .RI recipient=listme%dsbl.org@ DOMAIN .br .RI recipient=dsbl.org!listme@ DOMAIN .br .RI recipient=listme@dsbl.org( DOMAIN .br .RI recipient= DOMAIN .br .RI "realname=&email=\\nCc: listme@dsbl.org&recipient=" DOMAIN .br .RI "realname=)\\nCc: listme@dsbl.org (&email=&recipient=" DOMAIN .br .RI recipient=listme@dsbl.org( USER @ DASHDOMAIN .br .RI recipient= USER @ DASHDOMAIN .br .SH AUTHOR Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5), .BR spamtrap (1) dsbl-testers/man/socks4test.10000644000175000017500000000124407470472317014222 0ustar alal.\" (C) 2002 Ian Gulliver .TH socks4test 1 2002-04-03 .SH NAME socks4test \- attempt to use SOCKS 4 to relay to a DSBL-complaint host .SH SYNOPSIS .BI "socks4test <" "socks ip" "> <" "socks port" ">" .SH DESCRIPTION socks4test attempts to connect to port .RI < "socks port" > on .RI < "socks ip" > and relay through the host. It uses your .I sender_user as specified in your .BR dsbl.conf (5), "nobody", and "" as users to make the attempt. It attempts to connect to the .I target_domain mail server directly to send mail, and also to relay through .SM 127.0.0.1 on the host. .SH AUTHOR Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5), .BR spamtrap (1) dsbl-testers/man/socks5test.10000644000175000017500000000116007470472317014220 0ustar alal.\" (C) 2002 Ian Gulliver .TH socks5test 1 2002-04-03 .SH NAME socks5test \- attempt to use SOCKS 5 to relay to a DSBL-complaint host .SH SYNOPSIS .BI "socks5test <" "socks ip" "> <" "socks port" ">" .SH DESCRIPTION socks5test attempts to connect to port .RI < "socks port" > on .RI < "socks ip" > and relay through the host. It attempts to connect to the .I target_domain mail server directly to send mail, and also to relay through .SM 127.0.0.1 on the host. It only attempts using the SOCKS 5 "No Authentication" scheme. .SH AUTHOR Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5), .BR spamtrap (1) dsbl-testers/man/relaytest.10000644000175000017500000000722007776605641014137 0ustar alal.\" (C) 2002 Ian Gulliver .TH relaytest 1 2002-04-03 .SH NAME relaytest \- attempt to use SMTP to relay to a DSBL-compliant host .SH SYNOPSIS .BI "relaytest [-v] <" "ip address" "[:" "port" "]>" .SH DESCRIPTION relaytest attempts to connect to the specified .RI < "ip address" > on the specified .RI "" port "" (default is port 25) and uses a variety of tests to attempt to relay through the host. In the tests below, .B source.com is .I sender_domain from .BR dsbl.conf (5) and sender is .IR sender_user . .HP Non-domain-specific tests: MAIL FROM: .br RCPT TO: MAIL FROM: .br RCPT TO:<"listme@dsbl.org"> MAIL FROM: .br RCPT TO:listme@dsbl.org MAIL FROM: .br RCPT TO: MAIL FROM: .br RCPT TO: MAIL FROM: .br RCPT TO:<"listme@dsbl.org"> MAIL FROM: .br RCPT TO:listme@dsbl.org MAIL FROM: .br RCPT TO: MAIL FROM: .br RCPT TO: MAIL FROM: .br RCPT TO:<"listme@dsbl.org"> MAIL FROM: .br RCPT TO:listme@dsbl.org MAIL FROM: .br RCPT TO: MAIL FROM:<> .br RCPT TO: MAIL FROM:<> .br RCPT TO:<"listme@dsbl.org"> MAIL FROM:<> .br RCPT TO:listme@dsbl.org MAIL FROM:<> .br RCPT TO: .LP relaytest then builds a list of possible domains, including "[127.0.0.1]", "localhost", .RI [< "ip address" >], and any other domains that can be derived from reverse DNS of the IP or the SMTP greeting. .HP Domain specific tests: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO:<"listme@dsbl.org"> .RB "MAIL FROM: .br RCPT TO:listme@dsbl.org .RB "MAIL FROM: .br .RB "RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO:<"listme%dsbl.org"> .RB "MAIL FROM: .br .RB "RCPT TO: .RB "MAIL FROM: .br .RB "RCPT TO:<""listme@dsbl.org""@" DOMAIN > .RB "MAIL FROM: .br .RB "RCPT TO:<@" DOMAIN :listme@dsbl.org> .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br .RB "RCPT TO: .RB "MAIL FROM:<" DOMAIN !nobody> .br RCPT TO: .RB "MAIL FROM:<" DOMAIN !nobody> .br .RB "RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO: .RB "MAIL FROM: .br RCPT TO: .LP relaytest then tries a variety of SMTP AUTH methods to try to relay a message through the target server. .HP The envelopes used for these tests are always: MAIL FROM: .br RCPT TO: .HP The SMTP AUTH methods tried are as follows: AUTH LOGIN, user=/webmaster, password=(null) .br AUTH LOGIN, user=admin, password=admin .br AUTH LOGIN, user=administrator, password=(null) .br AUTH LOGIN, user=test, password=test .br AUTH NTLM (anonymous) .SH OPTIONS .TP .B \-v Verbose mode. Details of the SMTP transaction are written to standard output. .SH AUTHOR Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5), .BR spamtrap (1) dsbl-testers/man/spamtrap.10000644000175000017500000000126607470464621013746 0ustar alal.\" (C) 2002 Ian Gulliver .TH spamtrap 1 2002-04-03 .SH NAME spamtrap \- read mail from stdin and test .SH SYNOPSIS .HP In /etc/aliases: .br .BI spamtrap:|/usr/local/bin/spamtrap .HP In .qmail: .br .BI |/usr/local/bin/spamtrap .SH DESCRIPTION spamtrap reads spam from stdin. It locates any IP addresses in the spam and tests them using .BR relaytest (1), .BR httptest (1), .BR socks4test (1), .BR socks5test (1), and .BR formmailtest (1). If any of these IP addresses are open to relaying, they will be added to the DSBL-compliant server that these programs are configured to use. .SH AUTHOR Rik van Riel Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5) dsbl-testers/man/dsbl.conf.50000644000175000017500000001074007470751231013764 0ustar alal.\" (C) 2002 Ian Gulliver .TH dsbl.conf 5 2002-04-03 .SH NAME dsbl.conf \- configuration file for all DSBL testers .SH SYNOPSIS vi /usr/local/etc/dsbl.conf .br vi ~/.dsblrc .SH DESCRIPTION dsbl.conf and .dsblrc both control the functioning of the DSBL test programs and DSBL server programs. ~/.dsblrc is read if it exists, otherwise dsbl.conf in .IR $PREFIX /etc is read. .RI ( PREFIX is set at compile time and is .B /usr/local by default. .HP These files are in the format: .br .BR variable_name =" value """" .br .BR variable_name2 =" value2 """" .HP Test program variables: .br .B sender_user .br If you were sending tests as test@example.com, you would set .B sender_user to "test". .B sender_domain .br If you were sending tests as test@example.com, you would set .B sender_domain to "example.com". .B cookie_host .br Host to retrieve testing cookies from .RI ( cookie.dsbl.org for the DSBL). .B cookie_user .br Username to provide to the cookie server to retrieve a cookie. To test anonymously, set this to "". .B cookie_pass .br Password to provide to the cookie server to retrieve a cookie. To test anonymously, set this to "". .B target_user .br If the listing address is listme@dsbl.org, you would set .B target_user to "listme". .B target_domain .br If the listing address is listme@dsbl.org, you would set .B target_domain to "dsbl.org". .B statedir .br The directory to store the current state (last test date) of IPs. Must be writable by .IR spamtrap (1). .B checklist .br The list to check against before testing hosts. If you are an untrusted tester, this should be .IR unconfirmed.dsbl.org , otherwise it should be .IR list.dsbl.org . .B excluded_ip .br Each .B excluded_ip entry is checked against the beginning of an IP before testing. You should list IPs that are local to you and therefor shouldn't be tested. .B http_port .br An array of configuration variables to specify which ports HTTP proxies should be tested for on. .B socks_port .br An array of configuration variables to specify which ports SOCKS 4 and 5 proxies should be tested for on. .B message .br The actual message to send when relay testing. .B parallel .br A positive integer representing the number of test processes to run simultaneously. .B verbosity .br The amount of information to log to standard output. The options are: .IP 0 No logging 1 Log IP addresses as they are tested 10 Debugging level; log everything .HP Server program variables: .br .B mysql_host .br The hostname to use to connect to the MySQL server. .B mysql_user .br The username to use to connect to the MySQL server. .B mysql_pass .br The password to use to connect to the MySQL server. .B mysql_db .br The name of the DSBL-compliant database on the MySQL server. .B tempdir .br The temporary directory in which to store zones while they are being built. This must be on the same filesystem as .BR zonedir . .B zonedir .br The directory in which to store the zones once they are built. This must be on the same filesystem as .BR tempdir . .B unconfirmed_zone .br The fully qualified domain name of the unconfirmed zone. .B confirmed_zone .br The fully qualified domain name of the confirmed (trusted) singlehop zone. .B multihop_zone .br The fully qualified domain name of the confirmed (trusted) multihop zone. .B unconfirmed_nameserver .br The nameserver of the unconfirmed zone that will be provided in SOA record. .B confirmed_nameserver .br The nameserver of the confirmed (trusted) singlehop zone that will be provided in the SOA record. .B multihop_nameserver .br The nameserver of the confirmed (trusted) multihop zone that will be provided in the SOA record. .B zone_contact .br The contact email address to be provided in the SOA records of both zones. This should have a period (.) instead of an at sign (@). .B zone_message .br The TXT message to provide for each IP in the zones. This should end in the dollar sign character ($) which is replaced by the IP in question. .B listenip .br The IP address, in dotted quad notation, for the SMTP server to listen on. .B clientsperip .br The maximum number of clients per source IP address that will be accepted by the SMTP server. Additional clients from this IP address will be turned away with a temporary error. This is used to prevent attacks from tying up the entire server. .B idletimeout .br The time, in seconds, before an idle SMTP session is terminated. This is used to keep server resources available for other connections. .SH AUTHOR Ian Gulliver dsbl-testers/man/httptest.10000644000175000017500000000212607776605641014002 0ustar alal.\" (C) 2002 Ian Gulliver .TH httptest 1 2002-04-03 .SH NAME httptest \- attempt to use an HTTP proxy to relay to a DSBL-complaint host .SH SYNOPSIS .BI "httptest <" "http ip" "> <" "http port" ">" .SH DESCRIPTION httptest attempts to connect to port .RI < "http port" > on .RI < "http ip" > and relay through the host. It attempts to connect to the .I target_domain mail server directly to send mail, and also to relay through .SM 127.0.0.1 on the host. For each server, it tries all of: GET, POST, CONNECT. It works by embedding SMTP commands in the HTTP request header, which are then copied through to the mail server. There is extra junk in the HTTP header, but most SMTP servers ignore it. If a server is open to this type of relaying, it is highly likely that the relay will be anonymized and there will be no way to track back the sender (save possibly proxy logs). As of version 0.9.5, httptest attempts to use the CONNECT method as intended to form an actual SMTP conversation through the proxy. .SH AUTHOR Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5), .BR spamtrap (1) dsbl-testers/man/auth-relaytest.10000644000175000017500000000353507776575425015111 0ustar alal.\" (C) 2004 Paul Howarth .TH auth-relaytest 1 2004-01-06 .SH NAME auth-relaytest \- attempt to use authenticated SMTP to relay to a DSBL-compliant host .SH SYNOPSIS .BI "auth-relaytest [-tv] " "ntlm" " <" "ip address" "[:" "port" "]>" .br .BI "auth-relaytest [-tv] (" "cram-md5" "|" "login" ") <" "username" "> <" "password" "> <" "ip address" "[:" "port" "]>" .SH DESCRIPTION auth-relaytest attempts to connect to the specified .RI < "ip address" > on the specified .RI "" port "" (default is port 25) and tries to use the supplied authentication data to relay mail through the host. auth-relaytest uses the .IR sender_user ", " sender_domain ", " target_user ", " target_domain ", and " auth-message parameters from .BR dsbl.conf (5) by default. If the .I auth-message parameter is not present, the .I message parameter is used instead. In the first mode of operation shown, auth-relaytest attempts to authenticate using anonymous NTLM authentication. A well-known bug in certain Microsoft SMTP server implementations (described at http://www.microsoft.com/technet/security/bulletin/MS02-011.asp) will allow relaying for any client that authenticates in this way. In the second form of operation, auth-relaytest attempts to authenticate using either the .IR cram-md5 " or " login variant of SMTP AUTH, using the supplied .IR username " and " password . .SH OPTIONS .TP .B \-t Test mode. Instead of using the .I target_domain parameter from .BR dsbl.conf (5), the .I test_target_domain parameter is used instead. This is useful for sending a test message to yourself, perhaps to check that the server is actually relaying the messages. .TP .B \-v Verbose mode. Details of the SMTP transaction are written to standard output. .SH AUTHORS Paul Howarth .br Ian Gulliver .SH SEE ALSO .BR dsbl.conf (5), .BR spamtrap (1), .BR relaytest (1) dsbl-testers/man/getcookie.10000644000175000017500000000133407776575425014102 0ustar alal.\" (C) 2002, 2003 Ian Gulliver & Paul Howarth .TH getcookie 1 2003-12-22 .SH NAME getcookie \- get a cookie from the DSBL server for batch testing .SH SYNOPSIS .BI "getcookie" .SH DESCRIPTION getcookie attempts to retrieve a cookie from the DSBL server and writes it to stdout. If the retrieved cookie value is put into the environment variable DSBL_COOKIE, all of the test programs in the DSBL test suite will use that cookie value rather than attempting to retrieve a cookie themselves, hence saving time and bandwidth when a batch of tests is to be run. .SH AUTHOR Paul Howarth .SH SEE ALSO .BR dsbl.conf (5), .BR socks4test (1), .BR socks5test (1), .BR httptest (1), .BR formmailtest (1), .BR relaytest (1) dsbl-testers/conf/0000755000175000017500000000000007777070472012211 5ustar alaldsbl-testers/conf/dsbl.conf0000644000175000017500000000533507777070472014012 0ustar alal######### Clinet Variables ########## # Username and domain to send as (bounces will go here) #sender_user= #sender_domain= # # Directory to keep IP state information in #statedir= # # Number of tests to run in simultaneously parallel=5 # # HTTP proxy test ports http_port=8080 http_port=8000 http_port=6588 http_port=3128 http_port=443 http_port=81 http_port=80 http_port=808 http_port=2301 http_port=4480 http_port=6588 # # SOCKS 4 and 5 proxy test ports socks_port=1080 socks_port=1298 # # Excluded IP addresses excluded_ip=0. excluded_ip=127. excluded_ip=10. excluded_ip=172.16. excluded_ip=172.17. excluded_ip=172.18. excluded_ip=172.19. excluded_ip=172.20. excluded_ip=172.21. excluded_ip=172.22. excluded_ip=172.23. excluded_ip=172.24. excluded_ip=172.25. excluded_ip=172.26. excluded_ip=172.27. excluded_ip=172.28. excluded_ip=172.29. excluded_ip=172.30. excluded_ip=172.31. excluded_ip=192.168. excluded_ip=255. excluded_ip=0. # testing the DSBL mail server can cause you to list yourself excluded_ip=205.231.149. excluded_ip=205.231.29. # # Cookie server and credentials cookie_host=cookie.dsbl.org cookie_user= cookie_pass= # # Target user (which list you are submitting to) target_user=listme target_domain=listme.dsbl.org # test_target_domain used by auth-relaytest -t #test_target_domain= # # Actual message to send message="This message is a test of your mail server to determine if it will perform relaying (re-sending) of e-mail messages for unauthorized outside parties. This capability, if enabled in your mail server, is widely considered to be serious flaw in mail server security. Your mail server is being tested for relaying capability because we have received mail from it and wish to determine its likelihood to be abused by spammers." # Message to send for auth-relaytest auth-message="This message is a test of your mail server to determine if it will perform relaying (re-sending) of e-mail messages for unauthorized outside parties. This capability, if enabled in your mail server, is widely considered to be serious flaw in mail server security. Your mail server is being tested for relaying capability because we have received mail from it and wish to determine its likelihood to be abused by spammers. Notes on SMTP AUTH vulnerabilities: AUTH NTLM: See http://www.microsoft.com/technet/security/bulletin/MS02-011.asp AUTH LOGIN: See http://www.spamhaus.org/rokso/search.lasso?evidencefile=2669 AUTH CRAM-MD5: See http://www.spamhaus.org/rokso/search.lasso?evidencefile=2669 ... and, obviously, don't choose weak passwords" # # Verbosity level # 0 - Log nothing # 1 - Log IPs tested # 10 - Debug logging verbosity=0 # # The list to check before testing an IP # Trusted testers: set this to list.dsbl.org checklist=unconfirmed.dsbl.org dsbl-testers/formmailtest.c0000644000175000017500000002670007776605641014144 0ustar alal/* relaytest.c - DSBL SMTP open relay tester Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "testlib.h" #define MAXTEST 14 #define NEEDDOMAIN 5 #define NEEDUSER 12 #define WITH_REFERER 1 #define NO_REFERER 0 /* tests: * 0 recipient=listme@dsbl.org * 1 recipient=dsbl.org!listme * 2 realname=&email=\nCc: listme@dsbl.org&recipient=() * 3 realname=)\nCc: listme@dsbl.org (&recipient=() * 4 recipient=listme@dsbl.org&email=\n\nDSBL LISTME... * 5 recipient=listme%dsbl.org@DOMAIN * 6 recipient=dsbl.org!listme@DOMAIN * 7 recipient=listme@dsbl.org(DOMAIN * 8 recipient=DOMAIN * 9 realname=&email=\nCc: listme@dsbl.org&recipient=DOMAIN * 10 realname=&recipient=DOMAIN&email=\nCc: listme@dsbl.org\n\nDSBL LISTME... * 11 realname=)\nCc: listme@dsbl.org (&email=&recipient=DOMAIN * 12 recipient=listme@dsbl.org(USER@DASHDOMAIN * 13 recipient=USER@DASHDOMAIN */ char *maketest(int num, char *intip, char *cookie, char *hostname, char *url, char *spoofuser, char *spoofdomain, char *dashdomain, const char *target_user, const char *target_domain) { static char ret[1024]; switch(num) { case 0: firestring_snprintf(ret,1024,"recipient=%s%%40%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%40%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,intip,cookie,target_user,target_domain,hostname,url); break; case 1: firestring_snprintf(ret,1024,"recipient=%s%%21%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%21%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_domain,target_user,intip,cookie,target_domain,target_user,hostname,url); break; case 2: firestring_snprintf(ret,1024,"realname=&email=%%0ACc%%3A+%s%%40%s&recipient=%%28%%29&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arealname%%3D%%0Aemail%%3D%%5CnCc%%3A+%s%%40%s%%0Arecipient%%3D%%28%%29%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,intip,cookie,target_user,target_domain,hostname,url); break; case 3: firestring_snprintf(ret,1024,"realname=%%29%%0ACc%%3A+%s%%40%s+%%28&recipient=%%28%%29&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arealname%%3D%%29%%5CnCc%%3A+%s%%40%s+%%28%%0Arecipient%%3D%%28%%29%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,intip,cookie,target_user,target_domain,hostname,url); break; case 4: firestring_snprintf(ret,1024,"recipient=%s%%40%s&email=%%0A%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%40%s%%0Aemail%%3D%%5Cn%%5CnDSBL+LISTME...%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,intip,cookie,target_user,target_domain,hostname,url); break; case 5: firestring_snprintf(ret,1024,"recipient=%s%%25%s%%40%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%25%s%%40%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofdomain,intip,cookie,target_user,target_domain,spoofdomain,hostname,url); break; case 6: firestring_snprintf(ret,1024,"recipient=%s%%21%s%%40%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%21%s%%40%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_domain,target_user,spoofdomain,intip,cookie,target_domain,target_user,spoofdomain,hostname,url); break; case 7: firestring_snprintf(ret,1024,"recipient=%s%%40%s%%28%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%40%s%%28%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofdomain,intip,cookie,target_user,target_domain,spoofdomain,hostname,url); break; case 8: firestring_snprintf(ret,1024,"recipient=%%3C%s%%40%s%%3E%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%%3C%s%%40%s%%3E%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofdomain,intip,cookie,target_user,target_domain,spoofdomain,hostname,url); break; case 9: firestring_snprintf(ret,1024,"realname=&email=%%0ACc%%3A+%s%%40%s&recipient=%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arealname%%3D%%0Aemail%%3D%%5CnCc%%3A+%s%%40%s%%0Arecipient%%3D%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofdomain,intip,cookie,target_user,target_domain,spoofdomain,hostname,url); break; case 10: firestring_snprintf(ret,1024,"realname=&recipient=%s&email=%%0ACc%%3A+%s%%40%s%%0A%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arealname%%3D%%0Arecipient%%3D%s%%0Aemail%%3D%%5CnCc%%3A+%s%%40%s%%5Cn%%5CnDSBL+LISTME...%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",spoofdomain,target_user,target_domain,intip,cookie,spoofdomain,target_user,target_domain,hostname,url); break; case 11: firestring_snprintf(ret,1024,"realname=%%29%%0ACc%%3A+%s%%40%s+%%28&email=&recipient=%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arealname%%3D%%29%%5CnCc%%3A+%s%%40%s+%%28%%0Aemail%%3D%%0Arecipient%%3D%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofdomain,intip,cookie,target_user,target_domain,spoofdomain,hostname,url); break; case 12: firestring_snprintf(ret,1024,"recipient=%s%%40%s%%28%s%%40%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%s%%40%s%%28%s%%40%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofuser,dashdomain,intip,cookie,target_user,target_domain,spoofuser,dashdomain,hostname,url); break; case 13: firestring_snprintf(ret,1024,"recipient=%%3C%s%%40%s%%3E%s%%40%s&message=%%0ADSBL+LISTME%%3A+formmail+%s%%0A%s%%0Arecipient%%3D%%3C%s%%40%s%%3E%s%%40%s%%0AURL%%3Dhttp://%s%s%%0ADSBL+END%%0A",target_user,target_domain,spoofuser,dashdomain,intip,cookie,target_user,target_domain,spoofuser,dashdomain,hostname,url); break; default: ret[0] = '\0'; break; } return ret; } int sendpost(int num, char *intip, char *hostname, char *url, struct sockaddr_in *host, char *cookie, char *spoofuser, char *spoofdomain, char *dashdomain, const char *target_user, const char *target_domain, int with_referer_header) { int fd; static char packet[2048]; char *test; int i; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("host socket()"); exit(100); } if (connect(fd,(struct sockaddr *)host,sizeof(struct sockaddr_in)) != 0) { perror("host connect()"); exit(2); } test = maketest(num,intip,cookie,hostname,url,spoofuser,spoofdomain,dashdomain,target_user,target_domain); if (with_referer_header) { i = firestring_snprintf(packet,2048,"POST %s HTTP/1.1\r\n" "Host: %s\r\n" "Referer: http://%s/\r\n" "Content-Length: %d\r\n" "Connection: close\r\n" "\r\n" "%s",url,hostname,hostname,strlen(test),test); } else { i = firestring_snprintf(packet,2048,"POST %s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Length: %d\r\n" "Connection: close\r\n" "\r\n" "%s",url,hostname,strlen(test),test); } if (send(fd,packet,i,0) != i) { perror("host send()"); exit(2); } while (recv(fd,packet,2048,0) == 2048); close(fd); return 0; } int sendget(int num, char *intip, char *hostname, char *url, struct sockaddr_in *host, char *cookie, char *spoofuser, char *spoofdomain, char *dashdomain, const char *target_user, const char *target_domain, int with_referer_header) { int fd; static char packet[2048]; char *test; int i; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("host socket()"); exit(100); } if (connect(fd,(struct sockaddr *)host,sizeof(struct sockaddr_in)) != 0) { perror("host connect()"); exit(2); } test = maketest(num,intip,cookie,hostname,url,spoofuser,spoofdomain,dashdomain,target_user,target_domain); if (with_referer_header) { i = firestring_snprintf(packet,2048,"GET %s?%s HTTP/1.1\r\n" "Host: %s\r\n" "Referer: http://%s/\r\n" "Connection: close\r\n" "\r\n",url,test,hostname,hostname); } else { i = firestring_snprintf(packet,2048,"GET %s?%s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n" "\r\n",url,test,hostname); } if (send(fd,packet,i,0) != i) { perror("host send()"); exit(2); } while (recv(fd,packet,2048,0) == 2048); close(fd); return 0; } /* return values: * 0 - host accepted some tests, may relay * 1 - host accepted no tests, won't relay * 2 - host appears to be blocking tester (or may just be seriously broken) * 100 - format or internal error */ int main(int argc, char **argv) { struct in_addr *in; struct sockaddr_in host_addr; char *cookie; char query[1024]; char intip[16]; char *spoofuser = NULL, *spoofdomain = NULL; char dashdomain[256]; int i; char *tempchr; const char *target_user, *target_domain; setalarm(); if (argc < 2) { fprintf(stderr,"Usage: %s []\n",argv[0]); exit(100); } if (argc == 3) { spoofdomain = argv[2]; tempchr = strchr(spoofdomain,'@'); if (tempchr != NULL) { tempchr[0] = '\0'; spoofuser = spoofdomain; spoofdomain = tempchr + 1; firestring_strncpy(dashdomain,spoofdomain,256); tempchr = dashdomain; while ((tempchr = strchr(tempchr,'.')) != NULL) { tempchr[0] = '-'; tempchr++; } } } if (strncmp(argv[1],"http://",7) != 0) { fprintf(stderr,"Invalid URL.\n"); exit(100); } if (strlen(argv[1]) > 1023) { fprintf(stderr,"URL too long.\n"); exit(100); } tempchr = strchr(&argv[1][7],'/'); if (tempchr == NULL) firestring_strncpy(query,&argv[1][7],1024); else { memcpy(query,&argv[1][7],tempchr - argv[1] - 7); query[tempchr - argv[1] - 7] = '\0'; } in = firedns_aton4(query); if (in == NULL) { in = firedns_resolveip4(query); if (in == NULL) { fprintf(stderr,"Unable to resolve %s\n",query); exit(100); } } memcpy(&host_addr.sin_addr,in,sizeof(struct in_addr)); firestring_strncpy(intip,firedns_ntoa4(in),16); host_addr.sin_family = AF_INET; host_addr.sin_port = htons(80); readconf(); target_user = firestring_conf_find(config,"target_user"); if (target_user == NULL) { fprintf(stderr,"target_user not set in config.\n"); exit(100); } target_domain = firestring_conf_find(config,"target_domain"); if (target_domain == NULL) { fprintf(stderr,"target_domain not set in config.\n"); exit(100); } cookie = getcookie(); for (i = 0; i < MAXTEST; i++) { if (i == NEEDDOMAIN && spoofdomain == NULL) return 0; if (i == NEEDUSER && spoofuser == NULL) return 0; sendget(i,intip,query,tempchr,&host_addr,cookie, spoofuser,spoofdomain,dashdomain,target_user,target_domain,WITH_REFERER); sendget(i,intip,query,tempchr,&host_addr,cookie, spoofuser,spoofdomain,dashdomain,target_user,target_domain,NO_REFERER); sendpost(i,intip,query,tempchr,&host_addr,cookie, spoofuser,spoofdomain,dashdomain,target_user,target_domain,WITH_REFERER); sendpost(i,intip,query,tempchr,&host_addr,cookie, spoofuser,spoofdomain,dashdomain,target_user,target_domain,NO_REFERER); } return 0; } dsbl-testers/contrib/0000755000175000017500000000000007776605641012725 5ustar alaldsbl-testers/contrib/authcheck0000644000175000017500000001246107776575425014621 0ustar alal#!/bin/sh # http://www.spamhaus.org/rokso/evidence.lasso?rokso_id=ROK2669 # # An analysis done in July 2003 has shown that a total of 276 combinations are attempted # (of course new ones can have been added in the meanwhile): # # Usernames: # webmaster, admin, root, test, master, web, www, administrator, backup, server, data, abc # # each with the following passwords: # username, username12, username123, # 1, 111, 123, 1234, 12345, 123456, 1234567, 12345678, 654321, 54321, 00000000, 88888888, # admin, root, pass, passwd, password, super, !@#$%^&* # as well as with a blank password. USERNAMES="administrator webmaster admin test master web www backup server data abc root" case $# in 2) IP=$1; NONTLM=1;; 1) IP=$1; NONTLM=0;; *) echo 'authcheck: usage: authcheck IP[:port]' 1>&2 exit 1;; esac echo Checking $IP if [ -x /usr/bin/getcookie ]; then DSBL_COOKIE=`/usr/bin/getcookie` export DSBL_COOKIE echo "Using batch-mode cookie: $DSBL_COOKIE" fi do_relaytest () { auth-relaytest -v "$@" case $? in 0) logger -t auth-relaytest -p local5.info "$4 AUTH $1 USER=$2 PASS=$3" echo "" echo "-------------------------------------------------------" echo "Server accepted message" echo "AUTH=$1 USER=$2 PASS=$3 IP=$4" echo "-------------------------------------------------------" exit 0 ;; 4) # Auth accepted but message still rejected echo "" echo "========================================================" echo "Server accepted AUTH but rejected mail" echo "AUTH=$1 USER=$2 PASS=$3 IP=$4" echo "You may wish to retry this test at a later date" echo "if this looks like a temporary condition." echo "========================================================" exit 4 ;; 3) # Timeout echo echo "========================================================" echo 'Test timed out. Try again later perhaps?' echo "IP=$IP" echo "========================================================" exit 3 ;; esac } TEMPFILE=/tmp/authcheck.$$ trap 'rm -f $TEMPFILE; exit 1' 1 2 15 echo Checking $IP for AUTH NTLM vulnerability auth-relaytest -v ntlm $IP > $TEMPFILE case $? in 0) cat $TEMPFILE rm -f $TEMPFILE logger -t auth-relaytest -p local5.info "$IP AUTH NTLM (null)" echo "" echo "-------------------------------------------------------" echo "Server accepted message" echo "AUTH=ntlm IP=$IP" echo "-------------------------------------------------------" exit 0 ;; 4) if [ "$NONTLM" = "0" ]; then cat $TEMPFILE rm -f $TEMPFILE # Auth accepted but message still rejected echo "" echo "========================================================" echo "Server accepted AUTH but rejected mail" echo "AUTH=ntlm IP=$IP" echo "You may wish to retry this test at a later date" echo "if this looks like a temporary condition." echo "========================================================" exit 4 fi ;; 3) if [ "$NONTLM" = "0" ]; then cat $TEMPFILE rm -f $TEMPFILE echo echo "========================================================" echo 'Test timed out. Try again later perhaps?' echo "Or try authcheck $IP no-ntlm" echo "========================================================" exit 3 fi ;; esac cat $TEMPFILE PREFERRED_AUTH_STYLE=none if fgrep --silent LOGIN $TEMPFILE; then AUTH_LOGIN=1 PREFERRED_AUTH_STYLE=login else AUTH_LOGIN=0 fi if fgrep --silent CRAM-MD5 $TEMPFILE; then AUTH_CRAM_MD5=1 PREFERRED_AUTH_STYLE=cram-md5 else AUTH_CRAM_MD5=0 fi rm -f $TEMPFILE if [ "$PREFERRED_AUTH_STYLE" != "none" ]; then echo "Checking $IP for simple vulnerabilities" do_relaytest $PREFERRED_AUTH_STYLE /webmaster "" $IP do_relaytest $PREFERRED_AUTH_STYLE guest "" $IP echo "Checking $IP for user=password and no password" for username in $USERNAMES do do_relaytest $PREFERRED_AUTH_STYLE $username $username $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username "" $IP sleep 5 done echo "Checking $IP for other possibilities" for username in $USERNAMES do do_relaytest $PREFERRED_AUTH_STYLE $username ${username}12 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username ${username}123 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 1 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 111 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 123 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 1234 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 12345 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 123456 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 1234567 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 12345678 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 654321 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 54321 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 00000000 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username 88888888 $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username admin $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username root $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username pass $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username passwd $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username password $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username super $IP sleep 5 do_relaytest $PREFERRED_AUTH_STYLE $username '!@#$%^&*' $IP sleep 5 done fi dsbl-testers/README0000644000175000017500000000201107470472316012127 0ustar alalDSBL Tester Source Code ----------------------- (c) 2002 Ian Gulliver under the GNU Public License, Version 2. See GPL for more details. This package contains testing software configured to work with the DSBL (http://dsbl.org/) or DSBL-compliant services. It enables you to send tests to servers based on spam that you receive. If those tests succeed, the results will reach the DSBL host in question, and the relay will be listed. These programs require FireDNS and FireString to build. Both are available from http://ares.penguinhosting.net/~ian/ They also require the MySQL client libraries, available from http://www.mysql.org/ To build the programs, simply type: ./configure make (su to root) make install The makefile accepts the following environment variables to change its behaviour: PREFIX INSTALL_USER CC CFLAGS LDFLAGS SHAREDFLAGS LIBS You may need to alter these for your individual configuration. Thats it. If it doesn't work, I'm sorry. Let me know; you can reach me at ian@penguinhosting.net. dsbl-testers/firemake.binaries0000644000175000017500000000045107776605641014566 0ustar alalformmailtest: formmailtest.o testlib.o httptest: httptest.o testlib.o relaytest: relaytest.o testlib.o socks4test: socks4test.o testlib.o socks5test: socks5test.o testlib.o spamtrap: spamtrap.o testlib.o auth-relaytest: auth-relaytest.o testlib.o md5.o hmac_md5.o getcookie: getcookie.o testlib.o dsbl-testers/configure0000755000175000017500000000521207776605641013174 0ustar alal#!/bin/sh #configure - FireMake configuratin script #Copyright (C) 2002 Ian Gulliver # #This program is free software; you can redistribute it and/or modify #it under the terms of version 2 of the GNU General Public License 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. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA VERSION="1.9.8" ECHO=echo if test -f /usr/ucb/echo; then ECHO=/usr/ucb/echo fi disp() { if test ! "$LASTN" = "1"; then $ECHO -n "$PREPEND" 1>&2 fi LASTN="0" $ECHO "$1" 1>&2 } dispn() { if test ! "$LASTN" = "1"; then $ECHO -n "$PREPEND" 1>&2 fi LASTN="1" $ECHO -n "$1" 1>&2 } module() { test -f firemake/$1 } PHASES="library init config header makefile" disp "FireMake v$VERSION starting...."; disp disp "= Starting dependency check =" for MODULE in `ls firemake`; do REQ=`grep "^#require " firemake/$MODULE 2>/dev/null | cut -d ' ' -f 2`; if test "$?" = "0"; then # module has requirements, check that these modules exist for FILE in $REQ; do if test ! -f firemake/$FILE; then disp " Module $MODULE requires module $FILE which is not present; aborting" exit 1; fi done fi done disp "= Done with dependency check =" disp for PHASE in $PHASES; do disp "= Starting $PHASE phase =" case "$PHASE" in init) exec > /dev/null ;; config) exec > /dev/null ;; header) exec > firemake.h ;; makefile) exec > Makefile ;; esac NEWDATA="1" while test "$NEWDATA" = "1"; do NEWDATA="0" for MODULE in `ls firemake`; do $ECHO "$DID " | grep " ${PHASE}_${MODULE} " > /dev/null if test ! "$?" = "0"; then grep "^#phase $PHASE" firemake/$MODULE > /dev/null 2>/dev/null if test "$?" = "0"; then SAT="1" DEPS=`grep "^#after ${PHASE}_" firemake/$MODULE | cut -d ' ' -f 2`; if test "$?" = "0"; then #runtime dependencies for DEP in $DEPS; do $ECHO "$DID " | grep " ${DEP} " > /dev/null if test ! "$?" = "0"; then SAT="0" fi done fi if test "$SAT" = "1"; then # dependencies satisfied PREPEND=" " . firemake/$MODULE unset PREPEND DID="$DID ${PHASE}_${MODULE}" NEWDATA="1" fi fi fi done done disp "= Done with $PHASE phase =" disp done disp "Finished configuring. Now just run \"make\"" dsbl-testers/socks4test.c0000644000175000017500000002016207501367126013525 0ustar alal/* relaytest.c - DSBL SMTP open relay tester Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "testlib.h" #define SOCKS4_LENGTH 9 struct s_socks4_request { #define SOCKS4_VERSION 0x04 unsigned char version; #define SOCKS4_COMMAND_CONNECT 0x01 unsigned char command; unsigned short port; unsigned char ip[4]; char username[65]; }; struct s_socks4_response { unsigned char version; unsigned char command; unsigned short port; unsigned char ip[4]; }; char headers[4096]; char *getline(int fd) { static char buffer[4096]; static char line[4096]; static int bufpos = 0; int i; char *tempchr; tempchr = memchr(buffer,'\n',bufpos); while (tempchr == NULL) { i = recv(fd,&buffer[bufpos],4095 - bufpos,0); if (i <= 0) /* eof of error, let the parent figure out what to do */ return NULL; bufpos += i; tempchr = memchr(buffer,'\n',bufpos); if (tempchr == NULL && bufpos == 4095) /* line too long (hostile act) */ exit(2); } if (tempchr != NULL) { memcpy(line,buffer,tempchr - buffer); line[tempchr - buffer] = '\0'; bufpos -= (tempchr - buffer) + 1; memcpy(buffer,&tempchr[1],bufpos); return line; } return NULL; } int getresponse(int fd) { char *line; while (1) { line = getline(fd); if (line == NULL) /* eof */ return 9; if (strlen(line) >= 4 && line[3] == '-') continue; else if (line[0] == '1') return 1; else if (line[0] == '2') return 2; else if (line[0] == '3') return 3; else if (line[0] == '4') return 4; else if (line[0] == '5') return 5; else return 8; /* bad code */ } } const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void buildheaders(char *cookie, const char *source, const char *target_user, const char *target_domain) { struct tm *timestruct; time_t temptime; time(&temptime); timestruct = gmtime(&temptime); firestring_snprintf(headers,4096,"Message-ID: <%s@%s>\r\n" "Date: %s, %d %s %d %02d:%02d:%02d +0000\r\n" "To: <%s@%s>\r\n" "Subject: Open SOCKS 4 Proxy Test Message\r\n",cookie,source,days[timestruct->tm_wday],timestruct->tm_mday,months[timestruct->tm_mon],1900 + timestruct->tm_year,timestruct->tm_hour,timestruct->tm_min,timestruct->tm_sec,target_user,target_domain); } int sendtest(int fd, char *intip, int port, struct in_addr *remoteip, char *cookie, const char *sender, const char *source, const char *target_user, const char *target_domain) { char buffer[8192]; int i; i = firestring_snprintf(buffer,8192,"HELO [%s]\r\n",firedns_ntoa4(remoteip)); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 2; i = firestring_snprintf(buffer,8192,"MAIL FROM:<%s@%s>\r\n",sender,source); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer,8192,"RCPT TO:<%s@%s>\r\n",target_user,target_domain); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; firestring_strncpy(buffer,"DATA\r\n",8192); if (send(fd,buffer,6,0) != 6) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer,8192,"%s\r\n" "DSBL LISTME: socks4 %s\r\n" "%s\r\n" "Port %d, Connect to %s\r\n" "DSBL END\r\n" ".\r\n",headers,intip,cookie,port,firedns_ntoa4(remoteip)); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer,8192,"QUIT\r\n"); if (send(fd,buffer,i,0) != i) return 100; return 0; } int testsocks4(char *cookie, char *intip, struct sockaddr_in *socksaddr, const char *sockssource, const char *sourceuser, const char *sourcedomain, struct in_addr *remoteip, const char *target_user, const char *target_domain) { struct s_socks4_request r; struct s_socks4_response res; int i; int f; r.version = SOCKS4_VERSION; r.command = SOCKS4_COMMAND_CONNECT; r.port = htons(25); memcpy(&r.ip,remoteip,sizeof(struct in_addr)); firestring_strncpy(r.username,sockssource,65); f = socket(PF_INET, SOCK_STREAM, 0); if (f == -1) { perror("socket()"); exit(100); } if (connect(f,(struct sockaddr *)socksaddr,sizeof(struct sockaddr_in)) != 0) return 2; i = SOCKS4_LENGTH + strlen(r.username); if (send(f,&r,i,0) != i) { close(f); return 2; } if (recv(f,&res,sizeof(res),0) != sizeof(res)) { close(f); return 2; } if (res.command != 90) { close(f); return 1; } i = getresponse(f); if (i != 2) { close(f); return 2; } i = sendtest(f, intip, ntohs(socksaddr->sin_port), remoteip, cookie, sourceuser, sourcedomain, target_user, target_domain); close(f); return i; } /* return values: * 0 - host accepted some tests, may relay * 1 - host accepted no tests, won't relay * 2 - host appears to be blocking tester (or may just be seriously broken) * 100 - format or internal error */ int main(int argc, char **argv) { struct in_addr *in; struct sockaddr_in socks_addr; char *cookie; int ret = 1; char intip[16]; char *tempchr; const char *sender_user, *sender_domain, *target_user, *target_domain; setalarm(); if (argc < 3) { fprintf(stderr,"Usage: %s \n",argv[0]); exit(100); } in = firedns_aton4(argv[1]); if (in == NULL) { fprintf(stderr,"Invalid IP\n"); exit(100); } memcpy(&socks_addr.sin_addr,in,sizeof(struct in_addr)); socks_addr.sin_family = AF_INET; socks_addr.sin_port = htons(atoi(argv[2])); firestring_strncpy(intip,firedns_ntoa4(in),16); readconf(); sender_user = firestring_conf_find(config,"sender_user"); if (sender_user == NULL) { fprintf(stderr,"sender_user not set in config.\n"); exit(100); } sender_domain = firestring_conf_find(config,"sender_domain"); if (sender_domain == NULL) { fprintf(stderr,"sender_domain not set in config.\n"); exit(100); } target_user = firestring_conf_find(config,"target_user"); if (target_user == NULL) { fprintf(stderr,"target_user not set in config.\n"); exit(100); } target_domain = firestring_conf_find(config,"target_domain"); if (target_domain == NULL) { fprintf(stderr,"target_domain not set in config.\n"); exit(100); } cookie = getcookie(); tempchr = firedns_resolvemx(target_domain); if (tempchr == NULL) { fprintf(stderr,"Target domain has no mail exchanger\n"); exit(100); } in = firedns_resolveip4(tempchr); if (in == NULL) { fprintf(stderr,"Target domain MX has no corresponding A record\n"); exit(100); } buildheaders(cookie,sender_domain,target_user,target_domain); if (testsocks4(cookie,intip,&socks_addr,"",sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testsocks4(cookie,intip,&socks_addr,sender_user,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testsocks4(cookie,intip,&socks_addr,"nobody",sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; in = firedns_aton4("127.0.0.1"); if (testsocks4(cookie,intip,&socks_addr,"",sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testsocks4(cookie,intip,&socks_addr,sender_user,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testsocks4(cookie,intip,&socks_addr,"nobody",sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; exit(ret); } dsbl-testers/socks5test.c0000644000175000017500000002014007501367126013522 0ustar alal/* relaytest.c - DSBL SMTP open relay tester Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "testlib.h" struct s_socks5_auth { #define SOCKS5_VERSION 0x05 unsigned char version; unsigned char nmethods; #define SOCKS5_METHOD_NONE 0x00 unsigned char methods[64]; }; struct s_socks5_auth_response { unsigned char version; unsigned char method; }; #define SOCKS5_LENGTH 10 struct s_socks5_request { #define SOCKS5_VERSION 0x05 unsigned char version; #define SOCKS5_COMMAND_CONNECT 0x01 unsigned char command; unsigned char reserved; #define SOCKS5_ADDRESSTYPE_IPV4 0x01 unsigned char addresstype; unsigned char ip[4]; unsigned short port; }; char headers[4096]; char *getline(int fd) { static char buffer[4096]; static char line[4096]; static int bufpos = 0; int i; char *tempchr; tempchr = memchr(buffer,'\n',bufpos); while (tempchr == NULL) { i = recv(fd,&buffer[bufpos],4095 - bufpos,0); if (i <= 0) /* eof of error, let the parent figure out what to do */ return NULL; bufpos += i; tempchr = memchr(buffer,'\n',bufpos); if (tempchr == NULL && bufpos == 4095) /* line too long (hostile act) */ exit(2); } if (tempchr != NULL) { memcpy(line,buffer,tempchr - buffer); line[tempchr - buffer] = '\0'; bufpos -= (tempchr - buffer) + 1; memcpy(buffer,&tempchr[1],bufpos); return line; } return NULL; } int getresponse(int fd) { char *line; while (1) { line = getline(fd); if (line == NULL) /* eof */ return 9; if (strlen(line) >= 4 && line[3] == '-') continue; else if (line[0] == '1') return 1; else if (line[0] == '2') return 2; else if (line[0] == '3') return 3; else if (line[0] == '4') return 4; else if (line[0] == '5') return 5; else return 8; /* bad code */ } } const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void buildheaders(char *cookie, const char *source, const char *target_user, const char *target_domain) { struct tm *timestruct; time_t temptime; time(&temptime); timestruct = gmtime(&temptime); firestring_snprintf(headers,4096,"Message-ID: <%s@%s>\r\n" "Date: %s, %d %s %d %02d:%02d:%02d +0000\r\n" "To: <%s@%s>\r\n" "Subject: Open SOCKS 5 Proxy Test Message\r\n",cookie,source,days[timestruct->tm_wday],timestruct->tm_mday,months[timestruct->tm_mon],1900 + timestruct->tm_year,timestruct->tm_hour,timestruct->tm_min,timestruct->tm_sec,target_user,target_domain); } int sendtest(int fd, const char *intip, int port, struct in_addr *remoteip, char *cookie, const char *sender, const char *source, const char *target_user, const char *target_domain) { char buffer[8192]; int i; i = firestring_snprintf(buffer,8192,"HELO [%s]\r\n",firedns_ntoa4(remoteip)); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 2; i = firestring_snprintf(buffer,8192,"MAIL FROM:<%s@%s>\r\n",sender,source); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer,8192,"RCPT TO:<%s@%s>\r\n",target_user,target_domain); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; firestring_strncpy(buffer,"DATA\r\n",8192); if (send(fd,buffer,6,0) != 6) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer,8192,"%s\r\n" "DSBL LISTME: socks5 %s\r\n" "%s\r\n" "Port %d, Connect to %s\r\n" "DSBL END\r\n" ".\r\n",headers,intip,cookie,port,firedns_ntoa4(remoteip)); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer,8192,"QUIT\r\n"); if (send(fd,buffer,i,0) != i) return 100; return 0; } int testsocks5(char *cookie, const char *intip, struct sockaddr_in *socksaddr, const char *sourceuser, const char *sourcedomain, struct in_addr *remoteip, const char *target_user, const char *target_domain) { struct s_socks5_auth a; struct s_socks5_auth_response ar; struct s_socks5_request r; int i; int f; a.version = SOCKS5_VERSION; a.nmethods = 1; a.methods[0] = SOCKS5_METHOD_NONE; r.version = SOCKS5_VERSION; r.command = SOCKS5_COMMAND_CONNECT; r.port = htons(25); memcpy(&r.ip,remoteip,sizeof(struct in_addr)); r.reserved = 0x00; r.addresstype = SOCKS5_ADDRESSTYPE_IPV4; f = socket(PF_INET, SOCK_STREAM, 0); if (f == -1) { perror("socket()"); exit(100); } if (connect(f,(struct sockaddr *)socksaddr,sizeof(struct sockaddr_in)) != 0) return 2; if (send(f,&a,3,0) != 3) { close(f); return 2; } if (recv(f,&ar,sizeof(ar),0) != sizeof(ar)) { close(f); return 2; } if (ar.method != SOCKS5_METHOD_NONE) { close(f); return 1; } if (send(f,&r,SOCKS5_LENGTH,0) != SOCKS5_LENGTH) { close(f); return 2; } if (recv(f,&r,SOCKS5_LENGTH,0) != SOCKS5_LENGTH) { close(f); return 2; } if (r.command != 0x00) { close(f); return 1; } i = getresponse(f); if (i != 2) { close(f); return 2; } i = sendtest(f, intip, ntohs(socksaddr->sin_port), remoteip, cookie, sourceuser, sourcedomain, target_user, target_domain); close(f); return i; } /* return values: * 0 - host accepted some tests, may relay * 1 - host accepted no tests, won't relay * 2 - host appears to be blocking tester (or may just be seriously broken) * 100 - format or internal error */ int main(int argc, char **argv) { struct in_addr *in; struct sockaddr_in socks_addr; char *cookie; char intip[16]; int ret = 1; char *tempchr; const char *sender_user, *sender_domain, *target_user, *target_domain; setalarm(); if (argc < 3) { fprintf(stderr,"Usage: %s \n",argv[0]); exit(100); } in = firedns_aton4(argv[1]); if (in == NULL) { fprintf(stderr,"Invalid IP\n"); exit(100); } memcpy(&socks_addr.sin_addr,in,sizeof(struct in_addr)); socks_addr.sin_family = AF_INET; socks_addr.sin_port = htons(atoi(argv[2])); firestring_strncpy(intip,firedns_ntoa4(in),16); readconf(); sender_user = firestring_conf_find(config,"sender_user"); if (sender_user == NULL) { fprintf(stderr,"sender_user not set in config.\n"); exit(100); } sender_domain = firestring_conf_find(config,"sender_domain"); if (sender_domain == NULL) { fprintf(stderr,"sender_domain not set in config.\n"); exit(100); } target_user = firestring_conf_find(config,"target_user"); if (target_user == NULL) { fprintf(stderr,"target_user not set in config.\n"); exit(100); } target_domain = firestring_conf_find(config,"target_domain"); if (target_domain == NULL) { fprintf(stderr,"target_domain not set in config.\n"); exit(100); } cookie = getcookie(); tempchr = firedns_resolvemx(target_domain); if (tempchr == NULL) { fprintf(stderr,"Target domain has no mail exchanger\n"); exit(100); } in = firedns_resolveip4(tempchr); if (in == NULL) { fprintf(stderr,"Target domain MX has no corresponding A record\n"); exit(100); } buildheaders(cookie,sender_domain,target_user,target_domain); if (testsocks5(cookie,intip,&socks_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; in = firedns_aton4("127.0.0.1"); if (testsocks5(cookie,intip,&socks_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; exit(ret); } dsbl-testers/relaytest.c0000644000175000017500000004470007776605641013452 0ustar alal/* relaytest.c - DSBL SMTP open relay tester Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "testlib.h" #define DOMAIN_DEPTH 3 #define DOMAIN_TESTSTART 16 #define MAXTEST 34 #define AUTH_LOGIN 0 #define AUTH_NTLM 1 int needgreeting = 1; char domains[5 + (DOMAIN_DEPTH * 2)][256]; int domaincount = 3; char headers[4096]; int connection_closed; int verbose = 0; int checkdomain(char *domain) { int i; for (i = 0; i < domaincount; i++) { if (firestring_strcasecmp(domains[i],domain) == 0) return 1; } return 0; } void adddomain(char *domain) { char * tempchr; int i; if (strlen(domain) > 255) return; tempchr = strchr(domain,'.'); if (tempchr == NULL) return; if (checkdomain(domain)) return; strcpy(domains[domaincount++],domain); tempchr = domain; for (i = 0; i < DOMAIN_DEPTH; i++) { tempchr = strchr(tempchr,'.'); if (tempchr == NULL) return; tempchr++; if (checkdomain(tempchr)) return; if (strchr(tempchr,'.') == NULL) return; strcpy(domains[domaincount++],tempchr); } } char *getline(int fd) { static char buffer[16384]; static char line[16384]; static int bufpos = 0; int i; char *tempchr; tempchr = memchr(buffer,'\n',bufpos); while (tempchr == NULL) { i = recv(fd,&buffer[bufpos],16383 - bufpos,0); if (i <= 0) /* eof of error, let the parent figure out what to do */ return NULL; bufpos += i; tempchr = memchr(buffer,'\n',bufpos); if (tempchr == NULL && bufpos == 16383) { /* line too long (hostile act) */ fprintf(stderr,"Input buffer overflow\n"); exit(2); } } if (tempchr != NULL) { memcpy(line,buffer,tempchr - buffer); line[tempchr - buffer] = '\0'; bufpos -= (tempchr - buffer) + 1; memcpy(buffer,&tempchr[1],bufpos); return line; } return NULL; } int getresponse(int fd) { char *line; while (1) { line = getline(fd); if (line == NULL) { /* eof */ connection_closed = 1; return 9; } if (verbose) printf("<<< %s\n", line); if (strlen(line) >= 4 && line[3] == '-') continue; else if (line[0] == '1') return 1; else if (line[0] == '2') { if (needgreeting == 1) { char *tempchr; needgreeting = 0; tempchr = strchr(&line[4],' '); if (tempchr != NULL) *tempchr = '\0'; adddomain(&line[4]); } return 2; } else if (line[0] == '3') return 3; else if (line[0] == '4') return 4; else if (line[0] == '5') return 5; else return 8; /* bad code */ } } const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void buildheaders(char *cookie, const char *source, const char *target_user, const char *target_domain) { struct tm *timestruct; time_t temptime; time(&temptime); timestruct = gmtime(&temptime); firestring_snprintf(headers,4096,"Message-ID: <%s@%s>\r\n" "Date: %s, %d %s %d %02d:%02d:%02d +0000\r\n" "To: <%s@%s>\r\n" "Subject: Open Relay Test Message\r\n",cookie,source,days[timestruct->tm_wday],timestruct->tm_mday,months[timestruct->tm_mon],1900 + timestruct->tm_year,timestruct->tm_hour,timestruct->tm_min,timestruct->tm_sec,target_user,target_domain); } /* NUM FROM TO 0 1 <"listme@dsbl.org"> 2 listme@dsbl.org 3 4 5 <"listme@dsbl.org"> 6 listme@dsbl.org 7 8 9 <"listme@dsbl.org"> 10 listme@dsbl.org 11 12 <> 13 <> <"listme@dsbl.org"> 14 <> listme@dsbl.org 15 <> 16 17 <"listme@dsbl.org"> 18 listme@dsbl.org 19 20 21 <"listme%dsbl.org"> 22 23 <"listme@dsbl.org"@DOMAIN> 24 <@DOMAIN:listme@dsbl.org> 25 26 27 28 29 30 31 32 33 34 */ char *mailfrom(int num, const char *sender, const char *source, const char *domain) { static char buffer[512]; switch (num) { case 0: case 1: case 2: case 3: firestring_snprintf(buffer,512,"<%s@%s>",sender,source); break; case 4: case 5: case 6: case 7: firestring_strncpy(buffer,"",512); break; case 8: case 9: case 10: case 11: firestring_snprintf(buffer,512,"<%s!%s>",source,sender); break; case 12: case 13: case 14: case 15: firestring_strncpy(buffer,"<>",512); break; case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: firestring_snprintf(buffer,512,"",domain); break; case 27: case 28: firestring_snprintf(buffer,512,"<%s!nobody>",domain); break; case 29: firestring_snprintf(buffer,512,"",domain); break; case 30: firestring_snprintf(buffer,512,"",domain); break; case 31: firestring_snprintf(buffer,512,"",domain); break; case 32: firestring_snprintf(buffer,512,"",domain); break; case 33: firestring_snprintf(buffer,512,"",domain); break; case 34: firestring_snprintf(buffer,512,"",domain); break; default: buffer[0] = '\0'; break; } return buffer; } char *rcptto(int num, const char *sender, const char *source, const char *domain, const char *target_user, const char *target_domain) { static char buffer[512]; switch (num) { case 0: case 4: case 8: case 12: case 16: case 29: case 30: case 31: case 32: case 33: case 34: firestring_snprintf(buffer,512,"<%s@%s>",target_user,target_domain); break; case 1: case 5: case 9: case 13: case 17: firestring_snprintf(buffer,512,"<\"%s@%s\">",target_user,target_domain); break; case 2: case 6: case 10: case 14: case 18: firestring_snprintf(buffer,512,"%s@%s",target_user,target_domain); break; case 3: case 7: case 11: case 15: case 25: case 27: firestring_snprintf(buffer,512,"<%s!%s>",target_domain,target_user); break; case 19: firestring_snprintf(buffer,512,"<%s%%%s>",target_user,target_domain); break; case 20: firestring_snprintf(buffer,512,"<%s%%%s@%s>",target_user,target_domain,domain); break; case 21: firestring_snprintf(buffer,512,"<\"%s%%%s\">",target_user,target_domain); break; case 22: firestring_snprintf(buffer,512,"<%s@%s@%s>",target_user,target_domain,domain); break; case 23: firestring_snprintf(buffer,512,"<\"%s@%s\"@%s>",target_user,target_domain,domain); break; case 24: firestring_snprintf(buffer,512,"<@%s:%s@%s>",domain,target_user,target_domain); break; case 26: case 28: firestring_snprintf(buffer,512,"<%s!%s@%s>",target_domain,target_user,domain); break; default: buffer[0] = '\0'; break; } return buffer; } int sendtest(int fd, char *intip, const char *cookie, int num, const char *sender, const char *source, const char *domain, const char *target_user, const char *target_domain, const char *message, const char *extra_info, int smtp_port) { char buffer[8192]; char port_info[32]; char *mf, *rt; int i; if (smtp_port == 25) port_info[0] = '\0'; else firestring_snprintf(port_info,32,"SMTP Port: %d\r\n",smtp_port); mf = mailfrom(num,sender,source,domain); if (verbose) printf(">>> MAIL FROM:%s\n",mf); i = firestring_snprintf(buffer,8192,"MAIL FROM:%s\r\n",mf); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; rt = rcptto(num,sender,source,domain,target_user,target_domain); if (verbose) printf(">>> RCPT TO:%s\n",rt); i = firestring_snprintf(buffer,8192,"RCPT TO:%s\r\n",rt); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; firestring_strncpy(buffer,"DATA\r\n",8192); if (verbose) printf(">>> DATA\n"); if (send(fd,buffer,6,0) != 6) return 100; i = getresponse(fd); if (i != 3) return 1; if (verbose) printf(">>> (message)\n"); i = firestring_snprintf(buffer,8192,"%s\r\n" "DSBL LISTME: smtp %s\r\n" "%s\r\n" "%s" "%s" "MAIL FROM:%s\r\n" "RCPT TO:%s\r\n" "DSBL END\r\n" "\r\n" "%s\r\n" ".\r\n",headers,intip,cookie,port_info,extra_info,mf,rt,message); if (send(fd,buffer,i,0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return 0; } int reset(int fd) { if (verbose) printf(">>> RSET\n"); if (send(fd,"RSET\r\n",6,0) != 6) return 100; getresponse(fd); return 0; } /* copy message contents while replacing bare linefeeds */ void copymessage(char *outbuf, const char *inbuf) { int l,o,i; l = strlen(inbuf); o = 0; for (i = 0; i < l; i++) { if (o > 8189) break; if (inbuf[i] == '\n') { outbuf[o++] = '\r'; outbuf[o++] = '\n'; } else outbuf[o++] = inbuf[i]; } outbuf[o] = '\0'; } /* try to authenticate using SMTP AUTH, LOGIN method */ int auth_login(int fd, const char *username, const char *password) { int i; char buffer[1024]; i = firestring_snprintf(buffer, 1024, "AUTH LOGIN\r\n"); if (verbose) printf(">>> AUTH LOGIN\n"); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer, 1024, "%s\r\n", username); if (verbose) printf(">>> %s\n", username); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer, 1024, "%s\r\n", password); if (verbose) printf(">>> %s\n", password); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return i; } /* try to authenticate using SMTP AUTH, NTLM method */ int auth_ntlm(int fd, const char *username, const char *password) { int i; char buffer[1024]; i = firestring_snprintf(buffer, 1024, "AUTH NTLM %s\r\n", username); if (verbose) printf(">>> AUTH NTLM %s\n", username); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer, 1024, "%s\r\n", password); if (verbose) printf(">>> %s\n", password); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return i; } int auth_relaytest(struct sockaddr_in *host_addr, char *intip, int method, const char *auth_details, const char *username, const char *password, const char *cookie, int num, const char *sender_user, const char *sender_domain, const char *target_user, const char *target_domain, const char *msgbuf, int smtp_port) { int i, fd; char buffer[1024]; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) return 100; if (connect(fd, (struct sockaddr *)host_addr, sizeof(struct sockaddr_in)) != 0) return 100; i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer, 1024, "EHLO %s\r\n", sender_domain); if (verbose) printf(">>> EHLO %s\n", sender_domain); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; switch (method) { case AUTH_LOGIN: i = auth_login(fd, username, password); break; case AUTH_NTLM: i = auth_ntlm(fd, username, password); break; default: fprintf(stderr,"Bad SMTP AUTH method: %d\n",method); exit(100); } if (i == 2) i = sendtest(fd, intip, cookie, num, sender_user, sender_domain, "", target_user, target_domain, msgbuf, auth_details, smtp_port); if (verbose) printf(">>> QUIT\n"); send(fd, "QUIT\r\n", 6, 0); (void)getresponse(fd); close(fd); return i; } /* return values: * 0 - host accepted some tests, may relay * 1 - host accepted no tests, won't relay * 2 - host appears to be blocking tester (or may just be seriously broken) * 3 - test timed out (alarm timer) * 100 - format or internal error */ int main(int argc, char **argv) { int fd; struct in_addr *in; struct sockaddr_in host_addr; char *cookie; char query[1024]; int i; int ret = 1; char *tempchr; int test,domain; const char *sender_user, *sender_domain, *target_user, *target_domain; const char *message; char msgbuf[8192]; char intip[16]; int smtp_port = 25; setalarm(); /* check for -v (verbose) option */ if (argc == 3 && !strcmp(argv[1], "-v")) { verbose = 1; argv[1] = argv[2]; argc--; } if (argc != 2) { fprintf(stderr,"Usage: %s [-v] [:port]\n", argv[0]); exit(100); } /* See if a port has been specified, and if so, extract it */ tempchr = strchr(argv[1],':'); if (tempchr != NULL) { smtp_port = atoi(&tempchr[1]); tempchr[0] = '\0'; } in = firedns_aton4(argv[1]); if (in == NULL) { fprintf(stderr,"Invalid IP\n"); exit(100); } memcpy(&host_addr.sin_addr,in,sizeof(struct in_addr)); firestring_strncpy(intip,firedns_ntoa4(in),16); readconf(); sender_user = firestring_conf_find(config,"sender_user"); if (sender_user == NULL) { fprintf(stderr,"sender_user not set in config.\n"); exit(100); } sender_domain = firestring_conf_find(config,"sender_domain"); if (sender_domain == NULL) { fprintf(stderr,"sender_domain not set in config.\n"); exit(100); } target_user = firestring_conf_find(config,"target_user"); if (target_user == NULL) { fprintf(stderr,"target_user not set in config.\n"); exit(100); } target_domain = firestring_conf_find(config,"target_domain"); if (target_domain == NULL) { fprintf(stderr,"target_domain not set in config.\n"); exit(100); } message = firestring_conf_find(config,"message"); if (message == NULL) { fprintf(stderr,"message not set in config.\n"); exit(100); } copymessage(msgbuf,message); cookie = getcookie(); /* initial domains */ firestring_strncpy(domains[0],"localhost",256); firestring_strncpy(domains[1],"[127.0.0.1]",256); firestring_snprintf(domains[2],256,"[%s]",firedns_ntoa4(&host_addr.sin_addr)); /* pull up to 3 domains from reverse */ tempchr = firedns_resolvename4(&host_addr.sin_addr); if (tempchr != NULL) adddomain(tempchr); host_addr.sin_family = AF_INET; host_addr.sin_port = htons(smtp_port); test = 0; domain = 0; buildheaders(cookie,sender_domain,target_user,target_domain); restart: connection_closed = 0; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("host socket()"); exit(100); } if (connect(fd,(struct sockaddr *)&host_addr,sizeof(struct sockaddr_in)) != 0) { perror("host connect()"); exit(2); } i = getresponse(fd); if (i != 2) { fprintf(stderr,"Error on greeting: %d\n",i); exit(2); } i = firestring_snprintf(query,1024,"HELO %s\r\n",sender_domain); if (verbose) printf(">>> HELO %s\n",sender_domain); if (send(fd,query,i,0) != i) { perror("Error sending HELO"); exit(2); } i = getresponse(fd); if (i != 2) { fprintf(stderr,"Error in HELO response: %d\n",i); exit(2); } for (; test < DOMAIN_TESTSTART; test++) { i = sendtest(fd,intip,cookie,test,sender_user,sender_domain,"",target_user,target_domain,msgbuf,"",smtp_port); if (i == 0) ret = 0; if (i == 1) reset(fd); if (i == 100 || connection_closed == 1) { if (verbose) printf("(connection error - reconnecting)\n"); close(fd); test++; goto restart; } } for (; domain < domaincount; domain++) { /* Restart the alarm clock when we get here, to allow for slow connections */ if (test == DOMAIN_TESTSTART) { if (verbose) printf("*** Resetting alarm timer\n"); setalarm(); } for (; test <= MAXTEST; test++) { i = sendtest(fd,intip,cookie,test,sender_user,sender_domain,domains[domain],target_user,target_domain,msgbuf,"",smtp_port); if (verbose) printf("*** Resetting alarm timer\n"); setalarm(); if (i == 0) ret = 0; if (i == 1) reset(fd); if (i == 100 || connection_closed == 1) { close(fd); test++; goto restart; } } test = DOMAIN_TESTSTART; } send(fd,"QUIT\r\n",6,0); if (verbose) printf(">>> QUIT\n"); close(fd); /* Now try simple SMTP AUTH exploits */ if (verbose) printf("*** Resetting alarm timer\n"); setalarm(); i = auth_relaytest(&host_addr, intip, AUTH_LOGIN, "AUTH LOGIN, user=/webmaster\r\n", "L3dlYm1hc3Rlcg==", "", cookie, 0, sender_user, sender_domain, target_user, target_domain, msgbuf, smtp_port); if (i == 0) ret = 0; i = auth_relaytest(&host_addr, intip, AUTH_LOGIN, "AUTH LOGIN, user=admin\r\n", "YWRtaW4=", "YWRtaW4=", cookie, 0, sender_user, sender_domain, target_user, target_domain, msgbuf, smtp_port); if (i == 0) ret = 0; i = auth_relaytest(&host_addr, intip, AUTH_LOGIN, "AUTH LOGIN, user=administrator\r\n", "YWRtaW5pc3RyYXRvcg==", "", cookie, 0, sender_user, sender_domain, target_user, target_domain, msgbuf, smtp_port); if (i == 0) ret = 0; i = auth_relaytest(&host_addr, intip, AUTH_LOGIN, "AUTH LOGIN, user=test\r\n", "dGVzdA==", "dGVzdA==", cookie, 0, sender_user, sender_domain, target_user, target_domain, msgbuf, smtp_port); if (i == 0) ret = 0; i = auth_relaytest(&host_addr, intip, AUTH_NTLM, "AUTH NTLM, anonymous\r\n", "TlRMTVNTUAABAAAAB4IAgAAAAAAAAAAAAAAAAAAAAAA=", "TlRMTVNTUAADAAAAAQABAEAAAAAAAAAAQQAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABBAAAABYIAAAA=", cookie, 0, sender_user, sender_domain, target_user, target_domain, msgbuf, smtp_port); if (i == 0) ret = 0; exit(ret); } dsbl-testers/spamtrap.c0000644000175000017500000001643207777012731013257 0ustar alal/* spamtrap.c - DSBL spamtrap master tester Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include "testlib.h" int parallel; int children = 0; int verbosity = 0; void preload_cookie() { char env[64]; char *s; s = getcookie(); if (s == NULL) return; firestring_snprintf(env,64,"DSBL_COOKIE=%s",s); putenv(env); } void block_children() { pid_t p; int status; if (parallel == 0) return; while (children >= parallel) { p = wait(&status); if (verbosity >= 10) { printf("reclaimed child %d\n",p); if (WIFEXITED(status)) printf("exit status %d\n",WEXITSTATUS(status)); else if (WIFSIGNALED(status)) printf("caught signal %d\n",WTERMSIG(status)); } if (p < 0) exit(100); children--; } } int excluded(const char * const ip) { const char *excluded_ip = NULL; while ((excluded_ip = firestring_conf_find_next(config,"excluded_ip",excluded_ip)) != NULL) { if (strncmp(ip,excluded_ip,strlen(excluded_ip)) == 0) return 1; } return 0; } void do_http(const char * const ip) { const char *http_port = NULL; int i; if (verbosity >= 10) printf("%s: begin HTTP test\n",ip); while ((http_port = firestring_conf_find_next(config,"http_port",http_port)) != NULL) { block_children(); i = fork(); if (i == 0) { execl(BINDIR "/httptest",BINDIR "/httptest",ip,http_port,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test HTTP on port %s\n",ip,i,http_port); children++; } } void do_socks(const char * const ip) { const char *socks_port = NULL; int i; if (verbosity >= 10) printf("%s: begin SOCKS test\n",ip); while ((socks_port = firestring_conf_find_next(config,"socks_port",socks_port)) != NULL) { block_children(); i = fork(); if (i == 0) { execl(BINDIR "/socks4test",BINDIR "/socks4test",ip,socks_port,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test SOCKS4 on port %s\n",ip,i,socks_port); children++; block_children(); i = fork(); if (i == 0) { execl(BINDIR "/socks5test",BINDIR "/socks5test",ip,socks_port,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test SOCKS5 on port %s\n",ip,i,socks_port); children++; } } void do_formmail(const char * const ip) { char *tempchr; int i; if (verbosity >= 10) printf("%s: begin FormMail test\n",ip); tempchr = firestring_concat("http://",ip,"/cgi-bin/formmail.pl",NULL); block_children(); i = fork(); if (i == 0) { execl(BINDIR "/formmailtest",BINDIR "/formmailtest",tempchr,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test FormMail with URL %s\n",ip,i,tempchr); children++; free(tempchr); tempchr = firestring_concat("http://",ip,"/cgi-bin/formmail.cgi",NULL); block_children(); i = fork(); if (i == 0) { execl(BINDIR "/formmailtest",BINDIR "/formmailtest",tempchr,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test FormMail with URL %s\n",ip,i,tempchr); children++; free(tempchr); tempchr = firestring_concat("http://",ip,"/cgi-bin/FormMail.pl",NULL); block_children(); i = fork(); if (i == 0) { execl(BINDIR "/formmailtest",BINDIR "/formmailtest",tempchr,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test FormMail with URL %s\n",ip,i,tempchr); children++; free(tempchr); tempchr = firestring_concat("http://",ip,"/cgi-bin/FormMail.cgi",NULL); block_children(); i = fork(); if (i == 0) { execl(BINDIR "/formmailtest",BINDIR "/formmailtest",tempchr,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test FormMail with URL %s\n",ip,i,tempchr); children++; free(tempchr); } void do_smtp(const char * const ip) { int i; if (verbosity >= 10) printf("%s: begin FormMail test\n",ip); block_children(); i = fork(); if (i == 0) { execl(BINDIR "/relaytest",BINDIR "/relaytest",ip,NULL); exit(100); } if (verbosity >= 10) printf("%s: spawn child %d to test SMTP\n",ip,i); children++; } int main() { char buffer[4096]; int i,j; pid_t m; struct in_addr *in; char *ip; const char *statedir, *checklist, *p; struct stat s; int o1,o2,o3,o4; char *tempchr; char ipblock[4][16]; readconf(); statedir = firestring_conf_find(config,"statedir"); if (statedir == NULL) { fprintf(stderr,"statedir not set in config.\n"); exit(100); } p = firestring_conf_find(config,"parallel"); if (p == NULL) { fprintf(stderr,"parallel not set in config.\n"); exit(100); } parallel = atoi(p); if (parallel < 0) { fprintf(stderr,"invalid parallel setting in config.\n"); exit(100); } p = firestring_conf_find(config,"verbosity"); if (p == NULL) { fprintf(stderr,"verbosity not set in config.\n"); exit(100); } verbosity = atoi(p); preload_cookie(); while (fgets(buffer,4096,stdin) != NULL) { i = strlen(buffer) - 6; for (j = 0; j < i; j++) { in = firedns_aton4(&buffer[j]); if (in == NULL) continue; ip = firedns_ntoa4(in); j += strlen(ip); /* ok, we've got an ip * now we check if it's excluded */ if (excluded(ip) == 1) continue; if (sscanf(ip,"%d.%d.%d.%d",&o1,&o2,&o3,&o4) != 4) continue; firestring_snprintf(ipblock[0],16,"%d",o1); firestring_snprintf(ipblock[1],16,"%d",o2); firestring_snprintf(ipblock[2],16,"%d",o3); firestring_snprintf(ipblock[3],16,"%d",o4); tempchr = firestring_concat(statedir,"/",ipblock[0],"/",ipblock[1],"/",ipblock[2],"/",ipblock[3],NULL); if (stat(tempchr,&s) == 0) { free(tempchr); continue; } m = fork(); if (m == 0) { execlp("mkdir","mkdir","-p",tempchr,NULL); perror("execlp(mkdir)"); exit(0); } waitpid(m,NULL,0); free(tempchr); checklist = firestring_conf_find(config,"checklist"); while (checklist != NULL) { tempchr = firestring_concat(ipblock[3],".",ipblock[2],".",ipblock[1],".",ipblock[0],".",checklist,NULL); in = firedns_resolveip4(tempchr); if (in != NULL) { /* ip already listed */ free(tempchr); tempchr = firestring_concat(statedir,"/",ipblock[0],"/",ipblock[1],"/",ipblock[2],"/",ipblock[3],NULL); rmdir(tempchr); free(tempchr); goto nextip; } free(tempchr); checklist = firestring_conf_find_next(config,"checklist",checklist); } /* we now know we haven't tested this host recently, do tests */ if (verbosity >= 1) printf("%s: begin test\n",ip); do_smtp(ip); do_socks(ip); do_http(ip); do_formmail(ip); nextip: if (verbosity >= 10) printf("%s: end test start\n",ip); } } while (wait(NULL) > 0); return 0; } dsbl-testers/firemake.version0000644000175000017500000000000607776577163014462 0ustar alal0.9.5 dsbl-testers/getcookie.c0000644000175000017500000000217007776575425013410 0ustar alal/* getcookie.c - get cookie from DSBL server for batch testing Copyright (C) 2002, 2003 Ian Gulliver & Paul Howarth This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "testlib.h" /* return values: * 0 - got cookie OK * 1 - problem getting cookie * 3 - timeout * 100 - format or internal error */ int main(int argc, char **argv) { setalarm(); if (argc != 1) { fprintf(stderr,"Usage: %s\n",argv[0]); exit(100); } readconf(); printf("%s\n", getcookiefromserver()); exit (0); } dsbl-testers/httptest.c0000644000175000017500000002341307777012731013304 0ustar alal/* httptest.c - DSBL open HTTP proxy tester Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "testlib.h" char headers[4096]; const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; char *getline(int fd) { static char buffer[4096]; static char line[4096]; static int bufpos = 0; int i; char *tempchr; tempchr = memchr(buffer,'\n',bufpos); while (tempchr == NULL) { i = recv(fd,&buffer[bufpos],4095 - bufpos,0); if (i <= 0) /* eof or error, let the parent figure out what to do */ return NULL; bufpos += i; tempchr = memchr(buffer,'\n',bufpos); if (tempchr == NULL && bufpos == 4095) /* line too long (hostile act) */ exit(2); } if (tempchr != NULL) { memcpy(line,buffer,tempchr - buffer); line[tempchr - buffer] = '\0'; bufpos -= (tempchr - buffer) + 1; memcpy(buffer,&tempchr[1],bufpos); return line; } return NULL; } void buildheaders(char *cookie, const char *source, const char *target_user, const char *target_domain) { struct tm *timestruct; time_t temptime; time(&temptime); timestruct = gmtime(&temptime); firestring_snprintf(headers,4096,"Message-ID: <%s@%s>\r\n" "Date: %s, %d %s %d %02d:%02d:%02d +0000\r\n" "To: <%s@%s>\r\n" "Subject: Open HTTP Proxy Test Message\r\n",cookie,source,days[timestruct->tm_wday],timestruct->tm_mday,months[timestruct->tm_mon],1900 + timestruct->tm_year,timestruct->tm_hour,timestruct->tm_min,timestruct->tm_sec,target_user,target_domain); } int sendget(int fd, char *intip, int port, struct in_addr *remoteip, char *cookie, const char *sender, const char *source, const char *target_user, const char *target_domain) { char buffer[8192]; char *tempchr = firedns_ntoa4(remoteip); int i; i = firestring_snprintf(buffer,8192,"GET http://%s:25/ HTTP/1.1\r\n" "Host: http://%s:25/\r\n" "Connection: close\r\n" "HELO [%s]\r\n" "MAIL FROM:<%s@%s>\r\n" "RCPT TO:<%s@%s>\r\n" "DATA\r\n" "%s\r\n" "DSBL LISTME: http %s\r\n" "%s\r\n" "Port %d\r\n" "Connect to %s\r\n" "Method GET\r\n" "DSBL END\r\n" ".\r\n" "QUIT\r\n" "\r\n",tempchr,tempchr,intip,sender,source,target_user,target_domain,headers,intip,cookie,port,tempchr); buffer[i] = '\0'; if (send(fd,buffer,i,0) != i) return 100; i = 0; while (recv(fd,buffer,8192,0) > 0 && i < 20) i++; return 0; } int sendconnect(int fd, char *intip, int port, struct in_addr *remoteip, char *cookie, const char *sender, const char *source, const char *target_user, const char *target_domain) { char buffer[8192]; char *tempchr = firedns_ntoa4(remoteip); char *line; int i; i = firestring_snprintf(buffer, 8192, "CONNECT %s:25 HTTP/1.0\r\n\r\n", tempchr); buffer[i] = '\0'; if (send(fd, buffer, i, 0) != i) return 100; /* eat lines until we get the SMTP banner from the target host, unless we reach 20 lines in which case don't bother */ i = 0; while ((line = getline(fd)) != NULL && line[0] != '2' && i < 20) { i++; } if (line == NULL || i == 20) return 100; i = firestring_snprintf(buffer, 8192, "HELO [%s]\r\n" "MAIL FROM:<%s@%s>\r\n" "RCPT TO:<%s@%s>\r\n" "DATA\r\n" "%s\r\n" "DSBL LISTME: http %s\r\n" "%s\r\n" "Port %d\r\n" "Connect to %s\r\n" "Method CONNECT\r\n" "DSBL END\r\n" ".\r\n" "QUIT\r\n" "\r\n", intip, sender, source, target_user, target_domain, headers, intip, cookie, port, tempchr); buffer[i] = '\0'; if (send(fd, buffer, i, 0) != i) return 100; i = 0; while (recv(fd, buffer, 8192, 0) > 0 && i < 20) i++; return 0; } int sendpost(int fd, char *intip, int port, char *method, struct in_addr *remoteip, char *cookie, const char *sender, const char *source, const char *target_user, const char *target_domain) { char http[8192]; char buffer[8192]; char *tempchr = firedns_ntoa4(remoteip); int i; i = firestring_snprintf(buffer,8192, "HELO [%s]\r\n" "MAIL FROM:<%s@%s>\r\n" "RCPT TO:<%s@%s>\r\n" "DATA\r\n" "%s\r\n" "DSBL LISTME: http %s\r\n" "%s\r\n" "Port %d\r\n" "Connect to %s\r\n" "Method %s\r\n" "DSBL END\r\n" ".\r\n" "QUIT\r\n",intip,sender,source,target_user,target_domain,headers,intip,cookie,port,tempchr,method); i = firestring_snprintf(http,8192,"%s http://%s:25/ HTTP/1.1\r\n" "Host: http://%s:25/\r\n" "Connection: close\r\n" "Content-length: %d\r\n" "\r\n" "%s",method,tempchr,tempchr,i,buffer); if (send(fd,http,i,0) != i) return 100; i = 0; while (recv(fd,buffer,8192,0) > 0 && i < 20) i++; return 0; } int testhttp(char *cookie, char *intip, char *method, struct sockaddr_in *httpaddr, const char *sourceuser, const char *sourcedomain, struct in_addr *remoteip, const char *target_user, const char *target_domain) { int i; int f; f = socket(PF_INET, SOCK_STREAM, 0); if (f == -1) { perror("socket()"); exit(100); } if (connect(f,(struct sockaddr *)httpaddr,sizeof(struct sockaddr_in)) != 0) return 2; if (strcmp(method,"POST") == 0 || strcmp(method,"PUT") == 0) i = sendpost(f, intip, ntohs(httpaddr->sin_port), method, remoteip, cookie, sourceuser, sourcedomain, target_user, target_domain); else if (strcmp(method,"CONNECT") == 0) i = sendconnect(f, intip, ntohs(httpaddr->sin_port), remoteip, cookie, sourceuser, sourcedomain, target_user, target_domain); else i = sendget(f, intip, ntohs(httpaddr->sin_port), remoteip, cookie, sourceuser, sourcedomain, target_user, target_domain); close(f); return i; } /* return values: * 0 - host accepted some tests, may relay * 1 - host accepted no tests, won't relay * 2 - host appears to be blocking tester (or may just be seriously broken) * 100 - format or internal error */ int main(int argc, char **argv) { struct in_addr *in; struct sockaddr_in http_addr; char *cookie; int ret = 1; char *tempchr; char intip[16]; const char *sender_user, *sender_domain, *target_user, *target_domain; setalarm(); if (argc < 3) { fprintf(stderr,"Usage: %s \n",argv[0]); exit(100); } in = firedns_aton4(argv[1]); if (in == NULL) { fprintf(stderr,"Invalid IP\n"); exit(100); } memcpy(&http_addr.sin_addr,in,sizeof(struct in_addr)); http_addr.sin_family = AF_INET; http_addr.sin_port = htons(atoi(argv[2])); firestring_strncpy(intip,firedns_ntoa4(in),16); readconf(); sender_user = firestring_conf_find(config,"sender_user"); if (sender_user == NULL) { fprintf(stderr,"sender_user not set in config.\n"); exit(100); } sender_domain = firestring_conf_find(config,"sender_domain"); if (sender_domain == NULL) { fprintf(stderr,"sender_domain not set in config.\n"); exit(100); } target_user = firestring_conf_find(config,"target_user"); if (target_user == NULL) { fprintf(stderr,"target_user not set in config.\n"); exit(100); } target_domain = firestring_conf_find(config,"target_domain"); if (target_domain == NULL) { fprintf(stderr,"target_domain not set in config.\n"); exit(100); } cookie = getcookie(); buildheaders(cookie,sender_domain,target_user,target_domain); tempchr = firedns_resolvemx(target_domain); if (tempchr == NULL) { fprintf(stderr,"Target domain has no mail exchanger\n"); exit(100); } in = firedns_resolveip4(tempchr); if (in == NULL) { fprintf(stderr,"Target domain MX has no corresponding A record\n"); exit(100); } if (testhttp(cookie,intip,"CONNECT",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testhttp(cookie,intip,"GET",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testhttp(cookie,intip,"POST",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testhttp(cookie,intip,"PUT",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; in = firedns_aton4("127.0.0.1"); if (testhttp(cookie,intip,"CONNECT",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testhttp(cookie,intip,"GET",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testhttp(cookie,intip,"POST",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; if (testhttp(cookie,intip,"PUT",&http_addr,sender_user,sender_domain,in,target_user,target_domain) == 0) ret = 0; exit(ret); } dsbl-testers/testlib.c0000644000175000017500000000635307776605641013106 0ustar alal/* testlib.c - DSBL tester shared library Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define TESTLIB_C #include #include #include #include #include #include #include #include #include #include #include #include "testlib.h" struct firestring_conf_t *config; #define COOKIE_PORT 200 void readconf() { char *homedir; homedir = getenv("HOME"); if (homedir != NULL) { config = firestring_conf_parse(firestring_concat(homedir,"/.dsblrc",NULL)); if (config != NULL) return; } config = firestring_conf_parse(CONFDIR "/dsbl.conf"); if (config == NULL) { fprintf(stderr,"Cannot open ~/.dsblrc or " CONFDIR "/dsbl.conf\n"); exit(100); } } char *getcookiefromserver() { int fd; struct in_addr *in; struct sockaddr_in cookie_addr; static char cookie[COOKIE_LENGTH + 1]; char *cookie_login; int i; const char *cookie_host, *cookie_user, *cookie_pass; cookie_host = firestring_conf_find(config,"cookie_host"); if (cookie_host == NULL) { fprintf(stderr,"cookie_host not set in config.\n"); exit(100); } cookie_user = firestring_conf_find(config,"cookie_user"); if (cookie_user == NULL) { fprintf(stderr,"cookie_user not set in config.\n"); exit(100); } cookie_pass = firestring_conf_find(config,"cookie_pass"); if (cookie_pass == NULL) { fprintf(stderr,"cookie_pass not set in config.\n"); exit(100); } in = firedns_resolveip4(cookie_host); if (in == NULL) { fprintf(stderr,"Unable to resolve cookie server.\n"); exit(100); } memcpy(&cookie_addr.sin_addr,in,sizeof(struct in_addr)); cookie_addr.sin_family = AF_INET; cookie_addr.sin_port = htons(COOKIE_PORT); fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) { perror("cookie server socket()"); exit(100); } if (connect(fd,(struct sockaddr *)&cookie_addr,sizeof(struct sockaddr_in)) != 0) { perror("cookie server connect()"); exit(100); } cookie_login = firestring_concat(cookie_user,"\n",cookie_pass,"\n",NULL); i = strlen(cookie_login); if (send(fd,cookie_login,i,0) != i) { perror("cookie server send()"); exit(100); } if (recv(fd,cookie,COOKIE_LENGTH,0) != COOKIE_LENGTH) { perror("cookie server recv()"); exit(100); } cookie[COOKIE_LENGTH] = '\0'; return cookie; } char *getcookie() { static char *cookie; if ((cookie = getenv("DSBL_COOKIE")) == NULL) return getcookiefromserver(); if (strlen(cookie) != COOKIE_LENGTH) { perror("DSBL_COOKIE invalid"); exit(100); } return cookie; } static void alarmhandler(int sig) { exit(3); } void setalarm() { signal(SIGALRM,alarmhandler); alarm(120); } dsbl-testers/testlib.h0000644000175000017500000000156407776605641013112 0ustar alal/* testlib.h - DSBL tester shared library declarations Copyright (C) 2002 Ian Gulliver This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef TESTLIB_C extern struct firestring_conf_t *config; #endif #define COOKIE_LENGTH 32 char *getcookiefromserver(); char *getcookie(); void setalarm(); void readconf(); dsbl-testers/tests.txt0000644000175000017500000000334207452667677013202 0ustar alalNUM FROM TO 0 1 <"listme@dsbl.org> 2 listme@dsbl.org 3 4 5 <"listme@dsbl.org"> 6 listme@dsbl.org 7 8 9 <"listme@dsbl.org"> 10 listme@dsbl.org 11 12 <> 13 <> <"listme@dsbl.org"> 14 <> listme@dsbl.org 15 <> 16 17 <"listme@dsbl.org"> 18 listme@dsbl.org 19 20 21 <"listme%dsbl.org"> 22 23 <"listme@dsbl.org"@DOMAIN> 24 <@DOMAIN:listme@dsbl.org> 25 26 27 28 29 30 0 recipient=listme@dsbl.org 1 recipient=dsbl.org!listme 2 realname=&email=\nCc: listme@dsbl.org&recipient=() 3 realname=)\nCc: listme@dsbl.org (&recipient=() 4 recipient=listme%dsbl.org@DOMAIN 5 recipient=dsbl.org!listme@DOMAIN 6 recipient=listme@dsbl.org(DOMAIN 7 recipient=DOMAIN 8 realname=&email=\nCc: listme@dsbl.org&recipient=DOMAIN 9 realname=)\nCc: listme@dsbl.org (&email=&recipient=DOMAIN 10 recipient=listme@dsbl.org(USER@DASHDOMAIN 11 recipient=USER@DASHDOMAIN dsbl-testers/CREDITS0000644000175000017500000000025307452667677012315 0ustar alalRik van Riel -- the idea Ian Gulliver -- the big schmuck Ron Guilmette (monkeys.com) -- inspriration from mrt & formmail tester PERL scripts Fred Smith -- fixing the idea dsbl-testers/hmac_md5.c0000644000175000017500000001424107776575425013116 0ustar alal/* Copyright (C) 2003 Robert Laughlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Contact Information: Robert Laughlin, Digital Systems, PO Box 158 Walkersville, MD 21791 robert@dscinet.com */ /*** Function: hmac_md5 ***/ #include #include #include "md5.h" #include "hmac_md5.h" /************************************************************************************ * Call hmac_md5_key() one time to specify the key for subsequent * * calls to hmac_md5_digest(). it can be called again to change keys. * ************************************************************************************/ void hmac_md5_key(HMAC_CTX *ctx, unsigned char* key, int key_len) /* unsigned char* key; pointer to authentication key */ /* int key_len; length of authentication key */ { MD5_CTX context; unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ unsigned char k_opad[65]; /* outer padding - key XORd with opad */ unsigned char tk[16]; /* storage for MD5'd key, if key_len > 64 */ int i; /* if key is longer than 64 bytes reset it to key=MD5(key) */ if (key_len > 64) { MD5Init(&context); MD5Update(&context, key, key_len); MD5Final(&context); memcpy(tk, context.digest, 16 ); key = tk; key_len = 16; } /* start out by storing key in pads, note calloc cleared k_ipad & k_opad */ memset( k_ipad, 0, sizeof(k_ipad)); memcpy( k_ipad, key, key_len); memset( k_opad, 0, sizeof(k_opad)); memcpy( k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i=0; i<64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* precompute inner MD5: MD5(key XOR ipad) */ MD5Init(&context); /* init context for 1st pass */ MD5Update(&context, k_ipad, 64); /* start with inner pad */ memcpy( &ctx->context_inner, &context, sizeof( ctx->context_inner ) - 16 ); /* save partial result */ /* precompute outer MD5: MD5(key XOR opad) */ MD5Init(&context); /* init context for 2nd pass */ MD5Update(&context, k_opad, 64); /* start with outer pad */ memcpy( &ctx->context_outer, &context, sizeof( ctx->context_outer ) - 16 ); } void hmac_md5_digest(HMAC_CTX *ctx, unsigned char* text, int text_len, unsigned char* digest) /* unsigned char* text; pointer to data stream */ /* int text_len; length of data stream */ /* unsigned char* digest; caller digest to be filled in */ { MD5_CTX context; /* perform inner MD5 */ memcpy( &context, &ctx->context_inner, sizeof( context ) - 16 ); /* get partial result */ MD5Update(&context, text, text_len); /* text of datagram */ MD5Final(&context); /* finish up 1st pass */ memcpy(digest, context.digest, 16); /* perform outer MD5 */ memcpy( &context, &ctx->context_outer, sizeof( context )- 16 ); /* get partial result */ MD5Update(&context, digest, 16); /* results of 1st hash */ MD5Final(&context); /* finish up 2nd pass */ memcpy(digest, context.digest, 16); } void hmac_md5(unsigned char* text, int text_len, unsigned char* key, int key_len, unsigned char* digest) /* unsigned char* text; pointer to data stream */ /* int text_len; length of data stream */ /* unsigned char* key; pointer to authentication key */ /* int key_len; length of authentication key */ /* unsigned char* digest; caller digest to be filled in */ { MD5_CTX context; unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */ unsigned char k_opad[65]; /* outer padding - key XORd with opad */ unsigned char tk[16]; int i; /* if key is longer than 64 bytes reset it to key=MD5(key) */ if (key_len > 64) { MD5_CTX tctx; MD5Init(&tctx); MD5Update(&tctx, key, key_len); MD5Final(&tctx); memcpy(&tk, tctx.digest, 16 ); key = (unsigned char*) tk; key_len = 16; } /* * the HMAC_MD5 transform looks like: * * MD5(K XOR opad, MD5(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * and text is the data being protected */ /* start out by storing key in pads */ memset( k_ipad, 0, sizeof k_ipad); memset( k_opad, 0, sizeof k_opad); memcpy( k_ipad, key, key_len); memcpy( k_opad, key, key_len); /* XOR key with ipad and opad values */ for (i=0; i<64; i++) { k_ipad[i] ^= 0x36; k_opad[i] ^= 0x5c; } /* * perform inner MD5 */ MD5Init(&context); /* init context for 1st pass */ MD5Update(&context, k_ipad, 64); /* start with inner pad */ MD5Update(&context, text, text_len); /* then text of datagram */ MD5Final(&context); /* finish up 1st pass */ memcpy(digest, context.digest, 16); /* * perform outer MD5 */ MD5Init(&context); /* init context for 2nd pass */ MD5Update(&context, k_opad, 64); /* start with outer pad */ MD5Update(&context, digest, 16); /* then results of 1st hash */ MD5Final(&context); /* finish up 2nd pass */ memcpy(digest, context.digest, 16); } dsbl-testers/auth-relaytest.c0000644000175000017500000003735107776575425014423 0ustar alal/* auth-relaytest.c - DSBL SMTP AUTH open relay tester Copyright (C) 2002 Ian Gulliver Copyright (C) 2003 Paul Howarth This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "testlib.h" #include "hmac_md5.h" #define AUTH_LOGIN 0 #define AUTH_NTLM 1 #define AUTH_CRAM_MD5 2 #define BASE64MAXLEN 256 #define NTLM_ANON_USER "TlRMTVNTUAABAAAAB4IAgAAAAAAAAAAAAAAAAAAAAAA=" #define NTLM_ANON_PASS "TlRMTVNTUAADAAAAAQABAEAAAAAAAAAAQQAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABBAAAABYIAAAA=" #define FULL_DISCLOSURE 0 static char headers[4096]; static char *challenge; static int verbose = 0; char *getline(int fd) { static char buffer[16384]; static char line[16384]; static int bufpos = 0; int i; char *tempchr; tempchr = memchr(buffer, '\n' ,bufpos); while (tempchr == NULL) { i = recv(fd, &buffer[bufpos], 16383 - bufpos, 0); if (i <= 0) /* eof of error, let the parent figure out what to do */ return NULL; bufpos += i; tempchr = memchr(buffer, '\n', bufpos); if (tempchr == NULL && bufpos == 16383) { /* line too long (hostile act) */ fprintf(stderr, "Input buffer overflow\n"); exit(2); } } if (tempchr != NULL) { memcpy(line, buffer, tempchr - buffer); line[tempchr - buffer] = '\0'; bufpos -= (tempchr - buffer) + 1; memcpy(buffer, &tempchr[1], bufpos); return line; } return NULL; } int getresponse(int fd) { char *line; while (1) { line = getline(fd); if (line == NULL) /* eof */ return 9; if (verbose) printf("<<< %s\n", line); if (strlen(line) >= 4 && line[3] == '-') continue; else if (line[0] == '1') return 1; else if (line[0] == '2') return 2; else if (line[0] == '3') { challenge = &line[4]; return 3; } else if (line[0] == '4') return 4; else if (line[0] == '5') return 5; else return 8; /* bad code */ } } const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void buildheaders(char *cookie, const char *source, const char *target_user, const char *target_domain) { struct tm *timestruct; time_t temptime; time(&temptime); timestruct = gmtime(&temptime); firestring_snprintf(headers, 4096, "Message-ID: <%s@%s>\r\n" "Date: %s, %d %s %d %02d:%02d:%02d +0000\r\n" "To: <%s@%s>\r\n" "Subject: Open Relay Test Message\r\n", cookie ,source, days[timestruct->tm_wday], timestruct->tm_mday, months[timestruct->tm_mon], 1900 + timestruct->tm_year, timestruct->tm_hour, timestruct->tm_min, timestruct->tm_sec, target_user, target_domain); } int sendtest(int fd, char *intip, const char *cookie, const char *sender, const char *source, const char *target_user, const char *target_domain, const char *message, const char *extra_info, int smtp_port) { char buffer[8192]; char port_info[32]; int i; if (smtp_port == 25) port_info[0] = '\0'; else firestring_snprintf(port_info, 32, "SMTP Port: %d\r\n", smtp_port); i = firestring_snprintf(buffer, 8192, "MAIL FROM:<%s@%s>\r\n", sender, source); if (verbose) printf(">>> MAIL FROM:<%s@%s>\r\n", sender, source); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer, 8192, "RCPT TO:<%s@%s>\r\n", target_user, target_domain); if (verbose) printf(">>> RCPT TO:<%s@%s>\r\n", target_user, target_domain); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; firestring_strncpy(buffer, "DATA\r\n", 8192); if (verbose) printf(">>> DATA\n"); if (send(fd, buffer, 6, 0) != 6) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer, 8192, "%s\r\n" "DSBL LISTME: smtp %s\r\n" "%s\r\n" "%s" "%s" "MAIL FROM:<%s@%s>\r\n" "RCPT TO:<%s@%s>\r\n" "DSBL END\r\n" "\r\n" "%s\r\n" ".\r\n", headers, intip, cookie, port_info, extra_info, sender, source, target_user, target_domain, message); if (verbose) printf(">>> (message)\n"); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return 0; } /* copy message contents while replacing bare linefeeds */ void copymessage(char *outbuf, const char *inbuf) { int l,o,i; l = strlen(inbuf); o = 0; for (i = 0; i < l; i++) { if (o > 8189) break; if (inbuf[i] == '\n') { outbuf[o++] = '\r'; outbuf[o++] = '\n'; } else outbuf[o++] = inbuf[i]; } outbuf[o] = '\0'; } /* try to authenticate using SMTP AUTH, LOGIN method */ int auth_login(int fd, const struct firestring_estr_t *username, const struct firestring_estr_t *password) { int i; char buffer[1024]; struct firestring_estr_t b64u, b64p; i = firestring_snprintf(buffer, 1024, "AUTH LOGIN\r\n"); if (verbose) printf(">>> AUTH LOGIN\n"); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 3) return 1; /* Create base64-encoded versions of username and password */ firestring_estr_alloc(&b64u, username->l * 4 / 3 + 5); firestring_estr_alloc(&b64p, password->l * 4 / 3 + 5); firestring_estr_base64_encode(&b64u, username); firestring_estr_base64_encode(&b64p, password); firestring_estr_0(&b64u); firestring_estr_0(&b64p); i = firestring_snprintf(buffer, 1024, "%s\r\n", b64u.s); if (verbose) printf(">>> %s\n", b64u.s); if (send(fd, buffer, i, 0) != i) { firestring_estr_free(&b64u); firestring_estr_free(&b64p); return 100; } i = getresponse(fd); if (i != 3) { firestring_estr_free(&b64u); firestring_estr_free(&b64p); return 1; } i = firestring_snprintf(buffer, 1024, "%s\r\n", b64p.s); if (verbose) printf(">>> %s\n", b64p.s); firestring_estr_free(&b64u); firestring_estr_free(&b64p); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return i; } /* try to authenticate using SMTP AUTH, NTLM method */ /* Only anonymous authentication currently supported; username & password must be pre-encoded */ int auth_ntlm(int fd, const struct firestring_estr_t *username, const struct firestring_estr_t *password) { int i; char buffer[1024]; i = firestring_snprintf(buffer, 1024, "AUTH NTLM %s\r\n", username->s); if (verbose) printf(">>> AUTH NTLM %s\n", username->s); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 3) return 1; i = firestring_snprintf(buffer, 1024, "%s\r\n", password->s); if (verbose) printf(">>> %s\n", password->s); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return i; } /* try to authenticate using SMTP AUTH, CRAM-MD5 method */ int auth_cram_md5(int fd, const struct firestring_estr_t *username, const struct firestring_estr_t *password) { int i; char buffer[1024]; unsigned char digest[16], digest_ascii[33]; char *hextab = "0123456789abcdef"; struct firestring_estr_t encoded_challenge, decoded_challenge; struct firestring_estr_t encoded_response, unencoded_response; i = firestring_snprintf(buffer, 1024, "AUTH CRAM-MD5\r\n"); if (verbose) printf(">>> AUTH CRAM-MD5\n"); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 3) return 1; /* Get the challenge and decode it */ if ((i = strlen(challenge)) >= BASE64MAXLEN) { fprintf(stderr, "auth-relaytest: challenge too long (max %d)\n", BASE64MAXLEN); return 100; } firestring_estr_alloc(&encoded_challenge, i + 1); firestring_estr_alloc(&decoded_challenge, i * 3 / 4 + 4); firestring_estr_strcpy(&encoded_challenge, challenge); firestring_estr_base64_decode(&decoded_challenge, &encoded_challenge); firestring_estr_0(&encoded_challenge); firestring_estr_0(&decoded_challenge); /* Compute the response */ hmac_md5(decoded_challenge.s, decoded_challenge.l, (char *)password->s, password->l, digest); for (i = 0; i < 16; i++) { digest_ascii[2*i] = hextab[digest[i] >> 4]; digest_ascii[2*i+1] = hextab[digest[i] & 0xf]; } digest_ascii[32] = '\0'; firestring_estr_alloc(&unencoded_response, 35 + username->l); firestring_estr_alloc(&encoded_response, 55 + (4 * username->l / 3)); firestring_estr_sprintf(&unencoded_response, "%s %s", username->s, digest_ascii); firestring_estr_base64_encode(&encoded_response, &unencoded_response); firestring_estr_0(&unencoded_response); firestring_estr_0(&encoded_response); /* Send the response */ i = firestring_snprintf(buffer, 1024, "%s\r\n", encoded_response.s); if (verbose) printf(">>> %s\n", encoded_response.s); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; return i; } int auth_relaytest( struct sockaddr_in *host_addr, char *intip, int method, const char *auth_details, struct firestring_estr_t *username, struct firestring_estr_t *password, const char *cookie, const char *sender_user, const char *sender_domain, const char *target_user, const char *target_domain, const char *msgbuf, int smtp_port) { int i, fd; char buffer[1024]; fd = socket(PF_INET, SOCK_STREAM, 0); if (fd == -1) return 100; if (verbose) printf("Connecting to %s...", intip); if (connect(fd, (struct sockaddr *)host_addr, sizeof(struct sockaddr_in)) != 0) { if (verbose) printf(" failed.\n"); return 100; } else { if (verbose) printf(" done.\n"); } i = getresponse(fd); if (i != 2) return 1; i = firestring_snprintf(buffer, 1024, "EHLO %s\r\n", sender_domain); if (verbose) printf(">>> EHLO %s\n", sender_domain); if (send(fd, buffer, i, 0) != i) return 100; i = getresponse(fd); if (i != 2) return 1; switch (method) { case AUTH_LOGIN: i = auth_login(fd, username, password); break; case AUTH_NTLM: i = auth_ntlm(fd, username, password); break; case AUTH_CRAM_MD5: i = auth_cram_md5(fd, username, password); break; default: fprintf(stderr, "Bad SMTP AUTH method: %d\n", method); exit(100); } if (i == 2) { i = sendtest(fd, intip, cookie, sender_user, sender_domain, target_user, target_domain, msgbuf, auth_details, smtp_port); if (i != 0) i = 4; /* AUTH accepted but message not accepted */ } if (verbose) printf(">>> QUIT\n"); send(fd, "QUIT\r\n", 6, 0); (void)getresponse(fd); close(fd); return i; } void usage(const char *prog) { fprintf(stderr, "auth-relaytest: usage: %s [-tv] ntlm [:port]\n" " %s [-tv] (login|cram-md5) [:port]\n", prog, prog); exit(100); } /* return values: * 0 - host accepted some tests, may relay * 1 - host accepted no tests, won't relay * 2 - host appears to be blocking tester (or may just be seriously broken) * 3 - test timed out (alarm) * 4 - host accepted authentication but still didn't relay * 100 - format or internal error */ int main(int argc, char **argv) { struct in_addr *in; struct sockaddr_in host_addr; char *cookie; char exploit[1024]; int i; int ret = 1; char *tempchr; const char *sender_user, *sender_domain, *target_user, *target_domain; const char *message; char msgbuf[8192]; char intip[16]; int smtp_port = 25; int auth_method = -1; char *method = NULL; int testmode = 0; struct firestring_estr_t user, pass; char *username = "", *password = "", *ip = ""; setalarm(); /* Check for options */ while (argc > 1 && *argv[1] == '-') { for (i = 1; argv[1][i] ;i++) { switch (argv[1][i]) { case 't': testmode = 1; break; case 'v': verbose = 1; break; default: usage(argv[0]); } } for (i = 2; i < argc ;i++) argv[i-1] = argv[i]; argc--; } /* Check for correct parameters */ if (argc == 5) { if (firestring_strcasecmp(argv[1], "login") == 0) { auth_method = AUTH_LOGIN; method = "LOGIN"; username = argv[2]; password = argv[3]; ip = argv[4]; } else if (firestring_strcasecmp(argv[1], "cram-md5") == 0) { auth_method = AUTH_CRAM_MD5; method = "CRAM-MD5"; username = argv[2]; password = argv[3]; ip = argv[4]; } else { usage(argv[0]); } } else if (argc == 3) { if (firestring_strcasecmp(argv[1], "ntlm") == 0) { auth_method = AUTH_NTLM; method = "NTLM"; username = NTLM_ANON_USER; password = NTLM_ANON_PASS; ip = argv[2]; } else { usage(argv[0]); } } else { usage(argv[0]); } /* Create estring versions of username and password */ firestring_estr_alloc(&user, strlen(username) + 1); firestring_estr_alloc(&pass, strlen(password) + 1); firestring_estr_strcpy(&user, username); firestring_estr_strcpy(&pass, password); firestring_estr_0(&user); firestring_estr_0(&pass); /* Check for sane lengths */ if (user.l > BASE64MAXLEN) { fprintf(stderr, "auth-relaytest: username too long (max %d)\n", BASE64MAXLEN); exit(100); } if (pass.l > BASE64MAXLEN) { fprintf(stderr, "auth-relaytest: password too long (max %d)\n", BASE64MAXLEN); exit(100); } /* See if a port has been specified, and if so, extract it */ tempchr = strchr(ip, ':'); if (tempchr != NULL) { smtp_port = atoi(&tempchr[1]); tempchr[0] = '\0'; } /* Get the IP address */ in = firedns_aton4(ip); if (in == NULL) { fprintf(stderr, "auth-relaytest: invalid IP\n"); exit(100); } memcpy(&host_addr.sin_addr, in, sizeof(struct in_addr)); firestring_strncpy(intip, firedns_ntoa4(in), 16); host_addr.sin_family = AF_INET; host_addr.sin_port = htons(smtp_port); readconf(); sender_user = firestring_conf_find(config, "sender_user"); if (sender_user == NULL) { fprintf(stderr, "sender_user not set in config.\n"); exit(100); } sender_domain = firestring_conf_find(config, "sender_domain"); if (sender_domain == NULL) { fprintf(stderr, "sender_domain not set in config.\n"); exit(100); } target_user = firestring_conf_find(config, "target_user"); if (target_user == NULL) { fprintf(stderr, "target_user not set in config.\n"); exit(100); } if (testmode == 1) { target_domain = firestring_conf_find(config, "test_target_domain"); if (target_domain == NULL) { fprintf(stderr, "test_target_domain not set in config.\n"); exit(100); } } else { target_domain = firestring_conf_find(config, "target_domain"); if (target_domain == NULL) { fprintf(stderr, "target_domain not set in config.\n"); exit(100); } } message = firestring_conf_find(config, "auth-message"); if (message == NULL) { message = firestring_conf_find(config, "message"); } if (message == NULL) { fprintf(stderr, "auth-relaytest: neither auth-message nor message set in config.\n"); exit(100); } copymessage(msgbuf, message); cookie = getcookie(); buildheaders(cookie, sender_domain, target_user, target_domain); #if FULL_DISCLOSURE firestring_snprintf(exploit, 1024, "AUTH %s, user=%s, password=%s\r\n", method, user.s, *(pass.s) ? pass.s : "(null)"); #else firestring_snprintf(exploit, 1024, "AUTH %s, user=%s\r\n", method, user.s); #endif if (auth_method == AUTH_NTLM) { firestring_strncpy(exploit, "AUTH NTLM, anonymous\r\n", 1024); } i = auth_relaytest(&host_addr, intip, auth_method, exploit, &user, &pass, cookie, sender_user, sender_domain, target_user, target_domain, msgbuf, smtp_port); if (i == 0 || i == 4) ret = i; exit(ret); } dsbl-testers/hmac_md5.h0000644000175000017500000000271207776575425013123 0ustar alal/********************* hmac_md5.h *********************************** * to create an authentication tag, first call * * hmac_md5_key() to specify the key. Note the key must be * * kept secret. Call hmac_md5_digest() to compute the tag. * * Note that the same key will be used over and over, unless * * changed by another call to hmac_md5_key(), it is not necessary * * to call this routine each time a new tag is needed. * ********************* hmac_md5.h ***********************************/ #ifndef _HMAC_MD5_H_ #define _HMAC_MD5_H_ #ifndef _MD5_H_ #include "md5.h" #endif typedef struct { MD5_CTX context_inner; /* precomputed starting point for inner MD5 */ MD5_CTX context_outer; /* precomputed starting point for outer MD5 */ } HMAC_CTX; void hmac_md5_key(HMAC_CTX *ctx, unsigned char* key, int key_len); /* specify/set key for hmac conversions */ void hmac_md5_digest(HMAC_CTX *ctx, unsigned char* text, int text_len, unsigned char* digest); /* compute hmac digest, digest is 16 bytes */ /******************************************************************* * hmac_md5() computes a tag from a key and text as a single call * *******************************************************************/ void hmac_md5(unsigned char* text, int text_len, unsigned char* key, int key_len, unsigned char* digest); /* original (all in one) */ #endif dsbl-testers/md5.c0000644000175000017500000002545007776575425012132 0ustar alal/* Copyright (C) 2003 Robert Laughlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Contact Information: Robert Laughlin, Digital Systems, PO Box 158 Walkersville, MD 21791 robert@dscinet.com */ /*********************************************************************** ** md5.c -- the source code for MD5 routines ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** ** 1992.2.13 Jouko Holopainen, 80x86 version ** ** 2002.11.8 Robert Laughlin, converted for eZ80 ** ***********************************************************************/ #include "md5.h" /*********************************************************************** ** Message-digest routines: ** ** To form the message digest for a message M ** ** (1) Initialize a context buffer mdContext using MD5Init ** ** (2) Call MD5Update on mdContext and M ** ** this can be done with multiple calls if desired ** ** each call providing part of M ** ** (3) Call MD5Final on mdContext ** ** The message digest is now in mdContext->digest[0...15] ** ***********************************************************************/ static unsigned char PADDING[64] = { 0x80, 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 }; /* F, G, H and I are basic MD5 functions */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s, ac) \ {(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) \ {(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) \ {(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) \ {(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* The routine MD5Init initializes the message-digest context mdContext. All fields are set to zero. */ void MD5Init (MD5_CTX *mdContext) { mdContext->i[0] = mdContext->i[1] = (UINT4)0; /* Load magic initialization constants. */ mdContext->buf[0] = (UINT4)0x67452301; mdContext->buf[1] = (UINT4)0xefcdab89; mdContext->buf[2] = (UINT4)0x98badcfe; mdContext->buf[3] = (UINT4)0x10325476; } /* The routine MD5Update updates the message-digest context to account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) { UINT4 in[16]; int mdi; unsigned int i, ii; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* update number of bits */ if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0]) mdContext->i[1]++; mdContext->i[0] += ((UINT4)inLen << 3); mdContext->i[1] += ((UINT4)inLen >> 29); /* Speedup for little-endian machines suggested in MD5 report --P Karn */ if(mdi == 0 && ((long)inBuf & 3) == 0){ while(inLen >= 64){ MD5Transform(mdContext->buf,(UINT4 *)inBuf); inLen -= 64; inBuf += 64; } } while (inLen--) { /* add new character to buffer, increment mdi */ mdContext->in[mdi++] = *inBuf++; /* transform if necessary */ if (mdi == 0x40) { for (i = 0, ii = 0; i < 16; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); MD5Transform (mdContext->buf, in); mdi = 0; } } } /* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ void MD5Final (MD5_CTX *mdContext) { UINT4 in[16]; int mdi; unsigned int i, ii; unsigned int padLen; /* save number of bits */ in[14] = mdContext->i[0]; in[15] = mdContext->i[1]; /* compute number of bytes mod 64 */ mdi = (int)((mdContext->i[0] >> 3) & 0x3F); /* pad out to 56 mod 64 */ padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); MD5Update (mdContext, PADDING, padLen); /* append length in bits and transform */ for (i = 0, ii = 0; i < 14; i++, ii += 4) in[i] = (((UINT4)mdContext->in[ii+3]) << 24) | (((UINT4)mdContext->in[ii+2]) << 16) | (((UINT4)mdContext->in[ii+1]) << 8) | ((UINT4)mdContext->in[ii]); MD5Transform (mdContext->buf, in); /* store buffer in digest */ for (i = 0, ii = 0; i < 4; i++, ii += 4) { mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); } } /* Basic MD5 step. Transforms buf based on in. */ void MD5Transform (UINT4 *buf, UINT4 *in) { UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; /* Round 1 */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */ FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */ FF ( c, d, a, b, in[ 2], S13, 606105819UL); /* 3 */ FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */ FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */ FF ( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */ FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */ FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */ FF ( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */ FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */ FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */ FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */ FF ( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */ FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */ FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */ FF ( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */ /* Round 2 */ #define S21 5 #define S22 9 #define S23 14 #define S24 20 GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */ GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */ GG ( c, d, a, b, in[11], S23, 643717713UL); /* 19 */ GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */ GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */ GG ( d, a, b, c, in[10], S22, 38016083UL); /* 22 */ GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */ GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */ GG ( a, b, c, d, in[ 9], S21, 568446438UL); /* 25 */ GG ( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */ GG ( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */ GG ( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */ GG ( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */ GG ( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */ GG ( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */ GG ( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */ /* Round 3 */ #define S31 4 #define S32 11 #define S33 16 #define S34 23 HH ( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */ HH ( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */ HH ( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */ HH ( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */ HH ( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */ HH ( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */ HH ( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */ HH ( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */ HH ( a, b, c, d, in[13], S31, 681279174UL); /* 41 */ HH ( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */ HH ( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */ HH ( b, c, d, a, in[ 6], S34, 76029189UL); /* 44 */ HH ( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */ HH ( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */ HH ( c, d, a, b, in[15], S33, 530742520UL); /* 47 */ HH ( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */ /* Round 4 */ #define S41 6 #define S42 10 #define S43 15 #define S44 21 II ( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */ II ( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */ II ( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */ II ( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */ II ( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */ II ( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */ II ( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */ II ( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */ II ( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */ II ( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */ II ( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */ II ( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */ II ( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */ II ( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */ II ( c, d, a, b, in[ 2], S43, 718787259UL); /* 63 */ II ( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */ buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } /*********************************************************************** ** End of md5.c ** ***********************************************************************/ dsbl-testers/md5.h0000644000175000017500000000630607776575425012136 0ustar alal/* *********************************************************************** ** md5.h -- header file for implementation of MD5 ** ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** ** Created: 2/17/90 RLR ** ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** ** Revised (for MD5): RLR 4/27/91 ** ** -- G modified to have y&~z instead of y&z ** ** -- FF, GG, HH modified to add in last register done ** ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** ** -- distinct additive constant for each step ** ** -- round 4 added, working mod 7 ** *********************************************************************** */ /* *********************************************************************** ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** ** ** ** License to copy and use this software is granted provided that ** ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** ** Digest Algorithm" in all material mentioning or referencing this ** ** software or this function. ** ** ** ** License is also granted to make and use derivative works ** ** provided that such works are identified as "derived from the RSA ** ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** ** material mentioning or referencing the derived work. ** ** ** ** RSA Data Security, Inc. makes no representations concerning ** ** either the merchantability of this software or the suitability ** ** of this software for any particular purpose. It is provided "as ** ** is" without express or implied warranty of any kind. ** ** ** ** These notices must be retained in any copies of any part of this ** ** documentation and/or software. ** *********************************************************************** */ #ifndef _MD5_H_ #define _MD5_H_ /* typedef a 32-bit type */ typedef unsigned long int UINT4; /* Data structure for MD5 (Message-Digest) computation */ typedef struct { UINT4 i[2]; /* number of _bits_ handled mod 2^64 */ UINT4 buf[4]; /* scratch buffer */ unsigned char in[64]; /* input buffer */ unsigned char digest[16]; /* actual digest after MD5Final call */ } MD5_CTX; void MD5Init (MD5_CTX *); void MD5Update (MD5_CTX *,unsigned char *,unsigned int); void MD5Final (MD5_CTX *); void MD5Transform(UINT4 *,UINT4 *); /*********************************************************************** ** End of md5.h ** ******************************** (cut) ********************************/ #endif dsbl-testers/firemake/0000755000175000017500000000000007777027050013041 5ustar alaldsbl-testers/firemake/binaries0000644000175000017500000000424107776577143014575 0ustar alal#!/bin/sh #require prefix #require strip #require makefiletop #phase config #phase makefile #after makefile_makefiletop case $PHASE in config) dispn "Reading firemake.binaries..." BINARIES=`cut -d ':' -f 1 firemake.binaries 2>/dev/null` disp "done" dispn "Reading firemake.sbinaries..." SBINARIES=`cut -d ':' -f 1 firemake.sbinaries 2>/dev/null` disp "done" FULLBINARIES="$BINARIES $SBINARIES" dispn "Reading firemake.noinstall..." NOINSTALL=`cat firemake.noinstall 2>/dev/null` disp "done" ;; makefile) disp "Writing binary creation entries..." for BINARY in $FULLBINARIES; do dispn " $BINARY..." DEPS="`grep \"^$BINARY:\" firemake.binaries 2>/dev/null | cut -d ':' -f 2` `grep \"^$BINARY:\" firemake.sbinaries 2>/dev/null | cut -d ':' -f 2`" $ECHO "$BINARY: $DEPS" $ECHO " $CC $FM_CFLAGS $FM_LDFLAGS -o $BINARY $DEPS $FM_STATICLIBS $FM_LIBS" $ECHO BINARYLIST="$BINARYLIST $BINARY" BINARY_CLEANLIST="$BINARY_CLEANLIST $BINARY $DEPS" disp "done" if module dependencies; then DEPPREPEND="$PREPEND" PREPEND="$PREPEND " customdeplist "$DEPS" PREPEND="$DEPPREPEND" fi done dispn "Writing binary index entry..." $ECHO "binaries: $BINARYLIST" $ECHO disp "done" disp "Writing binary install entries..." $ECHO "install_binaries: $BINARYLIST" for BINARY in $BINARIES; do $ECHO "$NOINSTALL" | grep "^$BINARY\$" >/dev/null 2>/dev/null if test "$?" = "0"; then disp " skipping $BINARY" else dispn " $BINARY..." $ECHO " $INSTALL $BINARY \$(BINDIR) $INSTALL_USER $INSTALL_GROUP 0755" if test "$STRIP" != ""; then $ECHO " $STRIP \$(BINDIR)/$BINARY" fi disp "done" fi done for BINARY in $SBINARIES; do $ECHO "$NOINSTALL" | grep "^$BINARY\$" >/dev/null 2>/dev/null if test "$?" = "0"; then disp " skipping $BINARY" else dispn " $BINARY..." $ECHO " $INSTALL $BINARY \$(SBINDIR) $INSTALL_USER $INSTALL_GROUP 0755" if test "$STRIP" != ""; then $ECHO " $STRIP \$(SBINDIR)/$BINARY" fi disp "done" fi done $ECHO dispn "Writing binary cleanup entry..." $ECHO "clean_binaries:" $ECHO " rm -f $BINARY_CLEANLIST" $ECHO disp "done" ;; esac dsbl-testers/firemake/c990000644000175000017500000000157007776577143013407 0ustar alal#!/bin/sh #require cc #require cflags #phase init #after init_cc #after init_cflags #phase header case $PHASE in init) C99="0" dispn "Checking for C99 compatible compiler..." if test "`basename $CC`" = "gcc"; then VER=`$CC --version | head -1 | cut -d ' ' -f 3` MVER=`$ECHO "$VER" | cut -d '.' -f 1` if test "$MVER" -ge "3"; then disp "gcc $VER (>= 3.0.0) found, C99 support activated" C99="1" else disp "gcc $VER (< 3.0.0) found, no C99 support" fi else disp "compiler not gcc, no C99 support" fi if test "$C99" = "1"; then disp "Adding \"-std=c99\" to CFLAGS" FM_CFLAGS="$FM_CFLAGS -std=c99" fi ;; header) if test "$C99" = "0"; then disp "Removing \"inline\" and \"restrict\" keyworks from source" $ECHO "#define inline" $ECHO "#define restrict" else disp "C99 is supported, no header changes needed" fi ;; esac dsbl-testers/firemake/cc0000644000175000017500000000041307776577143013363 0ustar alal#!/bin/sh #phase init dispn "Checking for a compiler..." if (gcc --version > /dev/null; test "$?" = "0"); then disp "found gcc" CC="gcc" elif (cc -v > /dev/null; test "$?" = "0"); then disp "found cc" CC="cc" else disp "not found, unable to continue" exit 1 fi dsbl-testers/firemake/cflags0000644000175000017500000000102007776577143014230 0ustar alal#!/bin/sh #require cc #phase init #after init_cc dispn "Attempting to determine correct CFLAGS..." if test ! "$CFLAGS" = ""; then disp "CFLAGS provided by environment: \"$CFLAGS\"" FM_CFLAGS="$CFLAGS" elif test "`basename $CC`" = "gcc"; then disp "compiler is gcc, using \"-O20 -fstrict-aliasing -funroll-loops -fexpensive-optimizations -fomit-frame-pointer\"" FM_CFLAGS="-O20 -fstrict-aliasing -funroll-loops -fexpensive-optimizations -fomit-frame-pointer" else disp "compiler is unknown, using \"-O\"" FM_CFLAGS="-O" fi dsbl-testers/firemake/compiletest0000644000175000017500000000504107776577143015330 0ustar alal#!/bin/sh #require cc #require cflags #phase library disp "Loading compile testing helper function" rm -f compiletest.log library_test() { $ECHO "$1" > compiletest.c $ECHO " == START PROGRAM == $1 == END PROGRAM ==" >>compiletest.log $ECHO "== EXECUTING: $CC $FM_CFLAGS $2 -c -o compiletest.o compiletest.c $3 == " >>compiletest.log $CC $FM_CFLAGS $2 -c -o compiletest.o compiletest.c $3 >>compiletest.log 2>>compiletest.log if test "$?" = "0"; then rm -f compiletest.o compiletest.c $ECHO "== COMPILE OK ==" >>compiletest.log true return else rm -f compiletest.o compiletest.c $ECHO "== COMPILE FAIL ==" >>compiletest.log false return fi } shared_test() { $ECHO "$1" > compiletest.c $ECHO " == START PROGRAM == $1 == END PROGRAM ==" >>compiletest.log $ECHO "== EXECUTING: $CC $FM_CFLAGS $FM_LDFLAGS $FM_SHAREDFLAGS $2 -o compiletest.so compiletest.c $3 == " >>compiletest.log $CC $FM_CFLAGS $FM_LDFLAGS $FM_SHAREDFLAGS $2 -o compiletest.so compiletest.c $3 >>compiletest.log 2>>compiletest.log if test "$?" = "0"; then rm -f compiletest.so compiletest.c $ECHO "== COMPILE OK ==" >>compiletest.log true return else rm -f compiletest.so compiletest.c $ECHO "== COMPILE FAIL ==" >>compiletest.log false return fi } compile_test() { $ECHO "$1" > compiletest.c $ECHO " == START PROGRAM == $1 == END PROGRAM ==" >>compiletest.log $ECHO "== EXECUTING: $CC $FM_CFLAGS $FM_LDFLAGS $2 -o compiletest compiletest.c $3 == " >>compiletest.log $CC $FM_CFLAGS $FM_LDFLAGS $2 -o compiletest compiletest.c $3 >>compiletest.log 2>>compiletest.log if test "$?" = "0"; then $ECHO "== COMPILE OK ==" >>compiletest.log $ECHO "== EXECUTING: ./compiletest ==" >>compiletest.log ./compiletest >>compiletest.log 2>>compiletest.log if test "$?" = "0"; then rm -f compiletest compiletest.c $ECHO "== RUN OK ==" >>compiletest.log true return else rm -f compiletest compiletest.c $ECHO "== RUN FAIL ==" >>compiletest.log false return fi else rm -f compiletest compiletest.c $ECHO "== COMPILE FAIL ==" >>compiletest.log false return fi } compile_test_wrapper() { # Args: # $1 - Program # $2 - CFLAGS # $3 - LDFLAGS # $4 - LIBS if (compile_test "$1" "$2 $3" "$4" > /dev/null); then disp "found" if test "$2" != ""; then disp "Adding \"$2\" to CFLAGS" FM_CFLAGS="$FM_CFLAGS $2" fi if test "$3" != ""; then disp "Adding \"$3\" to LDFLAGS" FM_LDFLAGS="$FM_LDFLAGS $3" fi if test "$4" != ""; then disp "Adding \"$4\" to LIBS" FM_LIBS="$FM_LIBS $4" fi return 0 else return 1 fi } dsbl-testers/firemake/conf0000644000175000017500000000104507776602374013720 0ustar alal#!/bin/sh #require makefiletop #require prefix #phase config #phase makefile #after makefile_makefiletop case $PHASE in config) dispn "Checking for configuration files..." CONF=`ls conf/ 2>/dev/null` disp "done" ;; makefile) disp "Writing configure file installation entries..." $ECHO "install_conf:" for C in $CONF; do if test -f "conf/$C"; then dispn " $C..." $ECHO " if test ! -f \$(CONFDIR)/$C; then $INSTALL conf/$C \$(CONFDIR) $INSTALL_USER $INSTALL_GROUP 0644; fi" disp "done" fi done $ECHO ;; esac dsbl-testers/firemake/dependencies0000644000175000017500000000345107776577143015431 0ustar alal#!/bin/sh #require cc #require cflags #phase library #phase init #after init_cflags case $PHASE in library) disp "Loading dependency helper function" rm -f dependencies.log customdeplist() { for DEP in $1; do JUNK=`$ECHO "$BUILTDEPS" | grep "$DEP"` if test "$?" != "0"; then # haven't built this one yet BUILTDEPS="$BUILTDEPS $DEP" CNAME=`echo "$DEP" | sed 's/\\.o\$/.c/'` customdeps "$CNAME" "$DEP" fi done } customdeps() { if test "$CC_DEPENDENCY" = "n"; then return fi dispn "Generating customized build rule for $1..." $ECHO "Generating dependencies with \"$CC $FM_CFLAGS -M $1\" (errors print below):" >> dependencies.log $CC $FM_CFLAGS -M $1 2>>dependencies.log if test "$?" != "0"; then disp "unable to generate dependencies; this file probably won't build. Aborting (check dependencies.log for details)" exit 1 fi $ECHO >> dependencies.log $ECHO " $CC $FM_CFLAGS -DCONFDIR=\"\\\"\$(CONFDIR)\\\"\" -DBINDIR=\"\\\"\$(BINDIR)\\\"\" -DSBINDIR=\"\\\"\$(SBINDIR)\\\"\" -DLIBDIR=\"\\\"\$(LIBDIR)\\\"\" -DMANDIR=\"\\\"\$(MANDIR)\\\"\" -c -o $2 $1" $ECHO disp "done" } ;; init) dispn "Checking for compiler dependency support..." $ECHO "#include int main() { return 0; }" > deptest.c $ECHO "Testing \"$CC $FM_CFLAGS -M deptest.c\":" >> dependencies.log DEPOUTPUT=`$CC $FM_CFLAGS -M deptest.c` RESULT="$?" $ECHO "Result is $RESULT" >> dependencies.log $ECHO "Output is: $DEPOUTPUT " >> dependencies.log if test "$RESULT" = "0"; then JUNK=`$ECHO "$DEPOUTPUT" | grep stdio` if test "$?" = "0"; then disp "found" CC_DEPENDENCY="y" else disp "found but broken, skipping" CC_DEPENDENCY="n" fi else disp "not found, skipping" CC_DEPENDENCY="n" fi rm -f deptest.c ;; esac dsbl-testers/firemake/firedns0000644000175000017500000000251407776577143014434 0ustar alal#!/bin/sh #require compiletest #require cflags #require firestring #require pthread #phase init #after init_cflags #after init_pthread #after init_firestring #phase header case $PHASE in init) dispn "Checking for firedns library..." PROGRAM="#include int main() { firedns_resolveip4(\"firestuff.org\"); return 0; }" compile_test_wrapper "$PROGRAM" "" "" "-lfiredns" || \ compile_test_wrapper "$PROGRAM" "-I/usr/local/include" "-L/usr/local/lib" "-lfiredns" || \ compile_test_wrapper "$PROGRAM" "-I/usr/local/include" "-L/usr/local/lib -R/usr/local/lib" "-lfiredns" || \ { if (module "subdir" && test -x firedns/configure); then subdir firedns disp "Adding -Ifiredns/ to CFLAGS" FM_CFLAGS="$FM_CFLAGS -Ifiredns/" disp "Adding firedns/libfiredns.a to STATICLIBS" FM_STATICLIBS="$FM_STATICLIBS firedns/libfiredns.a" elif (module "subdir" && test "$FM_IN_SUBDIR" = "y" && test -x ../firedns/configure); then parentdir ../firedns disp "Adding -I../firedns/ to CFLAGS" FM_CFLAGS="$FM_CFLAGS -I../firedns/" disp "Adding ../firedns/libfiredns.a to STATICLIBS" FM_STATICLIBS="$FM_STATICLIBS ../firedns/libfiredns.a" else disp "not found, unable to continue" exit 1 fi } ;; header) disp "Adding \"#include \" to header" $ECHO "#include " ;; esac dsbl-testers/firemake/firestring0000644000175000017500000000251307776577143015155 0ustar alal#!/bin/sh #require compiletest #require cflags #phase init #after init_cflags #phase header case $PHASE in init) dispn "Checking for firestring library..." PROGRAM="#include int main() { firestring_printf(\"test %e\",&ESTR_S(\"foo\")); return 0; }" compile_test_wrapper "$PROGRAM" "" "" "-lfirestring" || \ compile_test_wrapper "$PROGRAM" "-I/usr/local/include" "-L/usr/local/lib" "-lfirestring" || \ compile_test_wrapper "$PROGRAM" "-I/usr/local/include" "-L/usr/local/lib -R/usr/local/lib" "-lfirestring" || \ { if (module "subdir" && test -x firestring/configure); then subdir firestring disp "Adding -Ifirestring/ to CFLAGS" FM_CFLAGS="$FM_CFLAGS -Ifirestring/" disp "Adding firestring/libfirestring.a to STATICLIBS" FM_STATICLIBS="$FM_STATICLIBS firestring/libfirestring.a" elif (module "subdir" && test "$FM_IN_SUBDIR" = "y" && test -x ../firestring/configure); then parentdir ../firestring disp "Adding -I../firestring/ to CFLAGS" FM_CFLAGS="$FM_CFLAGS -I../firestring/" disp "Adding ../firestring/libfirestring.a to STATICLIBS" FM_STATICLIBS="$FM_STATICLIBS ../firestring/libfirestring.a" else disp "not found, unable to continue" exit 1 fi } ;; header) disp "Adding \"#include \" to header" $ECHO "#include " ;; esac dsbl-testers/firemake/id0000644000175000017500000000035707776577143013401 0ustar alal#!/bin/sh #phase init dispn "Checking for id..." if /usr/xpg4/bin/id 2>/dev/null; then disp "found, /usr/xpg4/bin/id" ID="/usr/xpg4/bin/id" elif id 2>/dev/null; then disp "found, id" ID="id" else disp "not found, aborting" exit 1 fi dsbl-testers/firemake/install0000644000175000017500000000241707776602374014445 0ustar alal#!/bin/sh #require id #require makefiletop #phase init #after init_id #phase makefile #after makefile_makefiletop case $PHASE in init) dispn "Creating installation script..." $ECHO "#!/bin/sh FILENAME="\$2/\`basename \$1\`" mkdir -p \$2 cp -f \$1 \$FILENAME chown \$3:\$4 \$FILENAME chmod \$5 \$FILENAME" > copy.sh chmod 0755 copy.sh INSTALL="./copy.sh" disp "done" dispn "Checking for installation username..." INSTALL_GROUP=`$ID -ng root` if test "$?" = "0"; then INSTALL_USER=root disp "found, \"root\"" else disp "none found, aborting" exit 1 fi dispn "Checking for installation group name..." if test "$INSTALL_GROUP" = ""; then disp "none found, aborting" exit 1 else disp "found, \"$INSTALL_GROUP\"" fi ;; makefile) dispn "Writing install entry..." $ECHO -n "install:" if module binaries; then $ECHO -n " install_binaries" fi if module libraries; then $ECHO -n " install_libraries" fi if module man; then $ECHO -n " install_man" fi if module headers; then $ECHO -n " install_headers" fi if module conf; then $ECHO -n " install_conf" fi $ECHO $ECHO disp "done" dispn "Writing install cleanup entry..." $ECHO "clean_install:" $ECHO " rm -f $INSTALL" $ECHO disp "done" ;; esac dsbl-testers/firemake/make0000644000175000017500000000041007776577143013710 0ustar alal#!/bin/sh #phase init dispn "Checking to see if make supports \"?=\"..." rm -f Makefile echo "PREFIX ?= /usr/local" > Makefile echo "all:" >> Makefile make >/dev/null 2>&1 if test "$?" = "0"; then disp "yes" MAKE_CONDSET="y" else disp "no" MAKE_CONDSET="n" fi dsbl-testers/firemake/makefiletop0000644000175000017500000000427507776577143015310 0ustar alal#!/bin/sh #require prefix #require make #phase makefile dispn "Writing Makefile top entries..." if test "$MAKE_CONDSET" = "y"; then $ECHO "PREFIX ?= $FM_PREFIX" if test "$FM_MANDIRSTRICT" = "y"; then $ECHO "MANDIR ?= $FM_MANDIR" else $ECHO "MANDIR ?= \$(PREFIX)/man" fi if test "$FM_CONFDIRSTRICT" = "y"; then $ECHO "CONFDIR ?= $FM_CONFDIR" else $ECHO "CONFDIR ?= \$(PREFIX)/etc" fi if test "$FM_BINDIRSTRICT" = "y"; then $ECHO "BINDIR ?= $FM_BINDIR" else $ECHO "BINDIR ?= \$(PREFIX)/bin" fi if test "$FM_SBINDIRSTRICT" = "y"; then $ECHO "SBINDIR ?= $FM_SBINDIR" else $ECHO "SBINDIR ?= \$(PREFIX)/sbin" fi if test "$FM_LIBDIRSTRICT" = "y"; then $ECHO "LIBDIR ?= $FM_LIBDIR" else $ECHO "LIBDIR ?= \$(PREFIX)/lib" fi if test "$FM_INCLUDEDIRSTRICT" = "y"; then $ECHO "INCLUDEDIR ?= $FM_INCLUDEDIR" else $ECHO "INCLUDEDIR ?= \$(PREFIX)/include" fi else $ECHO "PREFIX = $FM_PREFIX" $ECHO "MANDIR = $FM_MANDIR" $ECHO "CONFDIR = $FM_CONFDIR" $ECHO "BINDIR = $FM_BINDIR" $ECHO "SBINDIR = $FM_SBINDIR" $ECHO "LIBDIR = $FM_LIBDIR" $ECHO "INCLUDEDIR = $FM_INCLUDEDIR" fi $ECHO $ECHO "all:" if module subdir; then # make even inside parents; brute force dependency handling for SUBDIR in $FM_SUBDIRS; do $ECHO " cd $SUBDIR && \$(MAKE) all && cd .." done fi if module binaries; then $ECHO " \$(MAKE) binaries" fi if module libraries; then $ECHO " \$(MAKE) libraries" fi $ECHO $ECHO $ECHO ".c.o:" $ECHO " $CC $FM_CFLAGS -DCONFDIR=\"\\\"\$(CONFDIR)\\\"\" -DBINDIR=\"\\\"\$(BINDIR)\\\"\" -DSBINDIR=\"\\\"\$(SBINDIR)\\\"\" -DLIBDIR=\"\\\"\$(LIBDIR)\\\"\" -DMANDIR=\"\\\"\$(MANDIR)\\\"\" -c -o \$@ \$<" $ECHO $ECHO "clean:" if module subdir; then for SUBDIR in $FM_CLEAN_SUBDIRS; do $ECHO " cd $SUBDIR && \$(MAKE) clean && cd .." done fi if module binaries; then $ECHO " \$(MAKE) clean_binaries" fi if module libraries; then $ECHO " \$(MAKE) clean_libraries" fi $ECHO $ECHO "distclean:" $ECHO " \$(MAKE) clean" if module subdir; then for SUBDIR in $FM_CLEAN_SUBDIRS; do $ECHO " cd $SUBDIR && \$(MAKE) distclean && cd .." done fi if module install; then $ECHO " \$(MAKE) clean_install" fi $ECHO " rm -f Makefile compiletest.log dependencies.log firemake.h" $ECHO disp "done" dsbl-testers/firemake/man0000644000175000017500000000360207776577143013554 0ustar alal#!/bin/sh #require makefiletop #require prefix #phase config #phase makefile #after makefile_makefiletop case $PHASE in config) dispn "Checking for manpages for section 1..." MAN1=`ls man/*.1 2>/dev/null` disp "done" dispn "Checking for manpages for section 3..." MAN3=`ls man/*.3 2>/dev/null` disp "done" dispn "Checking for manpages for section 5..." MAN5=`ls man/*.5 2>/dev/null` disp "done" dispn "Checking for manpages for section 6..." MAN6=`ls man/*.6 2>/dev/null` disp "done" dispn "Checking for manpages for section 7..." MAN7=`ls man/*.7 2>/dev/null` disp "done" dispn "Checking for manpages for section 8..." MAN8=`ls man/*.8 2>/dev/null` disp "done" ;; makefile) disp "Writing manpage installation entries..." $ECHO "install_man:" if test "$MAN1" != ""; then dispn " Section 1..." for MAN in $MAN1; do $ECHO " $INSTALL $MAN \$(MANDIR)/man1 $INSTALL_USER $INSTALL_GROUP 0644" done disp "done" fi if test "$MAN3" != ""; then dispn " Section 3..." for MAN in $MAN3; do $ECHO " $INSTALL $MAN \$(MANDIR)/man3 $INSTALL_USER $INSTALL_GROUP 0644" done disp "done" fi if test "$MAN5" != ""; then dispn " Section 5..." for MAN in $MAN5; do $ECHO " $INSTALL $MAN \$(MANDIR)/man5 $INSTALL_USER $INSTALL_GROUP 0644" done disp "done" fi if test "$MAN6" != ""; then dispn " Section 6..." for MAN in $MAN6; do $ECHO " $INSTALL $MAN \$(MANDIR)/man6 $INSTALL_USER $INSTALL_GROUP 0644" done disp "done" fi if test "$MAN7" != ""; then dispn " Section 7..." for MAN in $MAN7; do $ECHO " $INSTALL $MAN \$(MANDIR)/man7 $INSTALL_USER $INSTALL_GROUP 0644" done disp "done" fi if test "$MAN8" != ""; then dispn " Section 8..." for MAN in $MAN8; do $ECHO " $INSTALL $MAN \$(MANDIR)/man8 $INSTALL_USER $INSTALL_GROUP 0644" done disp "done" fi $ECHO ;; esac dsbl-testers/firemake/prefix0000644000175000017500000000376307776577143014306 0ustar alal#!/bin/sh #require cflags #phase init #after init_cflags dispn "Attempting to determine correct PREFIX..." if test ! "$PREFIX" = ""; then disp "PREFIX provided by environment: \"$PREFIX\"" FM_PREFIX="$PREFIX" else disp "prefix is unknown, using \"/usr/local\"" FM_PREFIX="/usr/local" fi dispn "Attempting to determine correct BINDIR..." if test ! "$BINDIR" = ""; then disp "BINDIR provided by environment: \"$BINDIR\"" FM_BINDIRSTRICT="y" FM_BINDIR="$BINDIR" else disp "bindir is unknown, deriving from PREFIX: \"$FM_PREFIX/bin\"" FM_BINDIR="$FM_PREFIX/bin" fi dispn "Attempting to determine correct SBINDIR..." if test ! "$SBINDIR" = ""; then disp "SBINDIR provided by environment: \"$SBINDIR\"" FM_SBINDIRSTRICT="y" FM_SBINDIR="$SBINDIR" else disp "sbindir is unknown, deriving from PREFIX: \"$FM_PREFIX/sbin\"" FM_SBINDIR="$FM_PREFIX/sbin" fi dispn "Attempting to determine correct MANDIR..." if test ! "$MANDIR" = ""; then disp "MANDIR provided by environment: \"$MANDIR\"" FM_MANDIRSTRICT="y" FM_MANDIR="$MANDIR" else disp "mandir is unknown, deriving from PREFIX: \"$FM_PREFIX/man\"" FM_MANDIR="$FM_PREFIX/man" fi dispn "Attempting to determine correct CONFDIR..." if test ! "$CONFDIR" = ""; then disp "CONFDIR provided by environment: \"$CONFDIR\"" FM_CONFDIRSTRICT="y" FM_CONFDIR="$CONFDIR" else disp "confdir is unknown, deriving from PREFIX: \"$FM_PREFIX/etc\"" FM_CONFDIR="$FM_PREFIX/etc" fi dispn "Attempting to determine correct LIBDIR..." if test ! "$LIBDIR" = ""; then disp "LIBDIR provided by environment: \"$LIBDIR\"" FM_LIBDIRSTRICT="y" FM_LIBDIR="$LIBDIR" else disp "libdir is unknown, deriving from PREFIX: \"$FM_PREFIX/lib\"" FM_LIBDIR="$FM_PREFIX/lib" fi dispn "Attempting to determine correct INCLUDEDIR..." if test ! "$INCLUDEDIR" = ""; then disp "INCLUDEDIR provided by environment: \"$INCLUDEDIR\"" FM_INCLUDEDIRSTRICT="y" FM_INCLUDEDIR="$INCLUDEDIR" else disp "includedir is unknown, deriving from PREFIX: \"$FM_PREFIX/include\"" FM_INCLUDEDIR="$FM_PREFIX/include" fi dsbl-testers/firemake/pthread0000644000175000017500000000112607776577143014427 0ustar alal#!/bin/sh #require compiletest #require cflags #phase init #after init_cflags #phase header case $PHASE in init) dispn "Checking for pthread method..." PROGRAM="#include void *nothing(void *v) { return NULL; } int main () { pthread_t thread; pthread_create(&thread,NULL,nothing,NULL); return 0; }" compile_test_wrapper "$PROGRAM" "-pthread" "" "" || \ compile_test_wrapper "$PROGRAM" "" "" "-lpthread" || \ { disp "not found, unable to continue" exit 1 } ;; header) disp "Adding \"#include \" to header" $ECHO "#include " ;; esac dsbl-testers/firemake/socket0000644000175000017500000000104607777027050014255 0ustar alal#!/bin/sh #require compiletest #require cflags #phase init #after init_cflags #phase header case $PHASE in init) dispn "Checking to see if compiler needs -lsocket -lnsl..." PROGRAM="#include #include int main () { socket(0,0,0); return 0; }" compile_test_wrapper "$PROGRAM" "" "" "-lsocket -lnsl" || \ disp "no" ;; header) disp "Adding \"#include \" to header" $ECHO "#include " disp "Adding \"#include \" to header" $ECHO "#include " ;; esac dsbl-testers/firemake/strip0000644000175000017500000000025507776577143014143 0ustar alal#!/bin/sh #phase init dispn "Checking for strip..." if strip -V 2>/dev/null; then disp "found strip" STRIP="strip" else disp "not found, continuing without" STRIP="" fi dsbl-testers/firemake/subdir0000644000175000017500000000115707776577143014274 0ustar alal#!/bin/sh #require cc #require cflags #phase library disp "Loading subdirectory helper functions" subdir() { disp "local copy found, configuring:" cd $1 disp "[ENTERING CONFIGURE PROGRAM FOR $1]" FM_IN_SUBDIR="y" ./configure disp "[EXITING CONFIGURE PROGRAM FOR $1]" if (test "$?" != "0"); then disp "subdirectory configure failed, unable to continue" exit 1 fi cd .. FM_SUBDIRS="$FM_SUBDIRS $1" FM_CLEAN_SUBDIRS="$FM_CLEAN_SUBDIRS $1" } parentdir() { dispn "local copy found, adding to build..." FM_SUBDIRS="$FM_SUBDIRS $1" # don't clean parents, or we don't get all the way through clean disp "done" } dsbl-testers/firemake/version0000644000175000017500000000054207776577143014466 0ustar alal#!/bin/sh #require cflags #phase config dispn "Reading firemake.version..." VERSION=`cat firemake.version 2>/dev/null` if test "$?" = "0"; then disp "done, \"$VERSION\"" else disp "not found, using \"0.0.0\"" VERSION="0.0.0" fi dispn "Adding -DVERSION=\"\\\"$VERSION\\\"\" to CFLAGS..." FM_CFLAGS="$FM_CFLAGS -DVERSION=\"\\\"$VERSION\\\"\"" disp done