pax_global_header00006660000000000000000000000064122621025410014505gustar00rootroot0000000000000052 comment=dfcefbd6e044a11e7cbd39f013bbb7ece1dbed98 zonecheck-3.0.5/000077500000000000000000000000001226210254100134635ustar00rootroot00000000000000zonecheck-3.0.5/BUGS000066400000000000000000000003411226210254100141440ustar00rootroot00000000000000# $Id: BUGS,v 1.21 2010/06/01 15:36:06 chabannf Exp $ For information about currently open bugs, as well as bug history, please refer to the bug tracker hosted on Savannah: https://savannah.nongnu.org/bugs/?group=zonecheck zonecheck-3.0.5/COPYING000066400000000000000000000052301226210254100145160ustar00rootroot00000000000000# $Id: COPYING,v 1.8 2010/06/07 08:51:26 chabannf Exp $ ZoneCheck is copyright AFNIC, 2003-2010. Originally written by Stephane D'Alu . Maintained by the ZoneCheck Team at AFNIC. For technical questions/patches about this software, you can contact the team at . For general purpose questions, you can contact AFNIC at . --------------------------------------------------------------- ZoneCheck terms of use and distribution: You can use, modify and distribute ZoneCheck according to the GPL v3 (GNU General Public License) , a copy has been made available in the file 'GPL'. To summarize (a lot!), it means you can use ZoneCheck freely (but not to link it with software which is not GPL-compatible), you can have the source code, you can distribute it freely (even after modifications) BUT you cannot deny these freedoms to the people who receive it: for instance, you must provide them with the source code. Alternatively, if you want to use or distribute a version of ZoneCheck in a way which is not compatible with the GPL you *must* get an agreement from AFNIC which will give you the right to use the following terms. The license is therefore *not* a disjunctive license. ----------- Terms after relicencing, for the licencee only ---- Permission is hereby granted, to <> obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit individuals or organizations to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -- WARNING ---------------------------------------------------- Patch submitters are therefore informed that, for the patches to be included, you must agree on this possible relicensing. --------------------------------------------------------------- References that you may find interesting: http://www.gnu.org/licenses/licenses.html zonecheck-3.0.5/CREDITS000066400000000000000000000006261226210254100145070ustar00rootroot00000000000000# $Id: CREDITS,v 1.9 2010/06/08 08:59:10 chabannf Exp $ Primary Code Design, Development and Maintenance: Fabien Chabanne Stéphane D'Alu Contributors: Alex Dalitz Tanaka Akira Eric Redon Stephane Bortzmeyer Icons/Pictures/Logo: David Barou Spelling corrections: Stephane Bortzmeyer Sylvie Lacep Marine Chantreau Bug reports and suggestions: Stephane Bortzmeyer Marcos Sanz Mohacsi Janos zonecheck-3.0.5/ChangeLog000066400000000000000000000221101226210254100152310ustar00rootroot00000000000000# $Id: ChangeLog,v 1.60 2011/04/11 08:32:38 kmkaplan Exp $ 2011-04-11 ZoneCheck-3.0.5 * Feature: ds-rdata can be passed as CGI arguments. * Bug #32746: "IWBN to give raw DS as argument to --securedelegation" fixed * Bug #32125: "Invalid trust anchors in --securedelegation are silently ignored" fixed * Bug #32123: "When several --securedelegation are given, only the last one is used" fixed * Bug: glues at the apex were not ignored by the test delegation_udp512_additional and for the cachability test. Fixes a bug introduced on 2010-06-01T15:36 during the migration do Dnsruby. 2010-11-22 ZoneCheck-3.0.4 * Bug #31382: "Test of IP address syntax does not work when there are several addresses" fixed 2010-10-05 ZoneCheck-3.0.3 * Bug #31169: "Checking fails when the MX is the domain itself and is not yet installed" fixed * Bug #31163: "non-FQDN NS with FQDN domain" fixed 2010-06-29 ZoneCheck-3.0.2 * input: cgi bug: [""].empty? => false * zc: change the call of Locale::new to ZoneCheck::Locale::new, so that ZoneCheck and ruby-locale can live together * test: change default severity for chk_soa_coherence and chk_soa_master_coherence to warning 2010-06-28 ZoneCheck-3.0.1 * input: bug empty DNSKEY field * zc: bug wrong number of arguments (again) * debug: store all messages, and print the matching messages if flags change * zc: add compatibility with ruby 1.9.1 * zc: can be used with either the package dnsruby or the gem dnsruby * input: change html input files, so that DNSSEC tests are off by default * test: chk_algorithm now checks all the SOA RRSIG not just the first one * test: change the error message of chk_algorithm 2010-06-22 ZoneCheck-3.0.0 * rootservers: add the new IPv6 address for i.root-servers.net * zc: nameserver name can not be an IP address * installer: bad interpreter bug fix * installer: dependency to rubygems-dnsruby >= 1.47 added in spec file 2010-06-17 ZoneCheck-3.0.0 RC2 * publisher: change error message when an exception is thrown while testing the "primary nameserver" in a "coherence test" * test: chk_edns now ask for ANY with DNSSEC instead of NS * test: error message bug fix for one_dnskey and has_soa_rrsig * zc: query_timeout, retyr_times and retry_delay are now read in zc.conf * debug: wrong number of arguments bug fix for some debug output * zc: cache mutex lock bug fix * output: fix the DNSKEY textarea width 2010-06-15 ZoneCheck-3.0.0 RC1 * test: new tests about DNSSEC (ds_and_dnskey_coherence, one_dnskey, several_dnskey, has_soa_rrsig, zsk_and_ksk, key_length, soa_rrsig_expiration, soa_rrsig_validity_period, algorithm, verify_soa_rrsig) (#20334) * test: new test on edns support (#28694) * nresolv: replace NResolv by Dnsruby * zc: an option make all tests performed with or without edns0 (#29120) * zc: classes are in module ZoneCheck (#19875) * input, output: GTK interface removed (#4139) * input: inetd input removed * input: add new options (edns, securedelegation) to HTML and CLI * i18n: add a debug message when language is not found (#28871) * zc: batch mode option removed (workaround in bug report) (#8474, #30032) 2010-05-26 ZoneCheck-2.1.1 * publisher: escape http query parameters to prevent XSS attacks (#29967) * installer: patch_cgi path typo removed 2010-02-12 ZoneCheck-2.1.0 * nresolv: zonecheck ask for a type A and AAAA instead of ANY in order to have ip adresses of nameservers (#13035) * test: fixed bug in serial number test (#28470) * test: ZoneCheck does not warn against IDN names anymore (#7816) * test: fixed bug with -obh option (#13227,#16194,#16195) * test: fixed compliance with SMTP request (#22925) * test: change ICMP TTL/Opcount to 64 (#28761) * test: added a timeout on SMTP request (#15228) * test: fixed bug in soa_coherence (#16317) * test: fixed bug in ns_sntx (#18889) * l10n: removed typos (#10339,#21018,#22362) 2008-10-29 ZoneCheck-2.0.8 * config: updated afnic profile 2004-05-?? ZoneCheck-2.0.4 * l10n: removed typos * test: added details for 'ns_ip' * nresolv: fixed bug in getaddress 2004-03-08 ZoneCheck-2.0.3 * dbg: fixed debuging output for nresolv * dbg: added smtp transaction as debuging information for mail * doc: fixed apache configuration example * zc: fixed locale interpretation * zc: added control on IP stack detection (ZC_IP_STACK) * zc: added environment variable to control config parameter * install: WWWDIR option allows changing static web page directory * nresolv: UDP retry a little less aggressive * publisher: option 'nojavascript' and 'ihtml' for html * misc: B rootserver IP addresse changed * config: fixed profile selection * html: use of option group for the profile selection * test: follow cname chain when checking for reverse 2004-01-20 ZoneCheck-2.0.2 * test: fixed bugs in mail_delivery_{postmaster,hostmaster} * zc: fixed bugs in XML parsing * zc: fixed --INPUT not working in some cases * test: only the default profile is enabled in the configuration file * input: gtk interface is still partially broken * input: fixed frozen object in cli 2004-01-05 ZoneCheck-2.0.1 * test: preeval doesn't report fatal error anymore * locale: removed wrong explanation for ping (french) * zc: automatically use ruby-libxml implementation if available * zc: fixed handling of preset * test: all_same_asn test activated in the default profile * publisher: removed right-click menu for html pages * test: added details for mx_cname test 2003-12-01 ZoneCheck-2.0.0 * publisher: protect quote in javascript string * test: re. use the same profile as fr. * zc: renamed profile fr to afnic * test: improved ip_bogon to handle NXDOMAIN responses * test: tcp connectivity has an 8 seconds timeout * nresolv: fix decoding of TXT records * test: new test to ensure different AS (chk_all_same_asn) 2003-11-18 ZoneCheck-2.0.0b10 * misc: fixed bug in installer * dbg: added debugging information * test: added details for email test * zc: explanations are formated automatically * config/msgcat: use of xml file format * test: soa_{refresh,retry,minimum,expire} are configurable * test: delegation_udp512* give the exceding size * publisher: link to the external reference * zc: added profile selection * zc: added preset configuration 2003-10-27 ZoneCheck-2.0.0b9 * dbg: time the execution of test * www: form can be submited by pressing enter * test: fix chk_aaaa test * cfg: use -n to disable name resolution for ping commande * test: use of alternative rootserver possible in chk_root_server_* * test: chk_root_server_* now give detailed information * test: checking of delegation response size chk_delegation_udp512* * nresolv: able to encode NS, A, AAAA records * zc: fixed wrong exit code when 'no stop on fatal' was enabled * zc: option --resolver is not necessary anymore on windows * zc: added statistics for web page * test: check for non recursive server (chk_not_recursive) * misc: new installation procedure (using ruby only) * misc: add zonecheck.spec 2003-10-02 ZoneCheck-2.0.0b8 * test: added chk_soa_coherence * l10n: improved chk_mx_ip description * etc: deal with ip6.int as with arpa * main: change handling of custom version (no more slave mode) * main: fixed bug in is_resolvable? * test: reduced timeout on tcp for mail connection * test: more in depth check of tcp connection (chk_tcp) * mail: fixed open relay detection * test: catch connection refused in chk_udp * test: aaaa query behaviour * test: fixed bug in chk_given_nsprim_vs_soa * nresolv: added code for handling lost of tcp connection 2003-09-01 ZoneCheck-2.0.0b7 * i18n/l10n: better handling of locale (and encoding) * input: added inetd mode * doc: man page for zonecheck cli * doc: general documentation has been sligthy completed * all: minor bug fixes 2003-08-11 ZoneCheck-2.0.0b6 * input: removed excessive sanity check for input parameter * all: changed strings "" to '' when possible * dbg: improved debugging facility (multiline, lazy evaluation) * publisher: 'fatalonly' flag to only print fatal errors * test: added dbgmsg to ease login of messages during test execution * test: correct 'chk_recursive' test * msgcat: reload method cleanup 2003-04-29 Stephane D'Alu * all: GPL version fixed to v2 2003-04-28 Stephane D'Alu * report: now provide 'byseverity' and 'byhost' * report: can generate the list of successful tests * publisher: able to report 'testname' 2003-03-21 Stephane D'Alu * test: added chk_mail_hostmaster_mx_cname * zc: IPv4 stack detection * i18n/10n: french translation of web pages * nresolv: skip unknown dns record 2003-03-18 Stephane D'Alu * i18n/l10n: UTF-8 output support, locale in UTF8 zonecheck-3.0.5/FAQ000066400000000000000000000104021226210254100140120ustar00rootroot00000000000000 -------------------------------------------------------------------------- Table of Contents [1]FAQ FAQ 1. [2]Where can I find documentation about Ruby? 2. [3]I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses... 3. [4]I want to use an interface other than the CLI. 4. [5]The -d lvl option doesn't display earlier debugging messages 5. [6]I would like to easily test ZoneCheck without doing a full installation... 6. [7]Why do I get rubbish or wrong results when doing the icmp test? 7. [8]Why did I get strange characters when using a locale other than US/English? 8. [9]ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server... 9. [10]ZoneCheck crashes when reading configuration files or the message catalog 1. Where can I find documentation about Ruby? Try the offical Ruby website: [11]http://www.ruby-lang.org/ 2. I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses... ZoneCheck only looks for an enabled IPv6 stack to authorize the use of IPv6 addresses. It would be a good idea to disable the IPv6 stack on your computer if you don't have the connectivity or you can use the -4 option to force IPv4 only connectivity. 3. I want to use an interface other than the CLI. Use the environment variable ZC_INPUT set to your input mode, or use the command line option --INPUT=im. The input modes currently supported are CLI, CGI, and inetd 4. The -d lvl option doesn't display earlier debugging messages Some debugging messages are sent before the debugging level is initialised by the command line, in this case use the environment variable ZC_DEBUG set to the desired level. But keep in mind that ZC_DEBUG will be overriden by the -d lvl option. 5. I would like to easily test ZoneCheck without doing a full installation... You can define the environment variable ZC_INSTALL_PATH to the initial ZoneCheck directory. 6. Why do I get rubbish or wrong results when doing the icmp test? ZoneCheck uses the command ping to perform this test, so you should set the constants ping4 and ping6 in the configuration file so that the ping is correctly invoked: stop after 5 echo requests, doesn't output messages, and return an exit code of 0 in case of success. If you are using ZoneCheck on the Windows platform, you better remove the test. 7. Why did I get strange characters when using a locale other than US/English? The default encoding is UTF-8, either you can configure your terminal to use UTF-8, or you can specify the desired encoding after the locale by using a dot as separator (ex: LANG=fr.latin1); in the last case the ruby-iconv package should have been installed. 8. ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server... Unfortunately, by default, djbdns/tinydns does not listen on TCP. See [12]http://cr.yp.to/djbdns/tcp.html to enable it. 9. ZoneCheck crashes when reading configuration files or the message catalog REXML is used to parse the XML files, but it only checks for well formed XML and doesn't perform validation against the DTD, so when you edit the configuration file or the message catalog you should ensure that the files are valid, for that purpose you can use xmllint for example. References Visible links 1. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2892242 2. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877039 3. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877064 4. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877089 5. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877372 6. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877411 7. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877434 8. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877486 9. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877509 10. file:///tmp/zcrelease.19344/zonecheck/doc/html/FAQ.html#id2877533 11. http://www.ruby-lang.org/ 12. http://cr.yp.to/djbdns/tcp.html zonecheck-3.0.5/GPL000066400000000000000000001045131226210254100140340ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . zonecheck-3.0.5/HISTORY000066400000000000000000000020151226210254100145450ustar00rootroot00000000000000# $Id: HISTORY,v 1.4 2010/06/01 15:36:06 chabannf Exp $ ZoneCheck was initiated and developed by engineers working at AFNIC in order to check the correct configuration of a zone before delegation of a domain name under .fr. Its development is still coordinated by people working at AFNIC. * ZoneCheck 1.0 ZoneCheck was created in 1995 by Benoit Grange and has been maintained by him until 1997. The prototype was a script using the dig command, which evolved into a Perl programme based on the DNS resolver Resolv5. Vincent Gillet maintained the programme in 1998, this task has been taken over by Erwan Mas and Philippe Lubrano from 1998 on. * ZoneCheck 2.0 It is a rewrite from scratch done in Ruby at the end of 2002 by Stephane D'Alu, so as to create a modular and extensible version. * ZoneCheck 3.0 This version was partially rewritten by Fabien Chabanne to leverage DNS Client code in the Dnsruby library. This allowed the development of new checks, including EDNS and DNSSEC support. zonecheck-3.0.5/INSTALL000066400000000000000000000054151226210254100145210ustar00rootroot00000000000000# $Id: INSTALL,v 1.17 2010/06/01 15:36:06 chabannf Exp $ For the impatient: 'ruby ./installer.rb all' to install Zonecheck. It should generally works, but there is sometimes some misconfigurations of the installer, so we recommend you to check the environment variables used by the installer. To do so you can type 'ruby ./installer.rb' without parameter. You will need Ruby to install ZoneCheck, after the installation the executable will be available under the name of 'zonecheck' Ruby can be found as a package or port in every serious Unix. Otherwise, see and , or if you are a Windows user, you can find a version of ruby in the cygwin distribution . WARNING: - you need at least the version 1.8 of Ruby. - it is not advised for now to use 'rubyinstaller' as some constants allowing to detect errors in network connectivity are not defined. If you are reading this file, we can assume that you haven't already install ZoneCheck by typing "make install"; in fact you don't need the 'make' command (but as it is a reflex, a dummy Makefile has been created). To install ZoneCheck you need to execute the following command: ruby ./installer.rb target [-Dparam=value] where target can have one of the following values - all: install everything - common: install common part of ZoneCheck - cgi: install the necessary files for cgi (requires: common) - cli: install the necessary files for command line (requires: common) - doc: install extra documentation the -D option allow to define one of the installation parameters for example: - RUBY define the full path of the interpreter to use - PREFIX define where ZoneCheck is to be installed - HTML_PATH define the path relative to the web site (for the cgi) There are a few other parameters but you shouldn't need them. The default hierarchy is: PREFIX [/usr/local] |-- bin | `-- zonecheck # Command line |-- etc | `-- zonecheck # Configuration directory | |-- zc.conf # Main configuration file | |-- rootservers # List of the root servers (YAML file) | |-- reverse.rules # Rules for checking reverse delegation | |-- ... # ... | `-- default.rules # Default set of rules to be used |-- libexec | `--zonecheck | |-- cgi-bin | | `-- zc.cgi # CGI | |-- html # HTML directory (javascript, css, pics, ...) | | |-- en # English version | | |-- ... # ... | | `-- fr # French version | |-- locale # Localization files | |-- test # Test set | |-- lib # Extra libraries (Whois) | `-- zc # core component `-- share `-- doc `-- zonecheck # Documentation zonecheck-3.0.5/Makefile000066400000000000000000000012601226210254100151220ustar00rootroot00000000000000# $Id: Makefile,v 1.40 2010/06/01 15:36:06 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/10/23 21:04:09 # REVISION : $Revision: 1.40 $ # DATE : $Date: 2010/06/01 15:36:06 $ # RUBY ?=ruby ZC_INSTALLER=$(RUBY) ./installer.rb all: configinfo configinfo: @echo "Nothing to make, you can install it right now!" @echo " => but ensure that you have the full path for the ruby interpreter!" @echo "" @$(ZC_INSTALLER) configinfo @echo "" @echo "You can change them by using the syntax:" @echo " $(MAKE) key=value" install: @$(ZC_INSTALLER) all default: $(MAKE) RUBY=`which ruby` installzonecheck-3.0.5/README000066400000000000000000000022551226210254100143470ustar00rootroot00000000000000# $Id: README,v 1.4 2010/06/15 08:27:22 chabannf Exp $ Documentation about 'ruby' can be found at: http://www.ruby-lang.org/ The DNS is a critical resource for every network application, quite important to ensure that a zone or domain name is correctly configured in the DNS. ZoneCheck is intended to help solving misconfigurations or inconsistencies usually revealed by an increase in the latency of the application, up to the output of unexpected/inconsistant results. The ZoneCheck configuration file reflect the policy. You can let ZoneCheck select the best test set to apply when checking a zone (for example, a specific profile for reverse delegation when under .ip6.arpa or .in-addr.arpa, or any mapping declared in ZoneCheck configuration file); but on the other hand, you can also force the use of a particular profile (for example you could create an RFC compliance checking profile). To install ZoneCheck from sources, please take a look at INSTALL file. To learn more about different versions of ZoneCheck you can see HISTORY and ChangeLog files. Details about license and copyrights see COPYING, GPL and CREDITS files. More informations are available at www.zonecheck.fr zonecheck-3.0.5/README-rpm000066400000000000000000000005621226210254100151420ustar00rootroot00000000000000Unofficial guide of RPM building ******************************* unset CVSROOT pushd contrib/distrib sh release.sh $VERSION /tmp sudo mv /tmp/$TARBALL /usr/src/redhat/SOURCES cvs -d :ext:$NAME@cvs.savannah.nongnu.org:/cvsroot/zonecheck co -r $TAG zonecheck cd zonecheck PREFIX=/usr ruby installer.rb configure cd contrib/distrib/rpm sudo rpmbuild -bb zonecheck.spec zonecheck-3.0.5/TODO000066400000000000000000000027121226210254100141550ustar00rootroot00000000000000# $Id: TODO,v 1.74 2010/06/01 15:36:06 chabannf Exp $ add preset to inetd, cgi version = 2.1.0 Tests: - Implement AXFR tests (only framework exists) - base de donnees reseau (RIR) - test connectivite avec plusieurs adresses IP handle in test1 the case when a 'test' (ie: switch) fails make it more clear that 'primary' is not the primary when hidden in SOA Finish xml publisher and DTD IDN check for label_xpl defined elsewhere special timeout return code Tests: - check coherence between parent glue and domain - Improve loopback delegation detection - chk_soa (should check for EXACTLY one record) - tst_loopback: check for A or AAAA record corresponding to PTR Round robin on dns record in NResolv for address resolution Check for authoritative answer in NResolv version = 3.0.0 stand alone package for resolver library add checking of message catalog and test set fix behaviour in case of test failed edns0 New scheduling engine (++++) \ New test scheme (ie: tst_*) (++++) | Have a useconf strict (+++) Detection of failure due to dependencies [doomed] A test can change the severity (ex: test soa.ttl between ns) (+++) Cachemanager destroy method (and use it) (++) Try zonecheck with the native thread ruby implementation Remove the need of a tagonly_supported in Report Finish implementing nresolv (Bitstring, DNSSEC) NResolv library able to inspect all the Sections (++++) Test: - whois for fr version = 3.1.0 DNSSEC zonecheck-3.0.5/contrib/000077500000000000000000000000001226210254100151235ustar00rootroot00000000000000zonecheck-3.0.5/contrib/DocMaker/000077500000000000000000000000001226210254100166105ustar00rootroot00000000000000zonecheck-3.0.5/contrib/DocMaker/src/000077500000000000000000000000001226210254100173775ustar00rootroot00000000000000zonecheck-3.0.5/contrib/DocMaker/src/xmlinfo.c000066400000000000000000000104071226210254100212210ustar00rootroot00000000000000/****************************************************************************** * $Id: xmlinfo.c,v 1.1 2010/10/05 09:00:55 bortzmeyer Exp $ * * AUTHOR : Stephane D'Alu * CREATED: 2003/01/12 18:02:35 * * WWW : http://www.sdalu.com/software/ * LICENSE: GPL v2 (see http://www.gnu.org/licenses/gpl.txt) * * * $Revision: 1.1 $ * $Date: 2010/10/05 09:00:55 $ * * * REQUIRES: * libxml2: http://xmlsoft.org/downloads.html * * COMPILING: * gcc -o xmlinfo xmlinfo.c `xml2-config --cflags` `xml2-config --libs` * */ #include #include #include #include #include #include #include #include #include #define EXIT_OK 0 #define EXIT_BADXML 1 #define EXIT_NOFILE 2 #define EXIT_USAGE 3 #define EXIT_INTERNAL 4 static char *progname; void usage(int exitcode) { printf("usage: %s [-h] [-q] [-e encoding] filename\n", progname); printf(" -q quiet\n"); printf(" -e output encoding (|utf16|iso-8859-1|...)\n"); printf(" -h this help\n"); exit(exitcode); } void noerror_handler(void *ctx, const char *msg, ...) { } int main(int argc, char **argv) { int ch; char *encoding = "utf8"; char *filename; int quiet = 0; int exitcode = EXIT_OK; xmlDocPtr doc = NULL; xmlDtdPtr dtd = NULL; xmlCharEncoding enc; xmlCharEncodingHandlerPtr enchandler; xmlOutputBufferPtr out; /* LibXML version checking */ LIBXML_TEST_VERSION; /* Who am I? */ if ((progname = rindex(argv[0], '/'))) progname++; else progname = argv[0]; /* Parsing CLI */ while ((ch = getopt(argc, argv, "hqe:")) != -1) switch (ch) { case 'q': quiet = 1; break; case 'e': encoding = optarg; break; case 'h': /* FALL THROUGH */ case '?': usage(EXIT_OK); break; default: usage(EXIT_USAGE); break; } argc -= optind; argv += optind; switch (argc) { case 1: filename = argv[0]; break; case 0: filename = "-"; break; default: usage(EXIT_USAGE); } /* Get user encoding */ if ((enc = xmlParseCharEncoding(encoding)) == XML_CHAR_ENCODING_ERROR) { fprintf(stderr, "Unknown encoding: %s\n", encoding); usage(EXIT_USAGE); } enchandler = xmlGetCharEncodingHandler(enc); /* Shut up */ xmlSetGenericErrorFunc(NULL, &noerror_handler); xmlGetWarningsDefaultValue = 0; xmlPedanticParserDefault(0); /* File exists? (race condition below) */ if (strcmp(filename, "-") && (open(filename, O_RDONLY) < 0)) { if (!quiet) fprintf(stderr, "ERROR: unable to open %s\n", filename); exitcode = EXIT_NOFILE; goto exit; } /* Parse document */ if ((doc = xmlParseFile(filename)) == NULL) { if (!quiet) fprintf(stderr, "ERROR: badly formed document\n"); exitcode = EXIT_BADXML; goto exit; } /* Extract DTD (if any) */ dtd = xmlGetIntSubset(doc); /* Create output buffer */ if ((out = xmlOutputBufferCreateFd(1, enchandler)) == NULL) { if (!quiet) fprintf(stderr, "ERROR: unable to open output channel\n"); exitcode = EXIT_INTERNAL; goto exit; } /* Dump information */ if (doc->version) { xmlOutputBufferWriteString(out, "Version : "); xmlOutputBufferWriteString(out, doc->version); xmlOutputBufferWriteString(out, "\n"); } if (doc->encoding) { xmlOutputBufferWriteString(out, "Encoding : "); xmlOutputBufferWriteString(out, doc->encoding); xmlOutputBufferWriteString(out, "\n"); } if (dtd && dtd->name) { xmlOutputBufferWriteString(out, "Name : "); xmlOutputBufferWriteString(out, dtd->name); xmlOutputBufferWriteString(out, "\n"); } if (dtd && dtd->ExternalID) { xmlOutputBufferWriteString(out, "Identifier: "); xmlOutputBufferWriteString(out, dtd->ExternalID); xmlOutputBufferWriteString(out, "\n"); } if (dtd && dtd->SystemID) { xmlOutputBufferWriteString(out, "URI : "); xmlOutputBufferWriteString(out, dtd->SystemID); xmlOutputBufferWriteString(out, "\n"); xmlOutputBufferFlush(out); } /* Free resources */ if (doc) xmlFreeDoc(doc); xmlCleanupParser(); /* OK */ exit: exit(exitcode); } zonecheck-3.0.5/contrib/dig.rb000066400000000000000000000007001226210254100162100ustar00rootroot00000000000000#!/usr/local/bin/ruby ZC_INSTALL_PATH = (ENV["ZC_INSTALL_PATH"] || (ENV["HOME"] || "/homes/sdalu") + "/Repository/zonecheck").dup.untaint ZC_LIB = "#{ZC_INSTALL_PATH}/lib" $LOAD_PATH << ZC_LIB require 'rubygems' require 'dnsruby' resolver = Dnsruby::Resolver::new({ :nameserver => 'ns1.nic.fr'}) resolver.dnssec = false name = Dnsruby::Name::create("fr.") puts name resolver.query(name.to_s, "NS") { |r,t,n,rpl| puts "#{r.to_dig}" } zonecheck-3.0.5/contrib/display-policy/000077500000000000000000000000001226210254100200655ustar00rootroot00000000000000zonecheck-3.0.5/contrib/display-policy/Makefile000066400000000000000000000004331226210254100215250ustar00rootroot00000000000000STYLESHEET=http://www.afnic.fr/tpl/tpl.css all: afnic.fr.html afnic.en.html afnic.fr.html: afnic.profile ./profile2html.py -l fr -s ${STYLESHEET} afnic.profile > $@ afnic.en.html: afnic.profile ./profile2html.py -l en -s ${STYLESHEET} afnic.profile > $@ clean: rm -f *.html *~zonecheck-3.0.5/contrib/display-policy/profile2html.py000066400000000000000000000342361226210254100230560ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: ISO-8859-1 -*- # TODO: recode in ElementTree, more Pythonesque than DOM! from xml.dom.ext.reader import Sax2 from xml.dom.ext import PrettyPrint from xml import xpath from xml.dom import getDOMImplementation import xml.dom import sys import os import re import string import getopt LANG = "en" stylesheet = None def file2DOM(filename): reader = Sax2.Reader() doc = reader.fromStream(filename) return doc def usage(): myself = sys.argv[0] return "Usage: %s [-p] [-l language] [-s CSS-stylesheet] zonecheck-profile" % myself def fatal(message): sys.stderr.write("%s\n" % message) sys.exit(1) def capitalize(thestring): """ Unlike string.capitalize(), we just touch the first letter, never the others. """ if len(thestring) == 0: return "" elif len(thestring) == 1: return string.upper(thestring[0]) else: return (string.upper(thestring[0]) + thestring[1:]) def all_check_messages(dir, lang='en'): messages = {} explanations = {} for file in os.listdir(dir): if not re.search("\.%s$" % lang, file): continue dom = file2DOM("file:%s/%s" % (dir, file)) checks = from_xpath("/msgcat/check", dom) for check in checks: messages[attribute(check, 'name')] = check local_explanations = from_xpath("/msgcat/shortcut/explanation", dom, required=False) if local_explanations is not None: for explanation in local_explanations: explanations["shortcut:%s" % attribute(explanation, 'name')] = explanation return (messages, explanations) def from_xpath(expr, dom, required=True, only_one_item=False): match = xpath.Evaluate(expr, dom) if match: if only_one_item: if len(match) > 1: raise Exception("More than one item (%i) found for \"%s\" in the DOM tree <%s>" % \ (len(match), expr, dom.nodeName)) else: return match[0] else: return match else: if required: raise Exception("No \"%s\" in the DOM tree <%s>" % \ (expr, dom.nodeName)) else: return None def attribute(node, attname): att_node = node.attributes.getNamedItem(attname) if att_node is not None: return att_node.nodeValue else: return None def explanation_text(node): reference = from_xpath("@sameas", node, required=False) if reference is not None: (category, ref) = string.split(reference[0].nodeValue, ":") details = explanations["%s:%s" % (category, ref)] srcs = from_xpath("src", details) message = "" for src in srcs: message = message + concat_text_nodes(from_xpath("title", src)) + \ " : " + \ concat_text_nodes(from_xpath("para", src)) message = message + "\n" else: source = from_xpath("src", node, required=False, only_one_item=True) if source is not None: message = concat_text_nodes(from_xpath("title", source)) + ". " + \ concat_text_nodes(from_xpath("para", source)) else: message = "" return mark_specials(message) def mark_specials(message): """ Finds in a message (a paragraph) "special" text such as references to RFCs or URLs and turns them into nice hypertext.""" result = html_result.createElement("p") nodes = mark_rfc(message) for node in nodes: if node.nodeType == xml.dom.Node.TEXT_NODE: new_nodes = mark_url(node.nodeValue) for new_node in new_nodes: result.appendChild(new_node) else: result.appendChild(node) return result def mark_url(msg): """ Finds references to URLs and turn them into hypertext """ # TODO: may be we whould rely on elements only but they are not always used. url_text = "((?:https?|ftp)://[A-Za-z0-9\.\-]+[^ ]*)" url_re = re.compile (url_text, re.IGNORECASE) chunks = re.split (url_re, msg) result = [] for chunk in chunks: if url_re.match (chunk): link = html_result.createElement("a") url = html_result.createAttribute("href") url.nodeValue = chunk link.setAttributeNode(url) code = html_result.createElement("code") link.appendChild(code) code.appendChild(html_result.createTextNode(chunk)) result.append(link) else: result.append(html_result.createTextNode(chunk)) return result def mark_rfc(msg): """ Finds references to IETF RFCs and turn them into hypertext """ chunks = re.split ("RFC-? ?([0-9]+)", msg) result = [] for chunk in chunks: if re.match ("[0-9]+", chunk): link = html_result.createElement("a") url = html_result.createAttribute("href") url.nodeValue = "http://www.ietf.org/rfc/rfc%i.txt" % int(chunk) link.setAttributeNode(url) link.appendChild(html_result.createTextNode("RFC %i" % int(chunk))) result.append(link) else: result.append(html_result.createTextNode(chunk)) return result def concat_text_nodes(list): result = "" for node in list: if node.nodeType == xml.dom.Node.TEXT_NODE: result = result + " " + node.nodeValue elif node.nodeType == xml.dom.Node.ELEMENT_NODE: if node.nodeName == "uri": result = result + " " + node.childNodes[0].nodeValue # TODO: transform in # instead, it is quite stupid to produce text from XML elements, to # turn them in XML afterwards, by a regexp! elif node.nodeName == "zcconst": constant_name = from_xpath("@name", node, only_one_item=True).nodeValue, constant = from_xpath("//const[@name=\"%s\"]" % constant_name, profile.documentElement, only_one_item=True) value = attribute(constant, "value") display = from_xpath("@display", node, only_one_item=True, required=False) if display is not None: if display.nodeValue == "duration": const_value = value + " s" else: const_value = value result = result + const_value else: result = result + concat_text_nodes(node.childNodes) return result if __name__ == '__main__': try: # Default values partial = False optlist, args = getopt.getopt (sys.argv[1:], "hl:s:p", ["help", "version", "partial-html", "lang=", "stylesheet="]) for option, value in optlist: if option == "--help" or option == "-h": print (usage()) sys.exit(0) elif option == "--version": print sys.argv[0] + " (CVS $Revision: 1.6 $)\n" + " Python " + sys.version sys.exit(0) elif option == "--partial-html" or option == "-p": partial = True elif option == "--lang" or option == "-l": LANG = value elif option == "--stylesheet" or option == "-s": stylesheet = value else: fatal ("Unknown option " + option) except getopt.error, reason: fatal (usage() + "\n%s" % reason) if len(args) < 1 or len(args) > 1: fatal (usage()) profilename = args[0] (messages, explanations) = all_check_messages("%s/AFNIC/zonecheck/locale/test" % \ os.environ['HOME'], LANG) profile = file2DOM(profilename) profilenode = from_xpath("/config/profile", profile, only_one_item=True) if not partial: html_result = getDOMImplementation().createDocument( None, "html", getDOMImplementation().createDocumentType( "html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd")) head = html_result.documentElement.appendChild(html_result.createElement('head')) body = html_result.documentElement.appendChild(html_result.createElement('body')) if LANG == "en": blurb = "Tests made by Zonecheck at" elif LANG == "fr": blurb = u"Tests effectus par Zonecheck " else: blurb = "" title = head.appendChild(html_result.createElement('title')) title.appendChild(html_result.createTextNode("%s %s (%s)" % \ (blurb, string.upper(attribute (profilenode, 'name')), attribute (profilenode, 'longdesc')))) if stylesheet is not None: css = head.appendChild(html_result.createElement('link')) css_rel = html_result.createAttribute("rel") css_rel.nodeValue = "stylesheet" css.setAttributeNode(css_rel) css_type = html_result.createAttribute("type") css_type.nodeValue = "text/css" css.setAttributeNode(css_type) css_url = html_result.createAttribute("href") css_url.nodeValue = stylesheet css.setAttributeNode(css_url) h1 = body.appendChild(html_result.createElement('h1')) h1.appendChild(html_result.createTextNode("%s %s (%s)" % \ (blurb, string.upper(attribute (profilenode, 'name')), attribute (profilenode, 'longdesc')))) else: # Partial HTML html_result = getDOMImplementation().createDocument( None, "div", None) body = html_result.documentElement rulenodes = from_xpath("rules", profilenode) for rule in rulenodes: body.appendChild(html_result.createElement("hr")) html_rule = body.appendChild(html_result.createElement("h2")) anchor = html_rule.appendChild(html_result.createElement("a")) anchor_name = html_result.createAttribute("name") anchor_name.nodeValue = attribute(rule, 'class') anchor.setAttributeNode(anchor_name) if LANG == "en": blurb = "Tests of class " elif LANG == "fr": blurb = u"Tests de la classe " else: blurb = "" html_rule.appendChild(html_result.createTextNode("%s \"%s\"" % (blurb, attribute(rule, 'class')))) checknodes = from_xpath("descendant::check", rule) for check in checknodes: name = attribute(check, 'name') precondition = from_xpath("../../when", check, required=False) is_else = not from_xpath("../@value", check, required=False) if precondition: if is_else: # TODO: internationalize condition = "(Only if \"" + \ from_xpath("../../@test/text()", check, only_one_item=True).nodeValue + \ "\" != \"" + \ from_xpath("../../when/@value", check, only_one_item=True).nodeValue + \ "\") " else: condition = "(Only if \"" + \ from_xpath("../../@test/text()", check, only_one_item=True).nodeValue + \ "\" = \"" + \ from_xpath("../@value", check, only_one_item=True).nodeValue + \ "\") " else: condition = "" html_check = body.appendChild \ (html_result.createElement("h3")) anchor = html_check.appendChild(html_result.createElement("a")) anchor_name = html_result.createAttribute("name") anchor_name.nodeValue = name anchor.setAttributeNode(anchor_name) if LANG == "en": blurb = "Test " elif LANG == "fr": blurb = u"Test " else: blurb = "" severity = from_xpath("@severity", check, only_one_item=True).nodeValue # TODO: internationalize it if severity == "f": severity = " (MANDATORY)" elif severity == "w": severity = " (OPTIONAL)" else: severity = " (UNKNOWN SEVERITY \"%s\")" % severity html_check.appendChild(html_result.createTextNode("%s%s \"%s\" %s" % (condition, blurb, name, severity))) if messages.has_key(name): longname = concat_text_nodes([from_xpath("name", messages[name], only_one_item=True)]) html_check_msg = body.appendChild( html_result.createElement("p")) html_check_msg.appendChild(html_result.createTextNode("%s" % \ capitalize(longname.strip()))) body.appendChild(explanation_text(from_xpath("explanation", messages[name], only_one_item=True))) else: raise Exception("Test %s not found in the message catalogs") PrettyPrint(html_result) # TODO: disable the XML declaration if --partial zonecheck-3.0.5/contrib/distrib/000077500000000000000000000000001226210254100165635ustar00rootroot00000000000000zonecheck-3.0.5/contrib/distrib/release.sh000066400000000000000000000042361226210254100205440ustar00rootroot00000000000000#!/bin/sh export SGML_CATALOG_FILES=/nicdoc/DocMaker/catalog.sgml export XML_CATALOG_FILES=/nicdoc/DocMaker/catalog.xml PATH=$PATH:/nicdoc/DocMaker/bin:/nicdoc/DocMaker/sysdeps/i386-FreeBSD/bin warn() { echo "WARN: $1" ; return 1; } die() { echo "ERROR: $1" ; exit 1; } info() { echo "$1" ; return 1; } # Arguments [ -z "$1" ] && die "version required (ex: 3.0.4)" dest=${2:-/dev/null} [ "${dest#/}" != ${dest} ] || dest=`pwd`/$dest release=$1 tmp=/tmp/zcrelease.$$ cvstag=ZC-`echo $release | sed 's/\./_/g'` module=zonecheck tarname=$module-$release.tgz tarlatest=$module-latest.tgz info "Making ZoneCheck release $release" info "Did you update the ChangeLog (and commit!) to document the changes?" info "Type to confirm or Control-C to cancel: " read confirmation info "- setting CVSROOT" if [ -z "$CVSROOT" ]; then if [ -f CVS/Root ]; then export CVSROOT=`cat CVS/Root` else die "unable to guess CVSROOT, you need to set it" fi fi info "- creating temporary directory $tmp" mkdir -p $tmp cd $tmp || die "unable to change directory to $tmp" info "- exporting from CVS with tag $cvstag" cvs -q export -r $cvstag $module || die "unable to export release tagged $cvstag (may be your forgot to tag *before*?)" info "- generating documentation" ( mkdir -p $module/doc/html cd $module/doc/html || die "unable to change directory to zc/doc/html" xml2doc -q ../xml/FAQ.xml --output=html xml2doc -q ../xml/zc.xml --output=htmlchunk ) ( cd $module elinks -dump doc/html/FAQ.html > FAQ ) info "- creating RPM spec" sed s/@VERSION@/$release/ < $module/contrib/distrib/rpm/zonecheck.spec.in > $module/contrib/distrib/rpm/zonecheck.spec info "- creating tarball: $tarname" tar cfz $tarname $module info "- copy on ${dest}" cp $tarname ${dest} info "- copy on savannah" ln -s $tarname $tarlatest rsync -av $tarname dl.sv.nongnu.org:/releases/zonecheck/ info "- copy on www.zonecheck.fr" rsync -av $tarname -e "ssh -p 2222" www.zonecheck.fr:/var/www/www.zonecheck.fr/htdocs/download info "- cleaning" rm -Rf $tmp info "Do not forget to update www.zonecheck.fr:/var/www/www.zonecheck.fr/htdocs/lastnews.ihtml and download.shtml" exit 0 zonecheck-3.0.5/contrib/distrib/rpm/000077500000000000000000000000001226210254100173615ustar00rootroot00000000000000zonecheck-3.0.5/contrib/distrib/rpm/zonecheck.spec000066400000000000000000000061751226210254100222170ustar00rootroot00000000000000Summary: Perform consistency checks on DNS zones Name: zonecheck Version: 3.0.5 Release: 1 License: GPL Group: Applications/Internet URL: http://www.zonecheck.fr/ Packager: The ZoneCheck Team Vendor: The ZoneCheck Team Source: http://savannah.nongnu.org/download/zonecheck/%{name}-%{version}.tgz BuildRoot: %{_tmppath}/root-%{name}-%{version} BuildArch: noarch BuildRequires: ruby >= 1.8, ruby-libs Requires: ruby >= 1.8, ruby-libs, rubygems-dnsruby >= 1.47 %description ZoneCheck is intended to help solve DNS misconfigurations or inconsistencies that are usually revealed by an increase in the latency of the application. The DNS is a critical resource for every network application, so it is quite important to ensure that a zone or domain name is correctly configured in the DNS. %package cgi Summary: Web service interface for ZoneCheck Group: Applications/Internet Requires: %{name} = %{version} %description cgi Provide a web service interface for ZoneCheck. (ZoneCheck is intended to help solve DNS misconfigurations) %prep %setup -n %{name} %build %{__rm} -rf %{buildroot} %install ruby ./installer.rb common cli cgi \ -DPREFIX="%{_prefix}" \ -DETCDIR="%{_sysconfdir}" \ -DLIBEXEC="%{_libexecdir}" \ -DMANDIR="%{_mandir}" \ -DETCDIST="" \ -DCHROOT="%{buildroot}" \ -DRUBY=/usr/bin/ruby case `uname` in OSF1) ruby -p -i \ -e "\$_.gsub"\!"(/()/, '\1/sbin/ping -n -q -t 5 -c 5 %s > /dev/null\2')" \ -e "\$_.gsub"\!"(/()/, '\1/sbin/ping -n -q -t 5 -c 5 %s > /dev/null\2')" \ %{buildroot}%{_sysconfdir}/zonecheck/zc.conf ;; *) ruby -p -i \ -e "\$_.gsub"\!"(/()/, '\1/bin/ping -n -q -w 5 -c 5 %s > /dev/null\2')" \ -e "\$_.gsub"\!"(/()/, '\1/usr/sbin/ping6 -n -q -w 5 -c 5 %s > /dev/null\2')" \ %{buildroot}%{_sysconfdir}/zonecheck/zc.conf ;; esac %clean %{__rm} -rf %{buildroot} %files %defattr(-, root, root, 0755) %doc BUGS ChangeLog COPYING CREDITS GPL HISTORY README TODO %doc doc/html %dir %{_sysconfdir}/zonecheck %config %{_sysconfdir}/zonecheck/rootservers %config %{_sysconfdir}/zonecheck/*.profile %verify(not size,not md5) %config(noreplace) %{_sysconfdir}/zonecheck/zc.conf %{_bindir}/* %dir %{_libexecdir}/zonecheck %{_libexecdir}/zonecheck/zc %{_libexecdir}/zonecheck/lib %{_libexecdir}/zonecheck/locale %{_libexecdir}/zonecheck/test %{_mandir}/man1/* %files cgi %defattr(-, root, root, 0755) %{_libexecdir}/zonecheck/www %{_libexecdir}/zonecheck/cgi-bin %changelog * Wed Oct 29 2008 Eric Redon - 2.0.8 - Updated AFNIC Configuration profile. * Mon Nov 13 2003 Stephane D'Alu - 2.0.0b10 - Updated for new zone configuration profile. * Fri Oct 24 2003 Jean-Philippe Pick - 2.0.0b9 - Reworked packaging to meet new installation process. * Tue Sep 02 2003 Dag Wieers - 2.0.0-0.b7 - Initial package. (using DAR) zonecheck-3.0.5/contrib/distrib/rpm/zonecheck.spec.in000066400000000000000000000062011226210254100226120ustar00rootroot00000000000000Summary: Perform consistency checks on DNS zones Name: zonecheck Version: @VERSION@ Release: 1 License: GPL Group: Applications/Internet URL: http://www.zonecheck.fr/ Packager: The ZoneCheck Team Vendor: The ZoneCheck Team Source: http://savannah.nongnu.org/download/zonecheck/%{name}-%{version}.tgz BuildRoot: %{_tmppath}/root-%{name}-%{version} BuildArch: noarch BuildRequires: ruby >= 1.8, ruby-libs Requires: ruby >= 1.8, ruby-libs, rubygems-dnsruby >= 1.47 %description ZoneCheck is intended to help solve DNS misconfigurations or inconsistencies that are usually revealed by an increase in the latency of the application. The DNS is a critical resource for every network application, so it is quite important to ensure that a zone or domain name is correctly configured in the DNS. %package cgi Summary: Web service interface for ZoneCheck Group: Applications/Internet Requires: %{name} = %{version} %description cgi Provide a web service interface for ZoneCheck. (ZoneCheck is intended to help solve DNS misconfigurations) %prep %setup -n %{name} %build %{__rm} -rf %{buildroot} %install ruby ./installer.rb common cli cgi \ -DPREFIX="%{_prefix}" \ -DETCDIR="%{_sysconfdir}" \ -DLIBEXEC="%{_libexecdir}" \ -DMANDIR="%{_mandir}" \ -DETCDIST="" \ -DCHROOT="%{buildroot}" \ -DRUBY=/usr/bin/ruby case `uname` in OSF1) ruby -p -i \ -e "\$_.gsub"\!"(/()/, '\1/sbin/ping -n -q -t 5 -c 5 %s > /dev/null\2')" \ -e "\$_.gsub"\!"(/()/, '\1/sbin/ping -n -q -t 5 -c 5 %s > /dev/null\2')" \ %{buildroot}%{_sysconfdir}/zonecheck/zc.conf ;; *) ruby -p -i \ -e "\$_.gsub"\!"(/()/, '\1/bin/ping -n -q -w 5 -c 5 %s > /dev/null\2')" \ -e "\$_.gsub"\!"(/()/, '\1/usr/sbin/ping6 -n -q -w 5 -c 5 %s > /dev/null\2')" \ %{buildroot}%{_sysconfdir}/zonecheck/zc.conf ;; esac %clean %{__rm} -rf %{buildroot} %files %defattr(-, root, root, 0755) %doc BUGS ChangeLog COPYING CREDITS GPL HISTORY README TODO %doc doc/html %dir %{_sysconfdir}/zonecheck %config %{_sysconfdir}/zonecheck/rootservers %config %{_sysconfdir}/zonecheck/*.profile %verify(not size,not md5) %config(noreplace) %{_sysconfdir}/zonecheck/zc.conf %{_bindir}/* %dir %{_libexecdir}/zonecheck %{_libexecdir}/zonecheck/zc %{_libexecdir}/zonecheck/lib %{_libexecdir}/zonecheck/locale %{_libexecdir}/zonecheck/test %{_mandir}/man1/* %files cgi %defattr(-, root, root, 0755) %{_libexecdir}/zonecheck/www %{_libexecdir}/zonecheck/cgi-bin %changelog * Wed Oct 29 2008 Eric Redon - 2.0.8 - Updated AFNIC Configuration profile. * Mon Nov 13 2003 Stephane D'Alu - 2.0.0b10 - Updated for new zone configuration profile. * Fri Oct 24 2003 Jean-Philippe Pick - 2.0.0b9 - Reworked packaging to meet new installation process. * Tue Sep 02 2003 Dag Wieers - 2.0.0-0.b7 - Initial package. (using DAR) zonecheck-3.0.5/contrib/presentations/000077500000000000000000000000001226210254100200215ustar00rootroot00000000000000zonecheck-3.0.5/contrib/presentations/OARC-2006/000077500000000000000000000000001226210254100211325ustar00rootroot00000000000000zonecheck-3.0.5/contrib/presentations/OARC-2006/zonecheck.tex000066400000000000000000000116531226210254100236330ustar00rootroot00000000000000\include{parameters} \usetheme{AFNIC} \usepackage[english]{babel} \usepackage[latin1]{inputenc} \usepackage[T1]{fontenc} \usepackage{bortzmeyer-utils} \title{Zonecheck, testing a DNS zone} \author{Stphane Bortzmeyer\\AFNIC ("\texttt{.fr}" registry)\\\texttt{bortzmeyer@nic.fr}} \date{16 november 2006} %\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex} % \setlength{\parskip}{15pt} \setlength{\parskip}{15pt plus 10pt minus 10pt} \begin{document} \maketitle \begin{frame} \titlepage \end{frame} \begin{frame}[fragile] Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License \url{http://www.gnu.org/licenses/licenses.html#FDL}, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. \end{frame} \begin{frame} \frametitle{Why test a DNS zone?} \begin{itemize} \item<2->To make sure it works, \item<3->To make sure it works fast (no timeouts or retransmissions). \end{itemize} \begin{block}<4>{It is not because ``it works'' that everything is perfect.}{See Ilya Sukhar's slides about the consequences of bad delegation.}\end{block} \end{frame} \begin{frame} \frametitle{The requirements} We started designing the new Zonecheck in 2002 (version 2, a program by the same name, but completely different, existed before). The requirements for the new version were: \begin{itemize} \item<2->Command-line (so it can be run everywhere) and Web tool, \item<3->Free software, \item<4->General tool, not a small ad-hoc hack, \item<5->Separated policy and engine (more on that later). \end{itemize} \end{frame} \begin{frame} \frametitle{The result} \begin{itemize} \item<2->Developed by Stphane d'Alu, \item<3->Written in Ruby, \item<4->Available under the GPL free licence, a very important point, since it allows people to run it at their site and to do the same tests as AFNIC does (administrators of zones under ``.fr'' are encouraged to run ZC before submitting their request for creation/modification), \item<5->Hosted at the hosting service Savannah, \item<6->Completely IPv4 and IPv6, \item<7->Used in daily production at AFNIC since. \end{itemize} \end{frame} \begin{frame} \frametitle{Engine, not policy} \begin{block}{Zonecheck is an engine, not a policy}{This is probably the main feature of Zonecheck: unlike all the other similar tools, the policy is not hardwired in the code.}\end{block} \only<2->{The code defines all the tests you \emph{can} run, the configuration file defines the subset of the tests that you \emph{do} run and their result (fatal error or just a warning).} \end{frame} \begin{frame}[fragile] \frametitle{Example of configuration} \begin{info} \end{info} \only<2->{A program can translate this configuration file to HTML, for the information of the users.} \end{frame} \begin{frame} \frametitle{Using it to check delegations from a registry} AFNIC uses Zonecheck \emph{prior} to every delegation. One fatal error and the domain is not created. (Every name server change triggers a Zonecheck, too.) \only<2-3>{The policy is quite strict. A few examples: \begin{itemize} \item TCP connectivity is mandatory, \item If the server is recursive, a lot of tests occur (such as whether the loopback address is delegated in in-addr.arpa). \end{itemize} } \only<3->{As a side effect, this creates a large number of support tickets (that may be used to measure the current skills level of some registrars :-) and (without smiley) the current level of competence of many DNS administrators} \only<4->{But it makes a much better zone and strongly diminishes the post-registration complaints of the type ``My site does not work''.} \end{frame} \begin{frame} \frametitle{Lessons for IANA checks} Context: IANA asks for comments about delegation checks (\url{http://www.icann.org/announcements/announcement-18aug06.htm}). [Generally speaking, the quality of DNS delegation is a very common issue today.] \only<2->{Many registries (CENTR, ccNSO) asked that such tests must be clearly described, and executed in a predictable way. An automatic tool, such as Zonecheck, fulfills these requirements.} \only<3->{Remember that using Zonecheck does not mean using AFNIC policy.} \end{frame} \begin{frame} \frametitle{Future tests?} \begin{itemize} \item DNSsec tests (see Eric Osterweil's slides) \item ``OR'' tests: ``at least M among N nameservers'', ``TCP or EDNS0'', \ldots \end{itemize} \end{frame} \begin{frame} \frametitle{Other users} \begin{itemize} \item \url{.de} \item \url{.ch} \item \url{.no} \end{itemize} \begin{block}<2->{Tomorrow, you?}{\url{http://www.zonecheck.fr/}}\end{block} \end{frame} \end{document} zonecheck-3.0.5/doc/000077500000000000000000000000001226210254100142305ustar00rootroot00000000000000zonecheck-3.0.5/doc/html/000077500000000000000000000000001226210254100151745ustar00rootroot00000000000000zonecheck-3.0.5/doc/html/FAQ.html000066400000000000000000000157261226210254100165040ustar00rootroot00000000000000

FAQ

1. Where can I find documentation about Ruby?
2. I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses...
3. I want to use an interface other than the CLI.
4. The -d lvl option doesn't display earlier debugging messages
5. I would like to easily test ZoneCheck without doing a full installation...
6. Why do I get rubbish or wrong results when doing the icmp test?
7. Why did I get strange characters when using a locale other than US/English?
8. ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server...
9. ZoneCheck crashes when reading configuration files or the message catalog
1.

Where can I find documentation about Ruby?

Try the offical Ruby website: http://www.ruby-lang.org/

2.

I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses...

ZoneCheck only looks for an enabled IPv6 stack to authorize the use of IPv6 addresses. It would be a good idea to disable the IPv6 stack on your computer if you don't have the connectivity or you can use the -4 option to force IPv4 only connectivity.

3.

I want to use an interface other than the CLI.

Use the environment variable ZC_INPUT set to your input mode, or use the command line option --INPUT=im. The input modes currently supported are CLI, CGI, and inetd

4.

The -d lvl option doesn't display earlier debugging messages

Some debugging messages are sent before the debugging level is initialised by the command line, in this case use the environment variable ZC_DEBUG set to the desired level. But keep in mind that ZC_DEBUG will be overriden by the -d lvl option.

5.

I would like to easily test ZoneCheck without doing a full installation...

You can define the environment variable ZC_INSTALL_PATH to the initial ZoneCheck directory.

6.

Why do I get rubbish or wrong results when doing the icmp test?

ZoneCheck uses the command ping to perform this test, so you should set the constants ping4 and ping6 in the configuration file so that the ping is correctly invoked: stop after 5 echo requests, doesn't output messages, and return an exit code of 0 in case of success.

If you are using ZoneCheck on the Windows platform, you better remove the test.

7.

Why did I get strange characters when using a locale other than US/English?

The default encoding is UTF-8, either you can configure your terminal to use UTF-8, or you can specify the desired encoding after the locale by using a dot as separator (ex: LANG=fr.latin1); in the last case the ruby-iconv package should have been installed.

8.

ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server...

Unfortunately, by default, djbdns/tinydns does not listen on TCP. See http://cr.yp.to/djbdns/tcp.html to enable it.

9.

ZoneCheck crashes when reading configuration files or the message catalog

REXML is used to parse the XML files, but it only checks for well formed XML and doesn't perform validation against the DTD, so when you edit the configuration file or the message catalog you should ensure that the files are valid, for that purpose you can use xmllint for example.

zonecheck-3.0.5/doc/html/apa.html000066400000000000000000000012651226210254100166270ustar00rootroot00000000000000AppendixA.Implemented tests

AppendixA.Implemented tests

toto

zonecheck-3.0.5/doc/html/ch01.html000066400000000000000000000040321226210254100166140ustar00rootroot00000000000000Chapter1.Installation

Chapter1.Installation

Requirement

zonecheck-3.0.5/doc/html/ch01s02.html000066400000000000000000000032021226210254100171370ustar00rootroot00000000000000Directory layout

Directory layout

PREFIX
|-- bin
|   `-- zonecheck		# Command line
|-- etc
|   `-- zonecheck		# Configuration directory
|      |-- zc.conf		#   Main configuration file
|      |-- rootservers		#   List of the root servers (YAML file)
|      |-- reverse.profile	#   Profile for checking reverse delegation
|      |-- ...			#   ...
|      `-- default.profile	#   Default set of rules to be used
|-- libexec
|   `--zonecheck
|      |-- cgi-bin
|      |   `-- zc.cgi		# CGI
|      |-- html			# HTML directory (javascript, css, pics, ...)
|      |   |-- en		#   English version
|      |   |-- ...              #   ...
|      |   `-- fr		#   French version
|      |-- locale		# Localisation files
|      |-- test			# test set
|      |-- lib			# Extra libraries (Whois)
|      `-- zc			# core component
`-- share
    `-- doc
        `-- zonecheck		# Documentation
zonecheck-3.0.5/doc/html/ch01s03.html000066400000000000000000000036271226210254100171530ustar00rootroot00000000000000CGI

CGI

Here is an exemple of Apache2 configuration file, assuming ZoneCheck has been installed in /usr/local (PREFIX=/usr/local) and for html pages generated in the /zc/ namespace (HTML_PATH=/zc).

AliasMatch  ^/zonecheck/?$         /usr/local/libexec/zonecheck/www/html/form.html
AliasMatch  ^/zonecheck/(en|fr)/?$ /usr/local/libexec/zonecheck/www/html/form.html.$1
AliasMatch  ^/zonecheck/(en|fr)/(.*)$ /usr/local/libexec/zonecheck/www/html/$2.$1
ScriptAlias /zonecheck/cgi-bin/    /usr/local/libexec/zonecheck/cgi-bin/
Alias       /zonecheck/js/         /usr/local/libexec/zonecheck/www/js/
Alias       /zonecheck/style/      /usr/local/libexec/zonecheck/www/style/
Alias       /zonecheck/img/        /usr/local/libexec/zonecheck/www/img/
Alias       /zonecheck/            /usr/local/libexec/zonecheck/www/html/

<Directory /usr/local/libexec/zonecheck/cgi-bin/>
    Options ExecCGI 
</Directory>

<Directory /usr/local/libexec/zonecheck/www/>
    Options Includes FollowSymLinks MultiViews
</Directory>

zonecheck-3.0.5/doc/html/ch01s04.html000066400000000000000000000027351226210254100171530ustar00rootroot00000000000000inetd

inetd

First you need to edit the file /etc/services, which contains information regarding the known services available in the Internet to add the following line:

zonecheck       1904/tcp  # ZoneCheck service

You also need to configure inetd, so that it is listening for the new zonecheck service, this is done by adding the line:

zonecheck stream tcp nowait root /usr/local/bin/zonecheck zonecheck --INPUT=inetd

If you have an IPv6 stack installed but don't have the connectivity with the outside world add the option -4 to the zonecheck command.

zonecheck-3.0.5/doc/html/ch02.html000066400000000000000000000111741226210254100166220ustar00rootroot00000000000000Chapter2.Configuration

Chapter2.Configuration

sections

A section declaration follow the rules:

     section  : name argument '{' commands '}' ';'
     name     : symbol
     argument : (string)?
     commands : (section_specific_command ';')*
     symbol   : [a-zA-Z0-9_]+
     string   : "([^\\\"]|\\[\\\"])*"

config

     section_specific_command : option_selection
     option_selection         : symbol '=' string

config {
    transp   = "ipv4,ipv6,std";
    output   = "straight,text";
    verbose  = "explain,details,intro,counter";
    error    = "standard";
    resolver = "127.0.0.1";
};

constant

toto

     section_specific_command : affectation
     affectation              : symbol '=' string

constant {
    # For connectivity testing
    #  the '%s' will be replaced by the IP address
    ping4                 = "ping  -q -c 5 %s > /dev/null";
    ping6                 = "ping6 -q -c 5 %s > /dev/null";

    # HTML path for generated pages
    publish_html_path     = "/zc/";
};

useconf

toto

     section_specific_command : domain_mapping
     domain_mapping           : 'map' domainname filename
     domainname               : string
     filename                 : string

useconf {
    map "fr."         "zc.conf.fr";
    map "arpa."       "zc.conf.arpa";
    map "."           "zc.conf.root";
};

testseq

toto

     commands                 : block
     block                    : (check ';' | switch)*
     check                    : checkname  severity  category
     switch                   : 'case' testname ('when' symbol block)+ 
                                                ('else' block)? 'end'
     testname                 : symbol    # with prefix 'tst_'
     checkname                : symbol    # with prefix 'chk_'
     severity                 : 'f' | 'w' | 'i'

testseq "address" {
    chk_given_ip			f	dns;
    chk_given_nsprim_vs_soa		f	dns;
    case tst_mail_by_mx_or_a
    when MX
        # MX
	chk_mx				f	dns;
	chk_mx_auth			f	dns;
	chk_mx_sntx			f	dns;
    end
};

zonecheck-3.0.5/doc/html/ch02s02.html000066400000000000000000000014651226210254100171510ustar00rootroot00000000000000zonecheck configuration (zc.conf)

zonecheck configuration (zc.conf)

toto

zonecheck-3.0.5/doc/html/ch02s03.html000066400000000000000000000014411226210254100171440ustar00rootroot00000000000000zone specific configuration

zone specific configuration

toto

zonecheck-3.0.5/doc/html/ch03.html000066400000000000000000000015671226210254100166300ustar00rootroot00000000000000Chapter3.Overview

Chapter3.Overview

information warning fatal error

test description error message detailed error explanation referer

zonecheck-3.0.5/doc/html/ch04.html000066400000000000000000000013501226210254100166170ustar00rootroot00000000000000Chapter4.Internal

Chapter4.Internal

toto

zonecheck-3.0.5/doc/html/ch05.html000066400000000000000000000201021226210254100166140ustar00rootroot00000000000000Chapter5.Using ZoneCheck

Chapter5.Using ZoneCheck

Input

Command Line Interface (CLI)

  • --lang

    Select another language (en, fr, ...). The syntax is the same as for the environment variable LANG.

  • -d lvl, --debug lvl

    Select the debugging messages to print or activate debugging code. This parameter will override the value of the environment variable ZC_DEBUG.

    The available options are:

    CodeDescription
    0x0001Initialisation
    0x0002Localization / Internationalisation
    0x0004Configuration
    0x0008Autoconf
    0x0010Loading tests
    0x0020Tests performed
    0x0040Debugging messages from tests
    0x0400Information about cached object
    0x0800Debugger itself
    0x1000Crazy Debug, don't try this at home!
    0x2000Dnsruby library debugging messages
    0x4000Disable caching
    0x8000Don't try to rescue exceptions

  • -h, --help

    Show a short description of the different options available in ZoneCheck

  • -V, --version

    print the ZoneCheck version and exit

  • -q, --quiet

    don't display extra titles

  • -c cfgfile, --config cfgfile

    specify the location of the configuration file (default is etc/zonecheck/zc.conf)

  • --testdir directory

    specify the directory where all the tests are located

  • -C catlist, --category catlist

    limit the test to the specified category list (catlist); the list is comma separeted and we stop on the first match. If the category start with - or ! the test should not belong to that category, if it starts with nothing or + the test should belong to it. It is possible to have subcategories which are delimited by :. Here is an example that says don't perform DNS tests that are not SOA related: dns:soa,!dns,+

  • -T testname, --test testname

    only the test testname will be performed and its severity will default to fatal

  • -r host, --resolver host

    the nameserver running on host will be used as the local resolver instead of taking this information from /etc/resolv.conf

  • -n nameservers, --ns nameservers

    nameservers is the exhaustive list of nameservers that are primary or secondary for the zone, they are separated by a semicolon, if IP addresses should be specified the hostname must be followed by the equal sign and a coma separated list of IP addresses. For example: ns1.toto.fr=192.168.1.5,192.168.1.6;ns2.toto.fr

  • -1, --one

    only display the most relevant message

  • -g, --tagonly

    display tag instead of sentences, this option should be used when writing scripts

  • -e list, --error list

  • -t list, --transp list

    list

  • -v list, --verbose list

    list

  • -o list, --output list

    list

  • -4, --ipv4

    use IPv4 connectivity only

  • -6, --ipv6

    use IPv6 connectivity only

  • --testlist

    list all the available tests

  • --testdesc type

    types is one of the keyword name expl error

% zc -4 -v c,x,d,i afnic.fr
ZONE  : afnic.fr.
NS <= : ns1.nic.fr. [192.93.0.1]
NS    : ns2.nic.fr. [192.93.0.4]
NS    : ns3.nic.fr. [192.134.0.49, 2001:660:1180:1:192:134::49]

==> SUCCED

Common Gateway Interface (CGI)

  • lang = [ fr | en | ... ]

  • quiet

  • - one\n

  • - verbose = [ i|intro, n|testname, x|explain, d|details,\n\ t|testdesc, c|counter, o|reportok ]\n\

    • - intro\n\

    • - testname\n\

    • - explain\n\

    • - details\n\

    • - progress = [ t|testdesc | c|counter ]\n\

    • - reportok\n\

  • - output = [ bs|byseverity, bh|byhost, t|text, h|html ]\n\ - report = bs|byseverity | bh|byhost\n\ - format = h|html | text\n\

  • - error = [ af|allfatal, aw|allwarning, std|standard,\n\ s|stop, ns|nostop ]\n\ - errorlvl = [ af|allfatal | aw|allwarning | std|standard ]\n\ - dontstop \n\

  • - transp = [ ipv4, ipv6, udp, tcp, std ]\n\ - transp3 = [ ipv4, ipv6 ]\n\ - transp4 = [ udp | tcp | std ]\n\

  • - category = cat1,!cat2:subcat1,cat2,!cat3,+\n\ - chkmail (!mail)\n\ - chkrir (!rir)\n\ - chkzone (!dns:axfr)\n\

  • - ns = ns1=ip1,ip2;ns2=ip3;ns3\n\ (WARNING: in URL '%3b' should be used instead of ';')\n\ - ns0 .. nsX = nameserver name\n\ - ips0 .. ipsX = coma separated ip addresses\n\

  • - zone = zone to test\n\

zonecheck-3.0.5/doc/html/ch05s02.html000066400000000000000000000017651226210254100171570ustar00rootroot00000000000000Output

Output

Text

toto

HTML

toto

zonecheck-3.0.5/doc/html/ch06.html000066400000000000000000000162171226210254100166310ustar00rootroot00000000000000Chapter6.FAQ

Chapter6.FAQ

6.1. Where can I find documentation about Ruby?
6.2. I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses...
6.3. I want to use an interface other than the CLI.
6.4. The -d lvl option doesn't display earlier debugging messages
6.5. I would like to easily test ZoneCheck without doing a full installation...
6.6. Why do I get rubbish or wrong results when doing the icmp test?
6.7. Why did I get strange characters when using a locale other than US/English?
6.8. ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server...
6.9. ZoneCheck crashes when reading configuration files or the message catalog
6.1.

Where can I find documentation about Ruby?

Try the offical Ruby website: http://www.ruby-lang.org/

6.2.

I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses...

ZoneCheck only looks for an enabled IPv6 stack to authorize the use of IPv6 addresses. It would be a good idea to disable the IPv6 stack on your computer if you don't have the connectivity or you can use the -4 option to force IPv4 only connectivity.

6.3.

I want to use an interface other than the CLI.

Use the environment variable ZC_INPUT set to your input mode, or use the command line option --INPUT=im. The input modes currently supported are CLI, CGI, and inetd

6.4.

The -d lvl option doesn't display earlier debugging messages

Some debugging messages are sent before the debugging level is initialised by the command line, in this case use the environment variable ZC_DEBUG set to the desired level. But keep in mind that ZC_DEBUG will be overriden by the -d lvl option.

6.5.

I would like to easily test ZoneCheck without doing a full installation...

You can define the environment variable ZC_INSTALL_PATH to the initial ZoneCheck directory.

6.6.

Why do I get rubbish or wrong results when doing the icmp test?

ZoneCheck uses the command ping to perform this test, so you should set the constants ping4 and ping6 in the configuration file so that the ping is correctly invoked: stop after 5 echo requests, doesn't output messages, and return an exit code of 0 in case of success.

If you are using ZoneCheck on the Windows platform, you better remove the test.

6.7.

Why did I get strange characters when using a locale other than US/English?

The default encoding is UTF-8, either you can configure your terminal to use UTF-8, or you can specify the desired encoding after the locale by using a dot as separator (ex: LANG=fr.latin1); in the last case the ruby-iconv package should have been installed.

6.8.

ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server...

Unfortunately, by default, djbdns/tinydns does not listen on TCP. See http://cr.yp.to/djbdns/tcp.html to enable it.

6.9.

ZoneCheck crashes when reading configuration files or the message catalog

REXML is used to parse the XML files, but it only checks for well formed XML and doesn't perform validation against the DTD, so when you edit the configuration file or the message catalog you should ensure that the files are valid, for that purpose you can use xmllint for example.

zonecheck-3.0.5/doc/html/ch07.html000066400000000000000000000021301226210254100166170ustar00rootroot00000000000000Chapter7.Writing tests

Chapter7.Writing tests

Available methods

titi

zonecheck-3.0.5/doc/html/ch07s02.html000066400000000000000000000013551226210254100171540ustar00rootroot00000000000000Framework

Framework

titi

zonecheck-3.0.5/doc/html/ch07s03.html000066400000000000000000000026221226210254100171530ustar00rootroot00000000000000Localisation

Localisation

The format of the message catalog is as follow:

 line       : '#' comment              # a comment
            | tag ':' definition       # a tag definition
            | tag '=' tag              # a link to another tag
            | '[' prefix ']'           # a prefix to append to other tags

 prefix     : tag                      # the tag to use as prefix
            | '*'                      # don't use a prefix

 definition : string                   # a string
            | string '\' definition    # with posibility of continuation '\'

 tag        : [a-zA-Z0-9_]+

zonecheck-3.0.5/doc/html/ch08.html000066400000000000000000000023641226210254100166310ustar00rootroot00000000000000Chapter8.About this book

Chapter8.About this book

This book was hard work if you look at the history and momentum behind the LDP and DocBook and SGML and XML and....and....and...

Copyrights and Trademarks

Copyright 2001 Foo Bar

zonecheck-3.0.5/doc/html/ch08s02.html000066400000000000000000000014741226210254100171570ustar00rootroot00000000000000Purpose/Scope

Purpose/Scope

This guide is tightly scoped with one purpose; to process.

zonecheck-3.0.5/doc/html/index-toc.html000066400000000000000000000051271226210254100177610ustar00rootroot00000000000000ZoneCheck II

ZoneCheck II

zonecheck-3.0.5/doc/html/index.html000066400000000000000000000033501226210254100171720ustar00rootroot00000000000000ZoneCheck II

ZoneCheck II

Stephane D'Alu

$Name: ZC-3_0_4 $

This legal mumbo jumbo will stop evil.

Abstract

The DNS is a critical resource for every network application, quite important to ensure that a zone or domain name is correctly configured in the DNS. ZoneCheck is intended to help solving misconfigurations or inconsistencies usually revealed by an increase in the latency of the application, up to the output of unexpected/inconsistant results.


zonecheck-3.0.5/doc/input.txt000066400000000000000000000007251226210254100161340ustar00rootroot00000000000000# $Id: input.txt,v 1.2 2010/06/01 15:36:07 chabannf Exp $ CGI: lang quiet one verbose intro explain progress [ | counter | testdesc ] output format [ html | text ] error errorlvl [ | allfatal | allwarning ] errorstop [ stop | nostop ] transp transp3 [ ipv4 / ipv6 ] transp4 [ udp | tcp | std ] category chkmail chkwhois chkzone ns ns0..ns7, ips0..ips7 zone zonecheck-3.0.5/doc/misc/000077500000000000000000000000001226210254100151635ustar00rootroot00000000000000zonecheck-3.0.5/doc/misc/catalog.xml000066400000000000000000000010161226210254100173150ustar00rootroot00000000000000 zonecheck-3.0.5/doc/misc/docbook.css000066400000000000000000000056231226210254100173230ustar00rootroot00000000000000/* * Copyright (c) 2001 The FreeBSD Documentation Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: doc/share/misc/docbook.css,v 1.4 2001/07/11 12:46:50 nik Exp $ */ BODY ADDRESS { line-height: 1.3; margin: .6em 0; } BODY BLOCKQUOTE { margin-top: .75em; line-height: 1.5; margin-bottom: .75em; } HTML BODY { margin: 1em 8% 1em 10%; line-height: 1.2; } .LEGALNOTICE { font-size: small; font-variant: small-caps; } BODY DIV { margin: 0; } DL { margin: .8em 0; line-height: 1.2; } BODY FORM { margin: .6em 0; } H1, H2, H3, H4, H5, H6, DIV.EXAMPLE P B, .QUESTION, DIV.TABLE P B, DIV.PROCEDURE P B { color: #990000; } BODY H1 { margin: .8em 0 0 -4%; line-height: 1.3; } BODY H2 { margin: .8em 0 0 -4%; line-height: 1.3; } BODY H3 { margin: .8em 0 0 -3%; line-height: 1.3; } BODY H4 { margin: .8em 0 0 -3%; line-height: 1.3; } BODY H5 { margin: .8em 0 0 -2%; line-height: 1.3; } BODY H6 { margin: .8em 0 0 -1%; line-height: 1.3; } BODY HR { margin: .6em } BODY IMG.NAVHEADER { margin: 0 0 0 -4%; } OL { margin: 0 0 0 5%; line-height: 1.2; } BODY P { margin: .6em 0; line-height: 1.2; } BODY PRE { margin: .75em 0; line-height: 1.0; color: #461b7e; } BODY TD { line-height: 1.2 } BODY TH { line-height: 1.2; } UL, BODY DIR, BODY MENU { margin: 0 0 0 5%; line-height: 1.2; } HTML { margin: 0; padding: 0; } .FILENAME { color: #007a00; } BODY H1, BODY H2, BODY H3, BODY H4, BODY H5, BODY H6 { margin-left: 0 } .GUIMENU, .GUIMENUITEM, .GUISUBMENU, .GUILABEL, .INTERFACE, .GUIBUTTON, .SHORTCUT, .SHORTCUT .KEYCAP { background-color: #F0F0F0; } .ACCEL { background-color: #F0F0F0; text-decoration: underline; } zonecheck-3.0.5/doc/misc/html.xsl000066400000000000000000000010761226210254100166630ustar00rootroot00000000000000 zonecheck-3.0.5/doc/misc/paper.xsl000066400000000000000000000004741226210254100170270ustar00rootroot00000000000000 zonecheck-3.0.5/doc/pics/000077500000000000000000000000001226210254100151665ustar00rootroot00000000000000zonecheck-3.0.5/doc/pics/gtk_expert.png000066400000000000000000000334421226210254100200560ustar00rootroot00000000000000PNG  IHDRH%kgAMA aMtEXtSoftwareXV Version 3.10a Rev: 12/29/94 (jp-extension 5.3.3 + PNG patch 1.2d){0 IDATxmyjJ⸲ߘ A/HA 1$v@4b!]oV)Nd'` 1X'!G&*c2b "ɚFMp9z۷ =3ӏ>O:9 ejWh&[]jnvG\,j P+˝<-SHr7ܷu;E)9cBJr# #6Hq [9CC]@E\}ՀSr-v`^z,Nd9Ћ׊pC^nՁrW ,>KlߞP3/=]"[-VTdƨzs". xkJi3{ NadW*Qt͞{K-3,-<z,b3̿ Jm!YF5=2>27e'-M/'+ ȶ-ه"?h2~zؖH3e9cK<[&n\32p1*CTBM]-nw!|wkrlZ8c6_?kS闍4_C i4"'MRg J DT`^@Q@RAH^ȹ&km%'ldd[VO^u_!JIctakVQPH "Ґj(WQJ5RD5$P%@ͺLE©So_8uzSoy{y7?o^ ?{;Oz}~|Ӎ7_zԛS?_}_w7׿ƛvo[o;?8/ȿ߻>3@59|dJo{`ddx~~^D/T3slNeSs36iugOp'R-fÛȗ"SoBuۍFC34-J$WJJZӏ$RIi,mEOMDΝ{Px@^kac;}fN= u4W*b8k= U5NIͦnf3 g&B_G)iPz0+,Xئؽy=_g QҐeJoLnME@ y(S)(%G`@)'*[?H~SvE梽 =Ǧ]댭ղRJe iSSͦ glˤ56M~.[|?o:m6G7iyIClZd-0,ݿXg>e ? džf=ݹW~'Jç?큯M .䒩$S«u?^t1glz9cv֝W/wnCrlgc-=wH.291~R7y饗ȱ/'6n\VMdn.('&"*-f96KQ9իck偲D^3-꫗^zU˭f#rl"rew8q-ȱqۍ"'tmm77m顇sWoLm6x_H?[£wI RT}l.4_~[nׯ76mWꪫ*ꫳlg~g~9e]w3k׮/׭[gݰaW\q+͛+֖-[~Λ+}B% wn7>ҺMj?W"Ӭ{{zsWDT?-P{9oо^yIǶu֝8qBgp9|p NNN /,"NMݫ^z_76o<66 /zEd˖-?Ç>|5$>cН7߹mx?xM[oɔ}􉭷("wvG.\N _{q<x_£} 9slOL嗎_asiãG_:77/J^ܼyTDd>Sc3sMDΞ=_tl"b:9wnɱ؋sQ Gr󭛞?d~^)>|ꫯou`˖V:k(c7/Y9>09~w7<f^_7d5+P@D˱Z'Vjm>bEXw-_:#\ާWJg4$96K>wB‘cggK/W^)A-n"Gzb7S7Gc9MmݺucG_%7_!"&ǶiӦADlR6i\a$6lp䅣UWm^u5\}af̱myc|?|gr:v{y5ҷ#slVg&`tĉcǎGݴi^x+oYȑ#CH)|}䤹8sbbB5>>/F۱c6lpՕ;96]r萾99NwE}vo796@m"w^9%|Πb_ =zT. i\E_;>>_^ˆkߠ{hh:)"?|v ]]wE@zEG5!?mnnee>MΥwxxʱYyu‚RJ-~a][eRf0%noZrTNT1L?Fꧮh&v ?eVXZͽ֛Ͻ<|O[['ضڃ÷|kG?/'/~IsO;v~n⦅}jgv>{>@'965ʱ5ω122ܭM?k֬[51w\5RJ  }>.gl j(}bZ-\z#GD>%MLC$\<222\N*i_/c@: ּ-O[JKMT2N`'}EsVb SEl?5M|l&W(|ER=i6 <"Oy,uS"oKSCSlYβ"YlO=y{FGGgff$GBsΧO߿{`)}*此籍=ǔ g;)fTK䔝ӜL3WlPs"e` 'Ն:] YV a=M_b/ IW MKi"oV Gcki3@GRv *;@G1 6@c 96@0 6@cJOؚͦy_ӅNK;>fuFF j%wpY*r!{؆oPJA<͛;0*3bFyN9cKDZ gCt)2oӍ:$Gl6P1FY#wo>3n*qtB;}gv}Bt#=#ǶzrH%&Bf) d3 3DPt$+1b I5͵TqFK32BD/ߙp V4!Ċoyb[C!rnj4fy+;JIܷSh^ƕ;Sm: ;# S Sv)S9Ǚ;yVs>=)%pF$m;6 i RHĥxBW\f+8z|r&hN3۟((5x3Wg+VA! ?$LJZ؂ $n-ső}Re_cee 'U}|g콖'qbG zG*X4ݺ ȉi>!ShW_Fw4g!Gk6c\S3<gCqǵj8Ec~::ڑc{Ϧ64l,m"b}eddxll]At4fɢb 3(}l||u4f:70uQ!1\xVzylc` 96@c SZa` 96@ lOKpZIJ-sG<=bi1(wEF#qY D P>CQ^A Ebi!blkV/w>qi !%1Tvp,r#A>堣 P+Sg̩Xb2'AF =Dՙdpbɜ!džbeȱYΔAih1dN̐cC VȱϦx.!džd1C *>ǶvS+֮]+"6n`96bdrl(Vէ"2WDOZ=ETC1$G^>*u8EJ 9}ئt5{ܼ^0̄^l^}ڵN$";+ǶiӢb;$ N윍?vy'ᄎ3P96׮]kϡ\' *$ɒuӠ]Ȟciv0H !$Vx[rl訶"1"`% R[X_ɨԐB7FVz\| z7٧Y?&V.M3/B8THh!ЙO^=5c ;rl&e=e/B9cVl/͂<\! 0 霴UFf. slMŹC(c9:'{̐cCʱ/Je& r_9Zȱwʏ1rh⑄& <9=M_:w0 rv}qGܞJ pf9c Ix^6e+5/r~n9TM9rl:cyKbBȩ ֮ -|1C *2dž)G( ȱ]@iK\[5>>^pC\nĉvOm@rlsV$L%%B21dN̐cCU+ŸS1dN̐cCÓ=,rAp3231=I~\o KZE !džbeȱZ?nAxfےЋŸ$sbqS4F S訜0Tb1(}`{ 1/PmݥԓJ6::Zf?(D633Sf?(DƬ7l w4FS+:=ylfj0sbx;]+'@v}20' e*&&]dNs*u*eӒ {=WT$96z96@0 36P>rl(ގ;jKɱ!Gw jhJZVB P+YslHmkdd8\k׮{'G"Z6(7( PQ|flllgffqUaCyFu_93sJ)QJ(T(!0\?Wߔ|rdy\Vn]_LPֵ]v9%z[ }vz(}lV->Uk{h͊]vΝ;E{$Vdy\席 ~܆: [[|%΄;.ۄ1+"A=a@1NΝ;Bd帖Xuwڥ.s=z 3,waT.x$nHʴMYGߖ#'{'C@eǨ]c=;Z6c W+i*}V$ H\pYywݭ'Yj z9nq#ǶrE5 ׏lǩ.7}f/Bɼ'we'zg#*cvSY~G@slALrs}9ʾ2ǵ+=' @׵uזUqv^Ξr 7%cӠ2yȱ=R t*Nq&OfBlԭm~*/kmddxll,Ld^ʮYn^o%\,[wdDd?{ ؀V#dÌt v뭷mVȱjrlZ!"}l(ؾ}UlYɱx;vvTRv{ Y VRJ$O qnw@/h AfIS.F/6@%j W96@'93LFM) PJIíljck6ydo;5^Hk:d͚s hDud*ruFFÅ$8 dc!n2T)u3ccc7o\_Hc;}9 0+4.d4͉)D3v. aIDATnidhp`briJ48 ޯeÔ瞖k9G";fTg6mLmGp҆:qrl_Wjw*Ƕz3A.T_Df YLOO;+A\.-: 0^+㨖H9VrquRWL @F5ԉc۾}={v)"sly-f-ifhq=\˽+ Ҙñ>@  0%4kܢoR7H%宻rJ/{cL̦S1,Y^%]4(yFK)|cW[sF5ʱY;IB'e25;wSn^&OLNeiݕ} 3uʼn=^||ʱ\ʱ/\?䴖>u3u*;q#/Zy.2he HڿU) J|#"2>>by+_f;rR+4s3? gƌg?HS`ˑլb;ӉETYBzK)uĉp+p=A^Y8fRNdZ>9JfWOs77؎j aT d?j"rȔ~}ߞr<._VRk;ؔRJ.?ߠ ܾiO=y`ǎ<@+xkw-zZ<,f%?sA07::{;v&^9glj+~g>ɫx'`)Xͱٗn8K:ȑᱱ1~W o ( nY|c̗q[$CZ/j$o`܅sctQQg>v˗iDI7h92ޞ~{j [gff `ۗ.96@cԊWjP} lZIܽ{wihWlz96@Ğ`_f|?)v`Of8@iOE@cmZtʝ vnT9B鴡fiRkf.w:}fnAj|S%Wԓ訾?2[f >K.w/5O}*此o1hg333*%|m[=yQ3q)Fz.'m-nN^%{!٥ l;L<=L]]nW6Fc`KMEV0#YBeb /QΝp%oP~9ӏ櫖9{c43@xV*c}ʱ>"IوNQ  3w6=-km5Eddd86v*L'ZC3k6GMmxT*όm޼s}ո׭T$fC*3gzm[r< Oa(S1%+rL^+!f˸@Jm /fRCBq'زyR:qW7EeC(Y91"[ŌdP!lzG駿\fWZz%fPU'(kmddxll,*>{Mt bQxҋ<"{;衘AET0f8? 2y@1 6@c 96@0 6@c 96@dn3b3<+<yx𣒌L':((8SZc;}y_kAly 99rL@"{]9Ǚ℀ UN# g}>.OM]n7eϽ.+G748`Vnd q"Cg$`Nq[I HrgN)LXQug2ÏS?w]t]9DƏÑwI8&8X~Z ELDQuD@] 43X x؆o|Xv3dz|3wjގ^m39E6Ҟlk)b̴c)1mz]/LeYَcU<6'Ly/Ӕ'˝ϭ]ͮZnoQWo-cGiڏY…YʳT+QEYY*cx lkq]務=u)' A׊u|hplIjl;->3e-r^ڏv_\yd%Āt)܈y`;&V|&tٖ[Ōǻo(Gmʾ9oAa>TWӲ~YH')$fIܭ-d[je{A7 ErrGx)8`![G"#C-y }^3@e;V3;-$xsl$JV`8INjj@Q] ~ɧV{9ٳs38N%T-(ČI6In5}c Kr [Fx/v37#ǶrE( o Wy:NhY?{a-2!ƌLʆ+G~oŕ*nݸ,xU c&`pmǖe-SKrJ呍di9!njǀnZx `og/|TcU2ȱ=m#z wRSˉ)$f" )ɛk$qx-g\L;{oJIR)K'D;SCɩ6#{,"3Cq LLN-G/q;~Bc[//_~d#Kfe9+*f…vMb++Jvwd:'TduC'r!E)$fvG d\S|.j{` 򶤄k4Rˋb : VY+6~ȱ=w^$T8䴆¹.2cmbr*! ׌k߬+G<k?f#_{< _94Hc s2PXnD>OCBVw3 ݻwz""0}ؚ{ WģtY*лP!wEb<)ss<`Qu%mbrl%eroCSJ\‰).Vt޵;\?23KwM3s[+wN̯r*_-A&,9*jlQ _:v`ObWbO5M;9P!a-ԉ, u3~m;fg\8^ŕ?x3M,οv^ȍ\ffFDd֭Yck$PbWWL7Np~f,,^ס4M]'{YvPB `zY?u7𨖐fKxĜceD+ѡZ+{^^*8Ia\Q̀f"QM6;#S'+10rr 6dөҽO!3λpOwq¦S{YI 8%!%4'fͱO-͜UDuZ 9>ggj§˫5Fnd˱q=w_`^rCܹڢK"}sld,DN H\;Rg3{~z5ƌpfΫWYzZ!9*i$K@%jq+p"\!uܛ nCC~&ԷO4Zƿyk촖ؖoGnpIK߷Q74EGrӯ;vd ىwgJ,y,\M4[c}ޣZ3z`zz[o%4krۉؔR7qFGGly-p)lج'fuߞ߳*NJE&\<6@,[͆mqd-QQE StIME 6|;,IENDB`zonecheck-3.0.5/doc/pics/gtk_input.png000066400000000000000000000353001226210254100177010ustar00rootroot00000000000000PNG  IHDRH%kgAMA aMtEXtSoftwareXV Version 3.10a Rev: 12/29/94 (jp-extension 5.3.3 + PNG patch 1.2d){0 IDATx{W}_kыDb 3Hd[9@{B[`VV K6$lr $'{O> 氎 ;lM؜ؒl=FbF3^H~T?U^}O̤֭[^:> s]<|z\F%/q]zi߁EsŢK`'B8cd  S^nO![}'ep`q R@fhЛ;pIb&cwu5CC]@a@ 嶻JG؁w\GLQkŸ˺ _@ww`↭%b6oO ajȘpo8t;Y2#ƶXIS c-0W8ήeڗH*(ո-;,-<=AC0.r&f 2i߁ _}=i/Emb?T,~8I[BMF5d$ j56"xfsƖxMȸψ!LLQ 9u&"56?S"%@'X9P+OJBȤQmeX{`3llƶ}&>q]=Q,2D6t5S/X7j\<Ӽ롁 _#!e!jnjNQM"vܜj@JoR% $@*QKIl?!6~+Yycd*H/mAE2*񩴅' $|?rJgӦMx$c/YfMk@#L=c+8VV\zLE2=[>o~-Pߨm16bxyi c#Pߐ!ݏ I}899) gz1ˑĄ <'cMddclzze]ut3LḦ 1G -OUp@nߐ!u͟ذf~]'푿a%G~ndJ?=r9ϏO™ft ȀPR_sȰLM^NȀPY‘_blmn Ȍ?!*g1cctEd  Sb"zۦMZ\"b`_Z_OŇ[@w(>@ )1׾/Y~yHNr9?I.u"zSJ) "LןxWWDx/)YVnI_-'9%J-yy^7y>*))OٚyM^җH\y|/>TV竘Eҿ2_2o)9YlxDymǎ[Mkv,֬X]g]!L"Uum_ڣ"ˉ5%%9QQVOLzy<QUB Mb8>#"#m"Rp*7?-/EuR\Qˉ Dr"J.?'9ckѝn~f{.6n8::v'8q5{"Ʀc1W*9zߕW^)"GFc۲嚃D*U1^H6)v7<tb.'w;~۾Ϳ}cltLz3{P,bl"¡瞻+W,|\MDt,ѣ\4Tlbls#G-&wǻC{ΏDwşk_+_F\C"b"cl+,s]uUzꫯ:|lذAܸqvӦM7o޲e͛M^+"]w_m۶nnHJWUWrƍ7nkznٲEWOۺum۶m&"dF-.ƶ;? >72_o+acK0888>>>>>."CCC"ӟTD;ȩ\pCȖ-[̪뮻g}gDd֭:q۶m߷o߾}nT2fӕ 6=zѣ"b6=:tHW?mݺ߿۷o1,'&"U31""n316ѿ it`Kk16qx6:|X9yrj &">{zԁgnZ ޾Uo߁nZW`۶mO=rl 5{6Wy_}O?M @ j_}{?xO_X{1ܠ-"G ܠ-"raXB8q_5}`g d۷oe cc@kؾGyl"%K|PߊxJG @^~yŷ{|wuw=wo>;?~`]_/?[~ᡏ|ݟwG?rg>οc䧿 "j"wm;y=Oh:/ j|,U:Y$2?"f`?N|>obofٟň؞xDڵkjjʿ6|eR)٧[nddvz"fUT]TkTh?ib@䳠1Zx4[i‘[ ѼL!j lԒ'!Z}Vg6 f^sa$!]$Hi`)?&£W*-'#`Ը*TV/+!U:'9Upzß+nuIzJzL O[>z9_>'@c+U~wT霔UyZ_U3-I(VԌϱL>E3%M@}LUxeUuT"Ugc>pW^6[*ńBZ,4@Ԏ+շ?zTuoZSnUJh D\ }ls嗮/^tzONWθzꑂr'"`D21ߵ_:\RTsŊT+rU*΋\=J/]vӇod ɓCz>31@̼ `u?W}@I9"r'oҩsG~6OEI_yY="[(8幢;3]SN0y\Hd0$K[}OKH/s/tc{^&&EylLa`dJ[mw2 Rmգvz[Y"v`).| Z "53đ?}~}[@^blV. =D5@5'K-bcw555e^E"mn:4VI=mY'dax? 3]žwV[nrNKniW_'"=."Tl\v7kH9Q]bl<#K-2tw gJ""dl|bhp 2p26>A@q]"q @ﰋ]ps~{O \Ba\'nz*\:eJhV(.~F`xU\OmvgVv ?&pF^xpRWV"1y`0b7yk#ڲ*wF遞ҀJS?-̸1C57LB[\6=ȶǖ~Ud$ qjcc3̤'m@I-wNߵ*na82Bt{I[N@k}&ݟA7ipV1E{ IqJ$Fyϖī5ڔZՌ񷔉|@OIZQMDJgalM7ho'mX @£ZZ8c9zr@jM ;'[ ,2@_B s\!5'*Sp*z%U-҂@ﰊyūAnP"}DNQu (ǜ\r\Ռ%@?Ka5Y+n5nte꾸mCD]^9a@z<SX]* f59BzLl|sJ^J5WNNW^8[O.!!onw3xe}]IJhS7Y]WY'ҿ07E]ec+*U"ZRNeR#K<6@džB5҂@XIiPM클 IsΩv"bluz]p-6dZ*blnw2N)BZFJ 5+҂@w92cd 16t4z ec7r׊*(Uvř.<[d䇮4ʠX lks9?$xs[-NqU̶WXTzUMgdɲe^&"9+޳|W8SOH@['DkQ\t6..vU)g}y抮<>bۧ%NNNFNuM5Җ#dO\ͤ3z)ĭ<;S=;S[Gp,D|ӒxIdz\fYu dNUHdk:̳TevYY9%/asspISy2L,0N:YGOF5)^d΀ Y8e EN*f@qA ԌN7 }lQ-.g}f2},-eIN__dnv#fYNڀacsĝܪ! Iuc|@<\G/{O3-ҏ\IHoN6碃F=*ƶRH99]Y/.:? ""2KLl,b17V`kTODgcs bęҹ甼*j蝜p,ҟJn~9U-l5ylSv^ԃ֬_yc nd5ozx*uͮN7-K-t#HBblͣWlvbs%316t4z @``dUmݹkED^̊s"RqKE+Ϟr h׮16Ӛ_2[6:#[̪xSqr)B?_'ZӍZͤR> @T^ve"l[?J{域=sjfI7Z,FV[WYt ~cuC+ylh@icttUЂ@0Oi=hA [n?|kт@Vcd SuڳgOv٤iA 7<<*dRjjjyӂ@7RJ$d ƶ(\}2Bt{I[N@k}&ݟA7ipV1E{ IqJ$Fyϖī5ڔZՌ񷔉|@OIZQMDJgalM7ho'mX @£ZZ8c9zr@jM ;'[ ,2@_B s\!5'*Sp*z%U-҂@ﰊyūAnP"}DNQu (ǜ\r\Ռ%@?Ka5Y+n5nte꾸mCD]^9a@z<SX]* f59BzLl|sJ^J5WNNW^8[O.!!onw3xe}]IJhS7Y]WY'ҿ07E]ec+*U"ZRNeR#K<6@džB5҂@XIiPM클 IsΩv"bluz]p-6dZ*blnw2N)BZFJ 5+҂@w92cd 16t4z ec7r׊*(Uvř.<[d䇮4ʠX lks9?$xs[-NqU̶WXTzUMgdɲe^&"9+޳|W8SOH@['DkQ\t6..vU)g}y抮<>bۧ%NNNFNuM5Җ#dO\ͤ3z)ĭ<;S=;S[Gp,D|ӒxIdz\fYu dNUHdk:̳TevYY9%/asspISy2L,0N:YGOF5)^d΀ Y8e EN*f@qA ԌN7 }lQ-.g}f2},-eIN__dnv#fYNڀacsĝܪ! Iuc|@<\G/{O3-ҏ\IHoN6碃F=*ƶRH99]Y/.:? ""2KLl,b17V`kTODgcs bęҹ甼*j蝜p,ҟJn~9U-l5ylSv^ԃ֬_yc nd5ozx*uͮN7-K-t#HBblͣWlvbs%316t4z @``dUmݹkED^̊s"RqKE+Ϟr h׮16Ӛ_2[6:#[̪xSqr)B?_'ZӍZͤR> @T^ve"l[?J{域=sjfI\'sŰMxaE ̞ 2L:G\oOunR{dqD}82 7zCGA!LgST#wdD/h^z~]8xȵ[6D&ZKq}2pC4&ƶ|y3Sݲѣzyƍ"lf!l:{э7,M{Ȥvi:=Kz]4K6TgwiքfttT|KSB(rttkon ݸqE**1.}5ׄ{^VJ%ti:,]:ե õ,JX .]VdzY>>|8$PEtvyI٥k&BFõMgdߥclŊR,gI?&B@"t[pVOn2Ƽ/M?EFХ#NEqd]CTJϫqZ.K%Ke&l}U˪7$2.KGJؖ-]/cGDfѥ1tHIi|ՀK#cґ'|8{iwFK#ct:@v3Sͯ @ emwDDV(\2-9zt׏^D$'l~*r߁qohp pҖkد(|>ؤʛ}ogQx[*QYnΝ;ED0}t[J{ gIix G O5CE3y_2@ZfT?]{66>'L~9480I\ı J'6 W>9xs,iSpzI)8[|q arۤב0aWףͷz{؁M ǸRSj|KȐYL u3~tf{g\ßFTť``"4P72JriONs)l[njjJDi;A% )r~wSU&=u(|^Y=JȖ!'F߻.\G0[#+)ZM]Bk^j^*M8Yø qi},|V$a`~E8% l+1@bd%OjꮧM? )- }gn]׬ad@thp hp^,?ppq0[ ,D3gq#3ԬŽԳf§r V$#Q&bcKjh7s0/9K!\K"GɸY2gHNQsw6{d9g_τEJKդō\Z԰f^Bl":\nݺ pv JyE8Cͭޝv9 r? j̽'lX4͹lM K=E=c;|c @kF[oxΟ?lnyM)դzg׮]/&<\3r3|OQ 2 )KE䶻J"W, }[dmwR:`( (tIME  t !IENDB`zonecheck-3.0.5/doc/pics/gtk_option.png000066400000000000000000000356141226210254100200620ustar00rootroot00000000000000PNG  IHDRH%kgAMA aMtEXtSoftwareXV Version 3.10a Rev: 12/29/94 (jp-extension 5.3.3 + PNG patch 1.2d){0 IDATx}Uߩ .zeZȐL "* u]&5Wݛ<^dW t]W뮻B"]^„e3^_}BsN:STGjsu5VpMګE\~ݡizi˶9u436@0reZeuu)$Un4ẗ&"Y/J:.|kРl6)1b`̱*}\o֘!.z`EIC-v`[tŤ'2hGN7k,-ۆ\3L.);=-<1!g=^qhQc[ȄQ E> ٕSgȦ,댢S6}}laՐoQm#9`.r&b 2i˶aF4Ux>o Eٖc͒~}8ZCMF5=9 ׽TqlKuUҜ%-r7r8 !*!Dؖj`G5;%Ru]ρy* FAflҌm[ p]V-3{vU,1D64k&^Hߨp3uC-B5 GBΔDfX6x $E~ -$<ĥ$|K$S H^/Ђ2 T:HҤp[PA73mV$xcʴ˯;$"ᓾ54e4QѬOv16BN;w6ITSO v${qטfP;2G{ƶX#@]l}T#@]0 ȕ lB)4LC}؈@e=ehhZ^C}]l?\(FFFȈL9e,Gۉ 9yO>cMddclz}zVh7N?O\~@aBbF9GL)smphؼe/=U]#]16;=r)X1ۓf_qH%fJܠ ȕ16;=rP(  ęft g(x8dQLM;]/'@d,or]{e+gB +< rjxb*+ l\"z`;S"b`mֽeVmzkz͊f7:: q;~Ǿ7k%JD(%JR&PJL @"A~~ }uu~WqxĿ=&-C)7!b`wmp_cxӏ~F:=Vǰ TՂED+$A "(|=~䊋G?r/+/{ׯ-_k,[~?O~b_?<h*#"[ 7vmyRD6lo%RIDR.z/8 &-ؙM_oy1\JOOD*%(O+gl|7댭TnIib́_@i@77}QG&"'!-qΛE' YfV&[1C-E'rt|=Irm1= 9U1K&7]Qֱ8gIK%|ߠS|%JJ /P&"˵H=ac^ "H6SGZ'5/"bmf[M|#[`Rs M*X&q4eB36%֡v"[ 8›:́˛6KpƦ$16H@+J~k-%WUXZF5u PG4:cƌ)k˜ȵ|PDX>cc;\5˖ؕњHxN '޽{*Zpd<4^ۢ3x͒.&" cl߹O\q?9&"~bl2.'v-:'7cСjM1_c[ˮzIeW],2Ȳ/"{A?G>u}}u/-_>Qw>17O؎>c C%v'̙3{{{{{{M)""s̙;wܹsM .\py k ,w>dbHn?]ag>k%"[qN_y]N.6sYfbQoٳgȜ9s̛7N;mx駋… 838C*mI(U^<2sݻw =͙3g```Νm۶Ȗ-[V)6)()zMMV07~D\?]뗉ȟ-Emƌ&90[_Κ5Kow m%"۟~flX`xmOmכn붧XxzT^ߖ-[K9G#+7tZ{QGuuĴi3i]LD PUȴ.utM]]ʺMĊnrf}l")*OR7/^^_tGs='1]v͚5kppPo8vv[xYܮrt%16c?֗ۖ]4u՛כǶc=}۷7fZw`sbl^}ZhK"]uYŚ?G0H)"O\i.Ʀ͚5khhX,V] A1CK}lbbls߾CY`n}JD8tcw6(%,+w9r_vեWؾsi}Dpݧ@gorm?{:bW1vs^:u);yҎb;ٳo,?ODLm޼y۞@.\ "[n؄N619sgyFg޾}SO~]ڶm)+["]]J_V$Ά }lMu ?* Lkkҿobl2Jc3eݻgΜi2͛/|gE"sN;͛:}[Ed˖-r͛7cqB1 ?s~&}CgXk?0E?U_Qܻ?|e#w?R_l;v7SO=d۲eKfN61RK 0<6}3Vvyl"rxToEٌtL1Os~>zWA]5cJF˞I{ӛ-ӿ_Ο,w>KO>ve?gcK{?~wƷ~ǟuOLo~?[~>ѯr>{_]y_}즿꿸{vknc׬x?]f8*ͿfAol*rQԤ&bl*#"soΓ"a}lo+>򁣏~Y)]'F}~y tN}heJ&?$/VSH߾m眖|%nL﵇0Ix)Z?nt-~7[k :RyG[y;㚲kVR|޽bGTdƘvĶƻ#[>6{ƖpTG/  ׻=$v` P(HHB!9C :YH{a [)Ȉ>o8;Nq2&9 R[\yI;}ph384l {{r;=N9>KS{ݺu)?=V՚ettԴ䳝 mfH3fDœ~i'FfHS4* lZǹc޵ߪ!MAҨ09GBA]|{s!IrA6i #M񯺂T!VS*sFSaj0x Wc`J5:b*+ l\!bl\a*+i+rʵ^ Wg BT̀ƫW5UN9睫<'J)n0IsL1!T>s$WBWi/bl)%]S1O v^2#1{G6eLkؿLB:s㷩4zT[*G޸ _!p=(΍)quR_#s"wN&9!.!סg*:JR ZMAdbWܷ3SՒ"$߮9|%3'^(c W[+wݭwl,bl>c:yn iblox k >np{>Ɩhɫ!MAHU}F oɄQ1ΪX.}&͡Bh ikVOiSr/U + "Cg4fNc7KcLn\8<)ĬE8x W>6Z16@0 6@c 16@0 6@c 16@0 6@cJ۪kkVԳE-P(:ڰ>'e%OT3j3Yx09V\{⛎=c{^ׁoߪk7^js}/cOlpC[S4ϰg-CmʵsO-;e֬3g8췿m>'|HEΐ䍗q1ZϰWۍ_x[v|Oω/A嗺}XooϪk=Crph8M;UONt>xdëO7>$"guK~T3g K":XYI&B`IhF\WGzU ڳ=c{ێ;wRԬޓDd"I=;ߊ +)>B,-dgs&,nIHU8-m{w)U$R̙3{`>ӳ w'Yp4=IGz;+gv\BW.22LE-zgF5;wM>=%yˬts#kiZÞM߻xB!rwkK^L<.HSgl\x{Ic[f3C><>6V++::2zUĕ5GSyq٪(\$͌bd )[MuyVg6KwȌ+3TeFz8S )#׬xv`/?_ѣZJ.b, LzoB8.XЕ+ǩP}&ngˑT Vlꢺ>b)Nh<-ۆn;GwܹiӦ]9nʭNzs#WP{;S雓lg~jZτы[n˃]=&UV5+P;߳ )Ҟ.]4EԲVpߦZ퐄}S˪f`ˤMwT:9@+p? +B +Iۺu"v`kd;؁-+؁eIG<2"-.v`-.[-. kN伔Ә/ 5Ő؁6}}}~)9EsһRIglmph`ܜ[ʗfahsH#DT>Q3ۜRJ6Wzhn"c=3̝;ÇǦOPݸ~ݱdbm^v˸r2]̛ۓqCJ;*8ri{rO/3ezdCf45nbl^8ny/{}_8d%& ťbl5: Brfs|Ovvylicl׬xfמ~{ÇJcccc_}WGGFꂸ9NӔMҬbm2;]黎6o&~ia1qeؿx73L"=^*jHn.YfųwЯ~G_|Cˆ—*us%f>:\ֹ*)ǞL_ ٌ1M+sNd8t*ex1u&oý g6Ο|Z-BzDd˶aNѝ;wnڴohsNrGܩnktka$>Bt掮3[n˃]=&UV5+Ppۛ:ҥKrgoґ;:`dHUy>L;w쎮Lj6T#]9@+p? +B +LEr +B +LEr +B +LEr%V\[15+jkL ѱs:˸ĪFL 3de*R) e'x'lٶoO3&G0)xM~Wm\;|pRJyKιҳ=)%\/xAPP`/wED'q%NS.R]miWQmRJ<ϻ\򾳺qM?f⑧Y 9'mrj9]sL X\.<^:rJ-mkFU<1Y+k,D3Ρ9N"7.Lli@:PK)婍6mz2$3| Pq6V#;T0.O\h}t9JŅ߸qqٕ+JXqEvzJS։LxZ/$ɥ<ۛθ1/#35"C }uጭ$><6@0ru46E@s1:""Qg4b*+ l\a*uF @s% l֭kX;؁.bF؈Q܍T(r6@Tcs-  {{DdphXwuNgʜ_D ] *[1S: _ -lӆr\投 SЩb,UEenơzRV9uwws9LIbUӖpeS:fsȓӕ WEz.2=S`~iu &2g2gM0ENseuK :T]o"I剫$S2%qbfz9!xf_wsHd:6:J-na'=2Ԡ~W3et46Q5A2@V WZw`#6B516ZVKȪu" Wr W  Wc+ǭ9oٿ^-}.B:P۪k+ֵz͊ؿ'R(=)aDT?16Ҕ>0#O>T)|n_3:YR^ǃ X|;EG6A?TABtJNѱh 3016e3_/&])Q#qЧbz~ɜ1>GblR^z'.]&G7K LGiJ.֥<幱@|? _KS %H pE7>~Dz2   a;Hx@L8?4cl^*J=tE""$ y'?}4Y"=O)϶Ag~ %Rɯ)ȁF7Ё2 l:ZbP~#T/1G NS pbloxbu3`h1kVWx 07hȕF< pH@0r WrH@0r WrH@0r WrH@dxh- ^qRFFFwM)tB&1o'&lEЦ2nʭNʗL3E5cK + ȕ16ZY516ZS\a` 16@$ l֭kX;؁.M6mڴ-"6T@]D lzk@U꼎\|7ZqR]~!9ypۤ!l=~=1quΚ19%@Vܲmx"<{{BP1%-P(f]vuV-ҘNwwu><2S <Ҧ™#:ͺ4!oEb*-h2@VfT+E=c. C&EGL384_{{N qC-h/'t޵?\|LӼp]Xҝ]Nf"?` 0yI"3a zgУ%[r=tuf?-.ŞR+ vp.!CB)L u3~m:S3'SmqfW<t&B闑M~r]yRuwwts5w(33G%8OvLi3]R(tK%g ӯ]W?igV£ZB-sc)Z]Bkm^*^*SpSq.F5R},|Ve$a`c?29tNq9NY|8#V"T4KԥpdyW&0V]i_?K{ښWeI`[J4sVI92C'>M;+6/|+O2&4rENK$]-ka d$v0/9K!\m%Ycld,DNӨ4kw2TK΄E~jKhH3‘LJŠ{E- hqɣZwww\:ܠD#/gXՉud_Dᡊv&OTP[m;ilnG0qIK[Kڑ_ QIG˗ :i_V8\M0@2jQb[`ܹz:ݛҔ~[O8}}}_v܁(U@Ѵn{n{c05p W2MD. 5Vo&KSh7KHtIME  -+%%)IENDB`zonecheck-3.0.5/doc/xml/000077500000000000000000000000001226210254100150305ustar00rootroot00000000000000zonecheck-3.0.5/doc/xml/.created000066400000000000000000000000001226210254100164260ustar00rootroot00000000000000zonecheck-3.0.5/doc/xml/FAQ.xml000066400000000000000000000011021226210254100161530ustar00rootroot00000000000000 ]>
FAQ &faq;
zonecheck-3.0.5/doc/xml/Makefile000066400000000000000000000002061226210254100164660ustar00rootroot00000000000000DOCBOOK_FILES=../../../formation/lib include ${DOCBOOK_FILES}/Makefile.inc # $Id: Makefile,v 1.2 2010/06/01 15:36:07 chabannf Exp $ zonecheck-3.0.5/doc/xml/common/000077500000000000000000000000001226210254100163205ustar00rootroot00000000000000zonecheck-3.0.5/doc/xml/common/config.xml000066400000000000000000000057401226210254100203150ustar00rootroot00000000000000
sections A section declaration follow the rules: section : name argument '{' commands '}' ';' name : symbol argument : (string)? commands : (section_specific_command ';')* symbol : [a-zA-Z0-9_]+ string : "([^\\\"]|\\[\\\"])*"
config section_specific_command : option_selection option_selection : symbol '=' string config { transp = "ipv4,ipv6,std"; output = "straight,text"; verbose = "explain,details,intro,counter"; error = "standard"; resolver = "127.0.0.1"; };
constant toto section_specific_command : affectation affectation : symbol '=' string constant { # For connectivity testing # the '%s' will be replaced by the IP address ping4 = "ping -q -c 5 %s > /dev/null"; ping6 = "ping6 -q -c 5 %s > /dev/null"; # HTML path for generated pages publish_html_path = "/zc/"; };
useconf toto section_specific_command : domain_mapping domain_mapping : 'map' domainname filename domainname : string filename : string useconf { map "fr." "zc.conf.fr"; map "arpa." "zc.conf.arpa"; map "." "zc.conf.root"; };
testseq toto commands : block block : (check ';' | switch)* check : checkname severity category switch : 'case' testname ('when' symbol block)+ ('else' block)? 'end' testname : symbol # with prefix 'tst_' checkname : symbol # with prefix 'chk_' severity : 'f' | 'w' | 'i' testseq "address" { chk_given_ip f dns; chk_given_nsprim_vs_soa f dns; case tst_mail_by_mx_or_a when MX # MX chk_mx f dns; chk_mx_auth f dns; chk_mx_sntx f dns; end };
zonecheck configuration (<filename>zc.conf</filename>) toto
zone specific configuration toto
zonecheck-3.0.5/doc/xml/common/faq.xml000066400000000000000000000114011226210254100176060ustar00rootroot00000000000000 Where can I find documentation about Ruby? Try the offical Ruby website: http://www.ruby-lang.org/ I don't have IPv6 connectivity but ZoneCheck is still using IPv6 addresses... ZoneCheck only looks for an enabled IPv6 stack to authorize the use of IPv6 addresses. It would be a good idea to disable the IPv6 stack on your computer if you don't have the connectivity or you can use the option to force IPv4 only connectivity. I want to use an interface other than the CLI. Use the environment variable ZC_INPUT set to your input mode, or use the command line option . The input modes currently supported are CLI, CGI, and inetd The option doesn't display earlier debugging messages Some debugging messages are sent before the debugging level is initialised by the command line, in this case use the environment variable ZC_DEBUG set to the desired level. But keep in mind that ZC_DEBUG will be overriden by the option. I would like to easily test ZoneCheck without doing a full installation... You can define the environment variable ZC_INSTALL_PATH to the initial ZoneCheck directory. Why do I get rubbish or wrong results when doing the icmp test? ZoneCheck uses the command ping to perform this test, so you should set the constants ping4 and ping6 in the configuration file so that the ping is correctly invoked: stop after 5 echo requests, doesn't output messages, and return an exit code of 0 in case of success. If you are using ZoneCheck on the Windows platform, you better remove the test. Why did I get strange characters when using a locale other than US/English? The default encoding is UTF-8, either you can configure your terminal to use UTF-8, or you can specify the desired encoding after the locale by using a dot as separator (ex: LANG=fr.latin1); in the last case the ruby-iconv package should have been installed. ZoneCheck complains about the lack of TCP connectivity for a djbdns/tinydns name server... Unfortunately, by default, djbdns/tinydns does not listen on TCP. See to enable it. ZoneCheck crashes when reading configuration files or the message catalog REXML is used to parse the XML files, but it only checks for well formed XML and doesn't perform validation against the DTD, so when you edit the configuration file or the message catalog you should ensure that the files are valid, for that purpose you can use xmllint for example. zonecheck-3.0.5/doc/xml/common/install.xml000066400000000000000000000104041226210254100205070ustar00rootroot00000000000000
Requirement For the ZoneCheck core components: Ruby (v. 1.8): http://www.ruby-lang.org/ For UTF-8 unaware terminal: Ruby Iconv: http://raa.ruby-lang.org/list.rhtml?name=iconv For the CGI interface (other servers or clients can be used): Apache2: http://httpd.apache.org/ Mozilla: http://www.mozilla.org/
Directory layout PREFIX |-- bin | `-- zonecheck # Command line |-- etc | `-- zonecheck # Configuration directory | |-- zc.conf # Main configuration file | |-- rootservers # List of the root servers (YAML file) | |-- reverse.profile # Profile for checking reverse delegation | |-- ... # ... | `-- default.profile # Default set of rules to be used |-- libexec | `--zonecheck | |-- cgi-bin | | `-- zc.cgi # CGI | |-- html # HTML directory (javascript, css, pics, ...) | | |-- en # English version | | |-- ... # ... | | `-- fr # French version | |-- locale # Localisation files | |-- test # test set | |-- lib # Extra libraries (Whois) | `-- zc # core component `-- share `-- doc `-- zonecheck # Documentation
CGI Here is an exemple of Apache2 configuration file, assuming ZoneCheck has been installed in /usr/local (PREFIX=/usr/local) and for html pages generated in the /zc/ namespace (HTML_PATH=/zc). AliasMatch ^/zonecheck/?$ /usr/local/libexec/zonecheck/www/html/form.html AliasMatch ^/zonecheck/(en|fr)/?$ /usr/local/libexec/zonecheck/www/html/form.html.$1 AliasMatch ^/zonecheck/(en|fr)/(.*)$ /usr/local/libexec/zonecheck/www/html/$2.$1 ScriptAlias /zonecheck/cgi-bin/ /usr/local/libexec/zonecheck/cgi-bin/ Alias /zonecheck/js/ /usr/local/libexec/zonecheck/www/js/ Alias /zonecheck/style/ /usr/local/libexec/zonecheck/www/style/ Alias /zonecheck/img/ /usr/local/libexec/zonecheck/www/img/ Alias /zonecheck/ /usr/local/libexec/zonecheck/www/html/ <Directory /usr/local/libexec/zonecheck/cgi-bin/> Options ExecCGI </Directory> <Directory /usr/local/libexec/zonecheck/www/> Options Includes FollowSymLinks MultiViews </Directory>
inetd First you need to edit the file /etc/services, which contains information regarding the known services available in the Internet to add the following line: zonecheck 1904/tcp # ZoneCheck service You also need to configure inetd, so that it is listening for the new zonecheck service, this is done by adding the line: zonecheck stream tcp nowait root /usr/local/bin/zonecheck zonecheck --INPUT=inetd If you have an IPv6 stack installed but don't have the connectivity with the outside world add the option to the zonecheck command.
zonecheck-3.0.5/doc/xml/zc.xml000066400000000000000000000306341226210254100161740ustar00rootroot00000000000000 ]> ZoneCheck II Stephane D'Alu 2002 AFNIC This legal mumbo jumbo will stop evil. &version; The DNS is a critical resource for every network application, quite important to ensure that a zone or domain name is correctly configured in the DNS. ZoneCheck is intended to help solving misconfigurations or inconsistencies usually revealed by an increase in the latency of the application, up to the output of unexpected/inconsistant results. Installation &install; Configuration &config; Overview information warning fatal error test description error message detailed error explanation referer Internal toto Using ZoneCheck
Input
Command Line Interface (CLI) Select another language (en, fr, ...). The syntax is the same as for the environment variable LANG. , Select the debugging messages to print or activate debugging code. This parameter will override the value of the environment variable ZC_DEBUG. The available options are: Code Description 0x0001Initialisation 0x0002Localization / Internationalisation 0x0004Configuration 0x0008Autoconf 0x0010Loading tests 0x0020Tests performed 0x0040Debugging messages from tests 0x0400Information about cached object 0x0800Debugger itself 0x1000Crazy Debug, don't try this at home! 0x2000Dnsruby library debugging messages 0x4000Disable caching 0x8000Don't try to rescue exceptions , Show a short description of the different options available in ZoneCheck , print the ZoneCheck version and exit , don't display extra titles , specify the location of the configuration file (default is etc/zonecheck/zc.conf) specify the directory where all the tests are located , limit the test to the specified category list (catlist); the list is comma separeted and we stop on the first match. If the category start with - or ! the test should not belong to that category, if it starts with nothing or + the test should belong to it. It is possible to have subcategories which are delimited by :. Here is an example that says don't perform DNS tests that are not SOA related: dns:soa,!dns,+ , only the test testname will be performed and its severity will default to fatal , the nameserver running on host will be used as the local resolver instead of taking this information from /etc/resolv.conf , nameservers is the exhaustive list of nameservers that are primary or secondary for the zone, they are separated by a semicolon, if IP addresses should be specified the hostname must be followed by the equal sign and a coma separated list of IP addresses. For example: ns1.toto.fr=192.168.1.5,192.168.1.6;ns2.toto.fr , only display the most relevant message , display tag instead of sentences, this option should be used when writing scripts , , list , list , list , use IPv4 connectivity only , use IPv6 connectivity only list all the available tests types is one of the keyword name expl error % zc -4 -v c,x,d,i afnic.fr ZONE : afnic.fr. NS <= : ns1.nic.fr. [192.93.0.1] NS : ns2.nic.fr. [192.93.0.4] NS : ns3.nic.fr. [192.134.0.49, 2001:660:1180:1:192:134::49] ==> SUCCED
Common Gateway Interface (CGI) = [ fr | en | ... ] quiet - one\n - verbose = [ i|intro, n|testname, x|explain, d|details,\n\ t|testdesc, c|counter, o|reportok ]\n\ - intro\n\ - testname\n\ - explain\n\ - details\n\ - progress = [ t|testdesc | c|counter ]\n\ - reportok\n\ - output = [ bs|byseverity, bh|byhost, t|text, h|html ]\n\ - report = bs|byseverity | bh|byhost\n\ - format = h|html | text\n\ - error = [ af|allfatal, aw|allwarning, std|standard,\n\ s|stop, ns|nostop ]\n\ - errorlvl = [ af|allfatal | aw|allwarning | std|standard ]\n\ - dontstop \n\ - transp = [ ipv4, ipv6, udp, tcp, std ]\n\ - transp3 = [ ipv4, ipv6 ]\n\ - transp4 = [ udp | tcp | std ]\n\ - category = cat1,!cat2:subcat1,cat2,!cat3,+\n\ - chkmail (!mail)\n\ - chkrir (!rir)\n\ - chkzone (!dns:axfr)\n\ - ns = ns1=ip1,ip2;ns2=ip3;ns3\n\ (WARNING: in URL '%3b' should be used instead of ';')\n\ - ns0 .. nsX = nameserver name\n\ - ips0 .. ipsX = coma separated ip addresses\n\ - zone = zone to test\n\
Output
Text toto
HTML toto
FAQ &faq; Writing tests
Available methods titi
Framework titi
Localisation The format of the message catalog is as follow: line : '#' comment # a comment | tag ':' definition # a tag definition | tag '=' tag # a link to another tag | '[' prefix ']' # a prefix to append to other tags prefix : tag # the tag to use as prefix | '*' # don't use a prefix definition : string # a string | string '\' definition # with posibility of continuation '\' tag : [a-zA-Z0-9_]+
About this book This book was hard work if you look at the history and momentum behind the LDP and DocBook and SGML and XML and....and....and...
Copyrights and Trademarks Copyright © 2001 Foo Bar
Purpose/Scope This guide is tightly scoped with one purpose; to process.
Implemented tests toto
zonecheck-3.0.5/etc/000077500000000000000000000000001226210254100142365ustar00rootroot00000000000000zonecheck-3.0.5/etc/zonecheck/000077500000000000000000000000001226210254100162075ustar00rootroot00000000000000zonecheck-3.0.5/etc/zonecheck/afnic.profile000066400000000000000000000136511226210254100206570ustar00rootroot00000000000000 zonecheck-3.0.5/etc/zonecheck/de.profile000066400000000000000000000143671226210254100201740ustar00rootroot00000000000000 zonecheck-3.0.5/etc/zonecheck/default.profile000066400000000000000000000202171226210254100212170ustar00rootroot00000000000000 zonecheck-3.0.5/etc/zonecheck/reverse.profile000066400000000000000000000117011226210254100212440ustar00rootroot00000000000000 zonecheck-3.0.5/etc/zonecheck/rootservers000066400000000000000000000022101226210254100205220ustar00rootroot00000000000000# $Id: rootservers,v 1.8 2010/06/18 13:28:09 bortzmeyer Exp $ # # This file is in YAML format # ( for more information about YAML see: http://yaml.org/ ) # # Tips: # - don't use tabulation # - don't forget the final dot of the name servers # # # This list can be generated by the following shell-script (sh): # # for ns in `dig +short . ns | tr 'A-Z' 'a-z' | sort` ; do # ips=`(dig +short $ns a; dig +short $ns aaaa) | tr '\n' ',' | sed 's/,$//'` # echo "$ns: [ $ips ]" # done # TODO: bad syntax? a.root-servers.net.: [ 198.41.0.4 , 2001:503:ba3e::2:30 ] b.root-servers.net.: [ 192.228.79.201 ] c.root-servers.net.: [ 192.33.4.12 ] d.root-servers.net.: [ 128.8.10.90 ] e.root-servers.net.: [ 192.203.230.10 ] f.root-servers.net.: [ 192.5.5.241 , 2001:500:2f::f ] g.root-servers.net.: [ 192.112.36.4 ] h.root-servers.net.: [ 128.63.2.53 , 2001:500:1::803f:235 ] i.root-servers.net.: [ 192.36.148.17, 2001:7FE:0:0:0:0:0:53 ] j.root-servers.net.: [ 192.58.128.30 , 2001:503:c27::2:30 ] k.root-servers.net.: [ 193.0.14.129 , 2001:7fd::1 ] l.root-servers.net.: [ 199.7.83.42 , 2001:500:3::42 ] m.root-servers.net.: [ 202.12.27.33 , 2001:dc3::35 ] zonecheck-3.0.5/etc/zonecheck/zc.conf000066400000000000000000000133261226210254100174770ustar00rootroot00000000000000 zonecheck-3.0.5/installer.rb000066400000000000000000000163341226210254100160140ustar00rootroot00000000000000# $Id: installer.rb,v 1.21 2010/06/21 07:30:27 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/10/23 21:04:09 # REVISION : $Revision: 1.21 $ # DATE : $Date: 2010/06/21 07:30:27 $ # require 'fileutils' include FileUtils class Installer CVS_NAME = %q$Name: ZC-3_0_5 $ VERSION = (Proc::new { n = CVS_NAME.split[1] n = /^ZC-(.*)/.match(n) unless n.nil? n = n[1] unless n.nil? n = n.gsub(/_/, '.') unless n.nil? n || Time::now.strftime("snapshot-%Y%d%m") }).call def initialize interpreter = `which ruby` interpreter ||= ENV['SUDO_COMMAND'] || ENV['_'] if RUBY_PLATFORM =~ /mswin32/ require 'Win32API' getcli = Win32API::new('kernel32', "GetCommandLine", [], 'P') getcli.call() =~ /^\"([^\"]+)\"/ interpreter = $1 end ARGV.delete_if { |arg| case arg when /^-D(\w+)(?:=(.*))?$/ then ENV[$1] = $2 ; true when /^-U(\w+)$/ then ENV.delete($1) ; true else false end } ENV['RUBY' ] ||= interpreter || 'ruby' ENV['PREFIX' ] ||= '/usr/local' ENV['PROGNAME' ] ||= 'zonecheck' ENV['HTML_PATH' ] ||= "/#{ENV['PROGNAME']}" ENV['ETCDIST' ] ||= '' ENV['CHROOT' ] ||= '' ENV['LIBEXEC' ] ||= "#{ENV['PREFIX']}/libexec" ENV['BINDIR' ] ||= "#{ENV['PREFIX']}/bin" ENV['MANDIR' ] ||= "#{ENV['PREFIX']}/man" ENV['DOCDIR' ] ||= "#{ENV['PREFIX']}/share/doc" ENV['ETCDIR' ] ||= "#{ENV['PREFIX']}/etc" ENV['CGIDIR' ] ||= "#{ENV['LIBEXEC']}/#{ENV['PROGNAME']}/cgi-bin" ENV['WWWDIR' ] ||= "#{ENV['LIBEXEC']}/#{ENV['PROGNAME']}/www" ENV['VERSION' ] ||= VERSION @installdir = "#{ENV['LIBEXEC']}/#{ENV['PROGNAME']}" @confdir = "#{ENV['ETCDIR']}/#{ENV['PROGNAME']}#{ENV['ETCDIST']}" @zc = "#{@installdir}/zc/zc.rb" @wwwdir = "#{ENV['WWWDIR']}" @ch_installdir = "#{ENV['CHROOT']}#{@installdir}" @ch_confdir = "#{ENV['CHROOT']}#{@confdir}" @ch_zc = "#{ENV['CHROOT']}#{@zc}" @ch_wwwdir = "#{ENV['CHROOT']}#{@wwwdir}" @verbose = true end def configure puts "==> Configure" [ 'www/zonecheck.conf.in', 'contrib/distrib/rpm/zonecheck.spec.in' ].each { |in_filename| out_filename = in_filename.gsub(/\.in$/, "") puts "Generating: #{out_filename}" content = File.readlines(in_filename) ENV.each { |k, v| content.each { |line| line.gsub!(/@#{k}@/, v) } } File::open(out_filename, "w") { |io| io.puts content } } puts end def configinfo puts "Default values are:" [ 'RUBY', 'PREFIX', 'PROGNAME', 'HTML_PATH' ].each { |k| puts " #{k}=#{ENV[k]}" } end def inst_doc puts "==> Installing documentation" mkdir_p "#{ENV['CHROOT']}#{ENV['DOCDIR']}/#{ENV['PROGNAME']}", :verbose => @verbose install ['README', 'TODO', 'BUGS', 'HISTORY', 'CREDITS'], "#{ENV['CHROOT']}#{ENV['DOCDIR']}/#{ENV['PROGNAME']}", :mode => 0644, :verbose => @verbose puts end def patch_common puts "==> Patching core components" zc_content = File.readlines(@ch_zc) [ [ /^\#!.*ruby/, "#!#{ENV['RUBY']}" ], [ 'ZC_INSTALL_PATH', "\\1\"#{@installdir}\"" ], [ 'ZC_CONFIG_DIR', "\\1\"#{ENV['ETCDIR']}/#{ENV['PROGNAME']}\"" ], [ 'ZC_LOCALIZATION_DIR', "\\1\"#{@installdir}/locale\"" ], [ 'ZC_TEST_DIR', "\\1\"#{@installdir}/test\"" ], [ 'ZC_HTML_PATH', "\\1\"#{ENV['HTML_PATH']}\"" ] ].each { |pattern, value| zc_content.each { |line| case pattern when Regexp line.gsub!(pattern, value) when String line.gsub!(/^(#{pattern}\s*=\s*(?:ENV\[[^\]]+\]\s*\|\|\s*)?).*/, value) end } } File::open(@ch_zc, "w") { |io| io.puts zc_content } chmod 0755, @ch_zc, :verbose => @verbose puts end def inst_common puts "==> Installing core components" mkdir_p @ch_installdir, :verbose => @verbose cp_r "zc", @ch_installdir, :verbose => @verbose chmod 0755, @ch_zc, :verbose => @verbose puts puts "==> Installing libraries" cp_r 'lib', @ch_installdir, :verbose => @verbose puts puts "==> Installing tests" cp_r 'test', @ch_installdir, :verbose => @verbose puts puts "==> Installing locale" cp_r 'locale', @ch_installdir, :verbose => @verbose puts puts "==> Installing default configuration file" mkdir_p @ch_confdir, :verbose => @verbose cp 'etc/zonecheck/zc.conf', @ch_confdir, :verbose => @verbose cp 'etc/zonecheck/rootservers', @ch_confdir, :verbose => @verbose cp Dir['etc/zonecheck/*.profile'], @ch_confdir, :verbose => @verbose puts end def inst_cli puts "==> Installing CLI" mkdir_p "#{ENV['CHROOT']}#{ENV['BINDIR']}", :verbose => @verbose ln_s @zc, "#{ENV['CHROOT']}#{ENV['BINDIR']}/#{ENV['PROGNAME']}", :force => true, :verbose => @verbose mkdir_p "#{ENV['CHROOT']}#{ENV['MANDIR']}/man1",:verbose => @verbose install "man/zonecheck.1", "#{ENV['CHROOT']}#{ENV['MANDIR']}/man1/#{ENV['PROGNAME']}.1", :mode => 0644, :verbose => @verbose puts end def patch_cgi puts "==> Patching HTML pages" Dir["#{@ch_wwwdir}/html/*.html.*"].each { |page| page_content = File.readlines(page) page_content.each { |line| line.gsub!(/HTML_PATH/, ENV['HTML_PATH']) } File::open(page, "w", 0644) { |io| io.puts page_content } } puts end def inst_cgi puts "==> Installing HTML pages" mkdir_p @ch_wwwdir, :verbose => @verbose Dir["www/*"].each { |entry| cp_r entry, @ch_wwwdir, :verbose => @verbose } puts puts "==> Installing CGI" mkdir_p "#{ENV['CHROOT']}#{ENV['CGIDIR']}", :verbose => @verbose ln_s @zc, "#{ENV['CHROOT']}#{ENV['CGIDIR']}/zc.cgi", :force => true, :verbose => @verbose puts end def info puts "==> Info" unless ENV['ETCDIST'].empty? print < # CREATED : 2002/07/19 07:28:13 # # COPYRIGHT: AFNIC (c) 2003 # CONTACT : # LICENSE : RUBY # # $Revision: 1.6 $ # $Date: 2010/06/01 15:36:07 $ # # INSPIRED BY: # Austin Ziegler ruby version of the perl version of Text::Format # # CONTRIBUTORS: (see also CREDITS file) # # module Text module Formater LEFT_ALIGN = 0 RIGHT_ALIGN = 1 FILLED = 2 JUSTIFY = 3 MaxLineLength = 79 # # Draw an L-shapped box (as below) arround the text # # | # | # `----- -- -- - - - # def self.lbox(text, decoration=[ '|', '`', '-', ' ' ]) finalline = decoration[1] + decoration[2]*5 + decoration[3] + decoration[2]*2 + decoration[3] + decoration[2]*2 + decoration[3] + decoration[2] + decoration[3] + decoration[2] + decoration[3]*2 + decoration[2] (text.split(/\n/).collect { |l| "#{decoration[0]} #{l}" } << finalline << '').join("\n") end # # Draw a title box as below # _____________ # ,-------------.| # ~~~~ | title || ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # `-------------' # def self.title(title, maxlen=MaxLineLength) txtlen = [title.length, maxlen-20].min txt = title[0..txtlen] [ ' ' + '_'*(8+txtlen), ' ,' + '-'*(8+txtlen) + '.|', '~~~~ | ' + txt + ' || ' + '~'*(maxlen-19-txtlen), ' `'+ '-' * (8+txtlen) + "'", '' ].join("\n") end # # Itemize a text as below # # => item1 on # several lines # => item2 # def self.item(text, bullet="=> ", offset=bullet.size) lines = text.split(/\n/) spacer = " " * offset ([ bullet + lines[0] ] + lines[1..-1].collect { |line| spacer + line } + ['']).join("\n") end def self.paragraph(text, width=78, tag=' ', style=LEFT_ALIGN) out = [ ] words = text.split(/\s+/) words.shift if words[0].empty? first_width = width - tag.size line = words.shift while w = words.shift break unless (w.size + line.size) < (first_width - 1) line << ' ' << w end out << build_line(line, width, tag, style, w.nil?) unless line.nil? line = w while w = words.shift if (w.size + line.size < (width - 1)) line << ' ' << w else out << build_line(line, width,'', style, w.nil?) unless line.nil? line = w end end out << build_line(line, width, '', style, true) unless line.nil? out.join('') end def self.build_line(line, width, tag='', style=LEFT_ALIGN, last=false) case style when JUSTIFY return line if last || line.empty? return line unless line =~ /\S+\s+\S+/ spaces = width - line.size - tag.size words = line.split(/(\s+)/) ws = spaces / (words.size / 2) spaces = spaces % (words.size / 2) if ws > 0 words.reverse.each { |rw| next if rw =~ /^\S/ if spaces > 0 then rw.replace((' ' * (ws+1)) + rw) ; spaces -= 1 else rw.replace((' ' * (ws) ) + rw) end } tag + words.join('') + "\n" when FILLED "#{tag}#{line}".ljust(width) + "\n" when RIGHT_ALIGN "#{tag}#{line}".rjust(width) + "\n" else tag + line + "\n" end end end end zonecheck-3.0.5/locale/000077500000000000000000000000001226210254100147225ustar00rootroot00000000000000zonecheck-3.0.5/locale/cgi.en000066400000000000000000000057141226210254100160170ustar00rootroot00000000000000 => You can't invoke directly the CGI script! Use one of the available form present on the site instead. Follow a quick summary of the possible parameters for more information see the ZoneCheck documentation. parameters: - lang = [ fr | en | ... ] - quiet - one - option - verbose = [ i|intro, n|testname, x|explain, d|details, t|testdesc, c|counter, o|reportok ] - intro - testname - explain - details - progress = [ t|testdesc | c|counter ] - reportok - fatalonly - output = [ bs|byseverity, bh|byhost, t|text, h|html ] - report = bs|byseverity | bh|byhost - format = h|html | text - error = [ af|allfatal, aw|allwarning, ds|dfltseverity, s|stop, ns|nostop ] - errorlvl = [ af|allfatal | aw|allwarning | ds|dfltseverity ] - dontstop - transp = [ ipv4, ipv6, udp, tcp, std ] - transp3 = [ ipv4, ipv6 ] - transp4 = [ udp | tcp | std ] - profile = profilename - category = cat1,!cat2:subcat1,cat2,!cat3,+ - chkmail (!mail) - chkrir (!rir) - chkzone (!dns:axfr) - ns-rdata = DS rdata - ns = ns1=ip1,ip2;ns2=ip3;ns3 (WARNING: in URL '%3b' should be used instead of ';') - ns0 .. nsX = nameserver name - ips0 .. ipsX = coma separated ip addresses - zone = zone to test exemples: - zone=afnic.fr&intro&progress=testdesc&transp=ipv4,ipv6,std - zone=afnic.fr&verbose=i,t&ns=ns1.nic.fr%3bns2.nic.fr%3bns3.nic.fr - zone=afnic.fr&verbose=i,t&ns=ns1.nic.fr=192.93.0.1&ns=ns2.nic.fr&ns=bns3.nic.fr zonecheck-3.0.5/locale/cgi.fr000066400000000000000000000060201226210254100160130ustar00rootroot00000000000000 => Ce script CGI ne peut pas être directement invoqué! Utilisez un des formulaires présent sur le site à la place. Ci-dessous se trouve un résumé des paramètres possibles, pour plus d'informations veuillez consulter la documentation de ZoneCheck. parametres: - lang = [ fr | en | ... ] - quiet - one - option - verbose = [ i|intro, n|testname, x|explain, d|details, t|testdesc, c|counter, o|reportok ] - intro - testname - explain - details - progress = [ t|testdesc | c|counter ] - reportok - fatalonly - output = [ bs|byseverity, bh|byhost, t|text, h|html ] - report = bs|byseverity | bh|byhost - format = h|html | t|text - error = [ af|allfatal, aw|allwarning, ds|dfltseverity, s|stop, ns|nostop ] - errorlvl = [ af|allfatal | aw|allwarning | ds|dfltseverity ] - dontstop - transp = [ ipv4, ipv6, udp, tcp, std ] - transp3 = [ ipv4, ipv6 ] - transp4 = [ udp | tcp | std ] - profile = nom du profile - category = cat1,!cat2:subcat1,cat2,!cat3,+ - chkmail (!mail) - chkrir (!rir) - chkzone (!dns:axfr) - ns-rdata = DS rdata - ns = ns1=ip1,ip2;ns2=ip3;ns3 (ATTENTION: utiliser '%3b' dans l'URL à la place de ';') - ns0 .. nsX = serveur de nom - ips0 .. ipsX = adresses IP séparées par une virgule - zone = zone à tester exemples: - zone=afnic.fr&intro&progress=testdesc&transp=ipv4,ipv6,std - zone=afnic.fr&verbose=i,t&ns=ns1.nic.fr%3bns2.nic.fr%3bns3.nic.fr - zone=afnic.fr&verbose=i,t&ns=ns1.nic.fr=192.93.0.1&ns=ns2.nic.fr&ns=bns3.nic.fr zonecheck-3.0.5/locale/cli.en000066400000000000000000000126421226210254100160220ustar00rootroot00000000000000 usage: PROGNAME: [-hqV] [-voet opt] [-46] [-n ns...] [-c conf] domainname --lang Select another language (en, fr, ...) -d, --debug Select debugging messages to print -h, --help Show this message -V, --version Display version and exit -B, --batch Depreciated, more information is provided in the FAQ file -c, --config Specify location of the configuration file --testdir Location of the directory holding tests -P, --profile Force uses of a particular profile -C, --category Only perform test for the specified category -T, --test Name of the test to perform --testlist List all the available tests --testdesc Give a description of the test (values: name, failure, success, explanation) -r, --resolver Resolver to use for guessing 'ns' information -n, --ns List of nameservers for the domain (ex: ns1;ns2=ip1,ip2;ns3=ip3) -q, --quiet Don't display extra titles -1, --one Only display the most relevant message -g, --tagonly Display only tag (suitable for scripting) -v, --verbose Display extra information (see verbose) -o, --output Output (see output) -e, --error Behaviour in case of error (see error) -t, --transp Transport/routing layer (see transp) -4, --ipv4 Only check the zone with IPv4 connectivity -6, --ipv6 Only check the zone with IPv6 connectivity --preset Use some preset configuration --option Set extra options (-,-opt,opt,opt=foo) -s, --securedelegation Run the DNSSEC tests (see man zonecheck) verbose: [intro/testname/explain/details] [reportok|fatalonly] [testdesc|counter] can be prefix by '-' or '!' to remove the effect intro [i] Print summary for domain and associated nameservers testname [n] Print the test name explain [x] Print an explanation for failed tests details [d] Print a detailed description of the failure reportok [o] Still report passed test fatalonly [f] Print fatal errors only testdesc [t] Print the test description before running it counter [c] Print a test counter output: [byseverity|byhost] [text|html] byseverity *[bs] Output is sorted/merged by severity byhost [bh] Output is sorted/merged by host text *[t] Output plain text html [h] Output HTML error: [allfatal|allwarning|dfltseverity] [stop|nostop] allfatal [af] All error are considered fatal allwarning [aw] All error are considered warning dfltseverity *[ds] Use the severity associated with the test stop *[s] Stop on the first fatal error nostop [ns] Never stop (even on fatal error) transp: [ipv4/ipv6] [udp|tcp|std] ipv4 *[4] Use IPv4 routing protocol ipv6 *[6] Use IPv6 routing protocol udp [u] Use UDP transport layer tcp [t] Use TCP transport layer std *[s] Use UDP with fallback to TCP for truncated messages Batch Mode: Process domain from file or stdin, with 1 per line. The syntax is: DOM=domainname or DOM=domainname NS=ns1;ns2=ip1,ip2 Categories: allow=[+|] disallow=[-|!] subcomponent=: separator=, ex: dns:soa,!dns,+ don't perform DNS tests that are not SOA related EXAMPLES: PROGNAME -6 --verbose=i,x,d afnic.fr. Test the 'afnic.fr.' domain with IPv6 only connectivity, print a summary information about the tested domain as well as explanations and details of failed tests PROGNAME --testdesc error -T soa Ask for the 'error' message associated with the test 'soa' The option %s is depreciated, more information is provided in the FAQ file zonecheck-3.0.5/locale/cli.fr000066400000000000000000000135111226210254100160230ustar00rootroot00000000000000 usage: PROGNAME: [-hqV] [-voet opt] [-46] [-n ns...] [-c conf] nomdedomaine --lang Choisit une autre langue (en, fr, ...) -d, --debug Choisit les messages de deboguage à afficher -h, --help Affiche ce message -V, --version Affiche le numéro de version et quitte -B, --batch Dépreciée, pour plus d'informations lisez la FAQ -c, --config Emplacement du fichier de configuration --testdir Emplacement du répertoire contenant les tests -P, --profile Force l'utilisation d'un profile -C, --category Limite les tests à un ensemble de catégories -T, --test Nom du test à effectuer --testlist Liste tous les tests disponibles --testdesc Donne une description du test (valeurs: name, failure, success, explanation) -r, --resolver Résolveur à utiliser pour déterminer les 'ns' -n, --ns Liste des serveurs de noms pour le domaine (ex: ns1;ns2=ip1,ip2;ns3=ip3) -q, --quiet N'affiche pas de titres suplémentaires -1, --one Affiche uniquement le message le plus significatif -g, --tagonly Affiche uniquement les tags (idéal pour les scripts) -v, --verbose Niveau de détail des informations (voir verbose) -o, --output Format de sortie (voir output) -e, --error Comportement en cas d'erreur (voir error) -t, --transp Choix de la couche transport/routage (voir transp) -4, --ipv4 Utilise uniquement IPv4 pour vérifier le domaine -6, --ipv6 Utilise uniquement IPv6 pour vérifier le domaine --preset Utilise une configuration préinitialisée --option Options supplémentaires (-,-opt,opt,opt=toto) -s, --securedelegation Lance les tests DNSSEC (voir man zonecheck) verbose: [intro/testname/explain/details] [reportok|fatalonly] [testdesc|counter] peut être préfixé par '-' ou '!' pour retirer l'effet intro [i] Affiche un résumé du domaine et de ses serveurs testname [n] Affiche le nom du test explain [x] Affiche une explication en cas d'échec du test details [d] Affiche les détails liés à l'échec du test reportok [o] Affiche quand même les tests qui ont réussi fatalonly [f] Affiche uniquement les erreurs fatales testdesc [t] Affiche la description du test en cours counter [c] Affiche une barre de progression output: [byseverity|byhost] [text|html] byseverity *[bs] Affiche les résultats classés par sévérité byhost [bh] Affiche les résultats classés par machine text *[t] Formatage en texte pur html [h] Formatage en HTML error: [allfatal|allwarning|dfltseverity] [stop|nostop] allfatal [af] Tout échec est considéré comme fatal allwarning [aw] Tout échec est considéré comme un avertissement dfltseverity *[ds] Utilise la sévérité associée au test stop *[s] Arrête dès le premier échec nostop [ns] Exécute tous les tests (même après échec fatal) transp: [ipv4/ipv6] [udp|tcp|std] ipv4 *[4] Utilise le protocole de routage IPv4 ipv6 *[6] Utilise le protocole de routage IPv6 udp [u] Utilise la couche de transport UDP tcp [t] Utilise la couche de transport TCP std *[s] Utilise UDP et se replie sur TCP si nécessaire Traitement en lots: Lit les domaines ligne par ligne depuis un fichier ou l'entrée standard, La syntaxe est: DOM=nom_de_domain ou DOM=nom_de_domain NS=ns1;ns2=ip1,ip2 Catégories: permet=[+|] interdit=[-|!] sous-composant=: séparateur=, ex: dns:soa,!dns,+ n'effectue pas les tests DNS qui ne sont pas liés au SOA EXEMPLES: PROGNAME -6 --verbose=i,x,d afnic.fr. Teste le domaine 'afnic.fr.' en utilisant uniquement une connectivité IPv6, affiche un résumé des informations sur le domaine testé ainsi qu'une explication et les détails sur les tests ayant échoués PROGNAME --testdesc error -T soa Demande le message 'error' associé avec le test soa' L'option %s est dépreciée, pour plus d'informations lisez la FAQ zonecheck-3.0.5/locale/test/000077500000000000000000000000001226210254100157015ustar00rootroot00000000000000zonecheck-3.0.5/locale/test/axfr.en000066400000000000000000000040311226210254100171630ustar00rootroot00000000000000 zone transfer possible Zone transfer is possible Zone transfer not possible
zone transfer contains data Zone transfer returned data Zone transfer is empty
zone transfer contains valid labels Zone transfer contains only valid label(s) Zone transfer contains invalid label(s)
zonecheck-3.0.5/locale/test/axfr.fr000066400000000000000000000041771226210254100172030ustar00rootroot00000000000000 transfert de zone possible Transfert de zone réussi Transfert de zone impossible
transfert de zone ne contenant aucune donnée Le transfert de zone contient des données Le transfert de zone ne contient pas de données
transfert de zone contenant des labels invalides Le transfert de zone ne contient aucun label invalide Le transfert de zone contient des labels invalides
zonecheck-3.0.5/locale/test/connectivity.en000066400000000000000000000052301226210254100207430ustar00rootroot00000000000000 IETF RFC1035 (p.32 4.2. Transport) The DNS assumes that messages will be transmitted as datagrams or in a byte stream carried by a virtual circuit. While virtual circuits can be used for any DNS activity, datagrams are preferred for queries due to their lower overhead and better performance. ICMP answer Host replies to ICMP requests Host doesn't reply to ICMP requests (firewall?)
UDP connectivity Server replies to UDP DNS request on port 53 Server doesn't listen/answer on port 53 for UDP protocol
TCP connectivity Server replies to TCP DNS request on port 53 Server doesn't listen/answer on port 53 for TCP protocol
zonecheck-3.0.5/locale/test/connectivity.fr000066400000000000000000000053611226210254100207550ustar00rootroot00000000000000 IETF RFC1035 (p.32 4.2. Transport) The DNS assumes that messages will be transmitted as datagrams or in a byte stream carried by a virtual circuit. While virtual circuits can be used for any DNS activity, datagrams are preferred for queries due to their lower overhead and better performance. réponses aux requêtes ICMP L'hôte répond aux requêtes ICMP L'hôte ne répond pas aux requêtes ICMP (présence d'un pare-feu?)
connectivité UDP Le serveur répond aux requêtes DNS en UDP sur le port 53 Le serveur n'écoute pas ou ne répond pas en UDP sur le port 53
connectivité TCP Le serveur répond aux requêtes DNS en TCP sur le port 53 Le serveur n'écoute pas ou ne répond pas en TCP sur le port 53
zonecheck-3.0.5/locale/test/dnssec.en000066400000000000000000000106631226210254100175120ustar00rootroot00000000000000 supports EDNS supports EDNS does not support EDNS
has a RRSIG for its SOA has a signed SOA does not have a signed SOA
a DNSKEY exists has at least one DNSKEY has no DNSKEY
several DNSKEY exist has several DNSKEY has just one DNSKEY
both ZSK and KSK exist has at least a KSK and a ZSK has no ZSK and/or no KSK
verification of the SOA RRSIG the SOA has a correct RRSIG the SOA has not a correct RRSIG
verify that the SOA RRSIG is not expired the SOA RRSIG is not about to expire the SOA RRSIG is about to expire or is already expired
Signature expires on .
verify that the SOA RRSIG has a correct lifetime the SOA RRSIG has a good lifetime the SOA RRSIG has a lifetime too short or too long
Signature lifetime is and should be between and and higher than the TTL (here, )
efficiency of the RRSIG algorithm A RRSIG with an efficient algorithm has been found The RRSIG algorithm is (are) not enough efficient
Signature algorithm is not efficient enough because:
key length The length of the key is enough The length of the key should be higher for this algorithm
the key length is bits for the algorithm :
coherence between DS or DNSKEY given in arguments and DNSKEYs in the zone The given DS or DNSKEY correspond to a DNSKEY in the zone The given DS or DNSKEY does not correspond to any DNSKEY in the zone
zonecheck-3.0.5/locale/test/dnssec.fr000066400000000000000000000114441226210254100175150ustar00rootroot00000000000000 Support de l'EDNS supporte EDNS ne supporte pas EDNS
présence d'une signature pour le SOA a son SOA signé n'a pas de signature pour son SOA
présence d'une DNSKEY une clé publique a été trouvée aucune clé publique n'a été trouvée
présence de plusieurs DNSKEY plusieurs clés publiques ont été trouvées une seule clé publique est publiée
présence d'une ZSK et d'une KSK au moins une ZSK et une KSK ont été trouvées pas de ZSK ou pas de KSK
vérification de la signature du SOA le SOA a une signature correcte le SOA a une signature non correcte
vérification de l'expiration du RRSIG du SOA la signature du SOA ne va pas expirer bientôt la signature du SOA va bientôt expirer ou est déjà expirée
La signature expire le .
vérification de la durée de vie de la signature du SOA la signature du SOA a une durée de vie acceptable la signature du SOA a une durée de vie trop courte ou trop longue
la durée de vie de la signature est de et devrait être entre et et plus grande que le TTL (ici )
vérification de la sécurité de l'algorithme Une signature avec un algorithme suffisament sûr a été trouvé l'algorithme choisi pour les signatures n'est pas très sûr
L'algoritme utilisé pour signer les enregistrement n'est pas très sûr car:
Taille de la clé la taille de la clé est suffisante la taille de la clé ne permet pas une bonne protection pour cet algorithme
La clé a une taille de bits pour l'algorithme
cohérence entre la DS ou DNSKEY donnée en paramètre et les DNSKEYs dans la zone La DS ou DNSKEY donnée correspond à une des DNSKEY de la zone La DS ou DNSKEY donnée ne correspond à aucune des DNSKEY de la zone
zonecheck-3.0.5/locale/test/generic.en000066400000000000000000000170501226210254100176440ustar00rootroot00000000000000 IETF RFC1034 (p.11) Labels are only composed by letters ([A-Za-z]), digits ([0-9]) or dashes ('-') (not starting or ending with), and should be less or equal than 63 characters; domain name (labels separated by '.') should be less or equal than 255 characters. See also [ref]: IETF RFC1912 (2.1 Inconsistent, Missing, or Bad Data). ZoneCheck To avoid losing all connectivity with the authoritative DNS in case of network outage it is advised to host the DNS on different networks. IETF RFC2182 (Abstract) The Domain Name System requires that multiple servers exist for every delegated domain (zone). This document discusses the selection of secondary servers for DNS zones. Both the physical and topological location of each server are material considerations when selecting secondary servers. The number of servers appropriate for a zone is also discussed, and some general secondary server maintenance issues considered. illegal symbols in domain name No illegal symbols found in domain name The domain name contains illegal symbols
dash ('-') at start or beginning of domain name No illegal use of dash ('-') in the domain name found The domain name start or end with a dash ('-')
double dash in domain name No double dash ('--') found The domain name contains a double dash IETF IDN project (internationalized domain names) The double dash ('--') will have a special meaning for the domain name encoding, so it is strongly advised not to used it. See http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm (4. Tagged Domain Names.)
one nameserver for the domain At least one nameserver found At least one nameserver is required
at least two nameservers for the domain At least two nameservers found At least two nameservers are necessary
identical addresses All addresses are distinct All addresses should be distinct
The nameservers are using the same IP address ().
nameserver's addresses on same subnet Some IP addresses are not on the same subnet IP addresses on the same subnet
The following subnets are used by several hosts: . Try moving some of their hosts to another subnet.
nameserver addresses are likely to be all on the same subnet Not all IP addresses are on the same subnet IP addresses are likely to be all on the same subnet
All the servers are likely to be on the subnet , try moving some of them to another subnet.
nameservers belong all to the same AS All nameservers are not part of the same AS Nameservers are all part of the same AS ZoneCheck To avoid losing all connectivity with the authoritative DNS in case of a routing problem inside your Autonomous System, it is advised to host the DNS on different AS.
All the nameservers are part of the same Autonomous System (AS number ), try to have some of them hosted on another AS.
delegation response fit in a 512 byte UDP packet Delagation response fit in a 512 byte UDP packet Delegation response won't fit in a 512 byte UDP packet
For a query of bytes, it won't be possible to send all the nameservers ( bytes in excess).
delegation response with additional fit in a 512 byte UDP packet Delagation response with additional fit in a 512 byte UDP packet Delegation response with additional won't fit in a 512 byte UDP packet
For a query of bytes, it won't be possible to send all the nameservers with the corresponding glues ( bytes in excess).
zonecheck-3.0.5/locale/test/generic.fr000066400000000000000000000200421226210254100176440ustar00rootroot00000000000000 IETF RFC1034 (p.11) Labels are only composed by letters ([A-Za-z]), digits ([0-9]) or dashes ('-') (not starting or ending with), and should be less or equal than 63 characters; domain name (labels separated by '.') should be less or equal than 255 characters. See also [ref]: IETF RFC1912 (2.1 Inconsistent, Missing, or Bad Data). ZoneCheck To avoid losing all connectivity with the autoritative DNS in case of network outage it is advised to host the DNS on different networks. IETF RFC2182 (Abstract) The Domain Name System requires that multiple servers exist for every delegated domain (zone). This document discusses the selection of secondary servers for DNS zones. Both the physical and topological location of each server are material considerations when selecting secondary servers. The number of servers appropriate for a zone is also discussed, and some general secondary server maintenance issues considered. nom de domaine contenant des caractères illégaux Le nom de domaine ne contient aucun caractère illégal Le nom de domaine contient des caractères illégaux
tiret ('-') au début ou à la fin du nom de domaine Aucune mauvaise utilisation du tiret ('-') dans le nom de domaine Le nom de domaine commence ou finit par un tiret ('-')
double tiret ('--') dans le nom de domaine Pas d'utilisation du double tiret ('--') Le nom de domaine contient un double tiret ('--') IETF IDN project (internationalized domain names) The double dash ('--') will have a special meaning for the domain name encoding, so it is strongly advised not to used it. See http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm (4. Tagged Domain Names.)
présence de serveurs de nom gérant le domaine Au moins un serveur de nom présent Au moins un serveur de nom est requis
présence d'au moins deux serveurs de noms pour le domaine Au moins deux serveurs de noms présents Au moins deux serveurs de noms sont nécessaires
adresses IP identiques parmi les serveurs Toutes les adresses IP sont distinctes Toutes les adresses IP doivent être distinctes
Les serveurs de noms utilisent la même adresse IP ().
serveurs de noms sur le même sous-réseau Aucun serveur de nom n'est sous le même sous-réseau Des serveurs sont sur le même sous-réseau
Les sous-réseaux suivants sont utilisés par plusieurs hôtes: . Essayez de déplacer certains hôtes sur un autre sous-réseau.
serveurs de noms tous sur le même sous-réseau Les serveurs de noms ne sont probablement pas tous sur le même sous-réseau Les serveurs de noms semblent être tous sur le même sous-réseau
Tous les serveurs de noms semblent être dans le sous-réseau . Essayez d'en déplacer quelques uns sur un autre sous-réseau.
serveurs de noms appartenant tous au même AS Tous les serveurs de noms ne font partie du même AS Les serveurs de nom font tous partie du même AS ZoneCheck Afin d'éviter de perdre la connectivité avec les serveurs DNS faisant autorité en cas de problèmes de routage dans le Système Autonome, il est conseillé d'héberger les serveurs sur différents AS.
Tous les serveurs de noms font partie du même Système Autonome (AS numéro ), essayez d'en héberger certains sur un autre.
delegation response fit in a 512 byte UDP packet Delagation response fit in a 512 byte UDP packet Delegation response won't fit in a 512 byte UDP packet
Pour une requête de octets, il n'est pas possible d'envoyer la liste complete des serveurs de noms ( octets en trop).
delegation response with additional fit in a 512 byte UDP packet Delagation response with additional fit in a 512 byte UDP packet Delegation response with additional won't fit in a 512 byte UDP packet
Pour une requête de octets, il n'est pas possible d'envoyer la liste complete des serveurs de noms avec leurs glues correspondantes ( octets en trop).
zonecheck-3.0.5/locale/test/interop.en000066400000000000000000000034671226210254100177170ustar00rootroot00000000000000 behaviour against AAAA query Correct behaviour against AAAA query Misbehaviour against AAAA query
behaviour against CNAME query Correct behaviour against CNAME query Misbehaviour against CNAME query
zonecheck-3.0.5/locale/test/interop.fr000066400000000000000000000036051226210254100177160ustar00rootroot00000000000000 comportement lors de demande d'un enregistrement AAAA Comportement correct lors de la demande d'un AAAA Mauvais comportement lors de la demande d'un AAAA
Comportement lors d'une requête CNAME Comportement correct de la requête CNAME Mauvais comportement de la requête CNAME
zonecheck-3.0.5/locale/test/loopback.en000066400000000000000000000046511226210254100200250ustar00rootroot00000000000000 IETF RFC1912 (p.13 4.1. Boot file setup) These are set up to either provide nameservice for "special" addresses, or to help eliminate accidental queries for broadcast or local address to be sent off to the root nameservers. All of these files will contain NS and SOA records just like the other zone files you maintain. loopback delegation Loopback domain has been delegated Loopback domain is not delegated
loopback is resolvable Loopback address is resolvable Loopback is not resolvable
zonecheck-3.0.5/locale/test/loopback.fr000066400000000000000000000047411226210254100200320ustar00rootroot00000000000000 IETF RFC1912 (p.13 4.1. Boot file setup) These are set up to either provide nameservice for "special" addresses, or to help eliminate accidental queries for broadcast or local address to be sent off to the root nameservers. All of these files will contain NS and SOA records just like the other zone files you maintain. délégation du 'loopback' Le domaine du 'loopback' a bien été délégué Le domaine du 'loopback' n'est pas délégué
'loopback' resolvable Il est possible de résoudre le 'loopback' Impossible de résoudre le 'loopback'
zonecheck-3.0.5/locale/test/mail.en000066400000000000000000000124131226210254100171500ustar00rootroot00000000000000 MAPS An Internet mail server performs third-party relay when it processes a message from a non-local sender to a non-local recipient. These days, junk emailers abuse this capability at an alarming rate. They use the stolen capacity to greatly increase the amount of spam they can deliver. ZoneCheck You can perform more complete testing by using the following command: "telnet relay-test.mail-abuse.org", for more information take a look at http://www.mail-abuse.org/ delegated domain is not an open relay The best MX for the domain doesn't seem to be an open relay The best MX for the domain is an open relay
The mailhost () used for receiving email for your domain seems to act as an open relay, it is allowing mail from to .
domain of the hostmaster email is not an open relay The best MX for the hostmaster address doesn't seem to be an open relay The best MX for the hostmaster address is an open relay
The mailhost () used for the hostmaster address () seems to act as an open relay, it is allowing mail from to .
can deliver email to 'postmaster' The postmaster can be contacted by email The postmaster can't be contacted by email IETF RFC1123 (p.51 5.2.7 RCPT Command: RFC-821 Section 4.1.1) A host that supports a receiver-SMTP MUST support the reserved mailbox "Postmaster".
Unable to send email to the postmaster address () using relays: .
can deliver email to hostmaster The hostmaster can be contacted by email The hostmaster can't be contacted by email
Unable to send email to the hostmaster address () using relays: .
hostmaster MX is not an alias The hostmaster MX is not an alias The hostmaster MX is not allow to point to a CNAME alias IETF RFC974 MX records shall not point to an alias defined by a CNAME.
domain able to receive email (delivery using MX, A, AAAA) The domain is able to receive email The domain doesn't have an MX or an address for mail delivery
test if mail delivery possible zonecheck-3.0.5/locale/test/mail.fr000066400000000000000000000126231226210254100171600ustar00rootroot00000000000000 MAPS An Internet mail server performs third-party relay when it processes a message from a non-local sender to a non-local recipient. These days, junk emailers abuse this capability at an alarming rate. They use the stolen capacity to greatly increase the amount of spam they can deliver. ZoneCheck You can perform more complete testing by using the following command: "telnet relay-test.mail-abuse.org", for more information take a look at http://www.mail-abuse.org/ domain délégué est un openrelay Le MX principal pour le domaine n'est pas un openrelay Le MX principal pour le domaine est un openrelay
La machine indiquée pour la réception du courrier () du domaine semble être un openrelay, elle permet l'envoi de mél de à .
domain of the hostmaster email is not an openrelay Le MX principal pour le "hostmaster" n'est pas un openrelay Le MX principal pour le "hostmaster" est un openrelay
La machine indiquée pour la réception du courrier () pour le "hostmaster" () semble être un openrelay, elle permet l'envoi de mél de à .
envoie de mél au "postmaster" Le "postmaster" peut être contacté par mél Le "postmaster" ne peut pas être contacté par mél IETF RFC1123 (p.51 5.2.7 RCPT Command: RFC-821 Section 4.1.1) A host that supports a receiver-SMTP MUST support the reserved mailbox "Postmaster".
Impossible d'envoyer un email au "postmaster" () à travers les relais: .
envoie de mél au "hostmaster" Le "hostmaster" peut être contacté par mel Le "hostmaster" ne peut pas être contacté par mél
Impossible d'envoyer un email au "hostmaster" () à travers les relais: .
l'enregistrement MX du "hostmaster" n'est pas un alias L'enregistrement MX du "hostmaster" n'est pas un alias L'enregistrement MX du "hostmaster" ne peut pas être un alias (CNAME) IETF RFC974 MX records shall not point to an alias defined by a CNAME.
domaine capable de recevoir du courrier (MX, A, AAAA) Le domaine est capable de recevoir du courrier Le domaine n'a pas de MX ou d'adresse pour delivrer le courrier
test if mail delivery possible zonecheck-3.0.5/locale/test/misc.en000066400000000000000000000074341226210254100171700ustar00rootroot00000000000000 nameserver IP reverse Reverse for nameserver IP address found Can't find reverse for the nameserver IP address
nameserver IP reverse matching nameserver name Reverse matching nameserver name Reverse for the nameserver IP address doesn't match
nameserver doesn't allow recursion The anameserver is not recursive The nameserver allow recursive queries ZoneCheck If you configure your nameserver to answer recursive queries, it means that you allow your nameserver to be used by anyone to resolve any kind of queries. This allows everyone to use your server as an amplifier for a Denial-of-Service attack. See http://www.us-cert.gov/reading_room/DNS-recursion121605.pdf.
check if server is really recursive Server is recursive as stated Server claims to be recursive but is not
given primary nameserver is primary The primary nameserver matches the given one The primary nameserver doesn't match the given one
The primary nameserver () doesn't match the given one ().
correctness of given nameserver list The nameserver list matches the given one The nameserver list doesn't match the given one
The given nameserver list () is not consistent with the one retrieved from the zone ().
test if server is recursive zonecheck-3.0.5/locale/test/misc.fr000066400000000000000000000103041226210254100171630ustar00rootroot00000000000000 existance du nom correspondant à l'adresse IP du serveur Le nom correspondant à l'adresse IP du serveur a été trouvé Impossible de trouver le nom correspondant à l'adresse IP du serveur
vérification du nom correspondant à l'adresse IP du serveur Le nom correspondant à l'adresse IP correspond au nom du serveur Incoherence entre le nom correspondant à l'adresse IP et celui du serveur
serveur de nom n'autorisant pas la récursion Le serveur de nom n'est pas récursif Le serveur de nom autorise les requêtes récursives ZoneCheck Si vous configurez le serveur de noms pour répondre aux requêtes récursives, cela implique que vous acceptez que n'importe qui l'utilise pour résoudre n'importe quel type de requêtes. Cela permet notamment l'utilisation de votre serveur pour amplifier des attaques par déni de service et c'est donc très déconseillé. Voir http://www.afnic.fr/actu/nouvelles/general/NN20060404.
serveur de nom réellement récursif Le serveur est récursif comme annoncé Le serveur dit être récursif mais ne l'est pas
serveur de nom donné comme primaire est primaire Le serveur de nom primaire correspond à celui donné Le serveur de nom primaire ne correspond pas à celui donné
Le serveur de nom primaire () ne correspond pas à celui indiqué ().
cohérence avec la liste des serveurs de noms donnée La liste des serveurs recuperée correspond à celle donnée La liste des serveurs récupérée ne correspond pas à celle donnée
La liste des serveurs de noms donnée () n'est pas cohérente avec celle récupérée sur la zone ().
test if server is recursive zonecheck-3.0.5/locale/test/mx.en000066400000000000000000000076111226210254100166560ustar00rootroot00000000000000 MX record present MX record found No MX record found on server IETF RFC1912 (p.7) Put MX records even on hosts that aren't intended to send or receive e-mail. If there is a security problem involving one of these hosts, some people will mistakenly send mail to postmaster or root at the site without checking first to see if it is a "real" host or just a terminal or personal computer that's not set up to accept e-mail.
MX authoritative answer The MX answer is authoritative The MX answer is not authoritative
MX syntax is valid for a hostname MX syntax is correct MX syntax is not correct
MX is not an alias MX is not an alias MX is not allowed to point to a CNAME alias IETF RFC974 MX records shall not point to an alias defined by a CNAME.
The MX is an alias to .
absence of wildcard MX No wildcard MX found A wildcard MX is present
MX can be resolved The IP address of the Mail eXchanger is resolvable The IP address of the Mail eXchanger can't be resolved
The MX representing the host name doesn't have an IP address.
coherence between MX and ANY records MX and ANY agree MX and ANY request disagree
test if mail is delivered using MX or A/AAAA zonecheck-3.0.5/locale/test/mx.fr000066400000000000000000000103311226210254100166540ustar00rootroot00000000000000 enregistrement MX présent L'enregistrement MX est présent sur le serveur Aucun enregistrement MX présent sur le serveur IETF RFC1912 (p.7) Put MX records even on hosts that aren't intended to send or receive e-mail. If there is a security problem involving one of these hosts, some people will mistakenly send mail to postmaster or root at the site without checking first to see if it is a "real" host or just a terminal or personal computer that's not set up to accept e-mail.
réponse faisant autorité pour le MX La réponse pour le MX fait autorité La réponse pour le MX ne fait pas autorité
syntaxe du MX représente un nom de machine valide La syntaxe du MX est correcte La syntaxe du MX n'est pas correcte
l'enregistrement MX n'est pas un alias L'enregistrement MX n'est pas un alias L'enregistrement MX ne peut pas être un alias (CNAME) IETF RFC974 MX records shall not point to an alias defined by a CNAME.
Le MX est un alias vers .
absence de joker pour l'enregistrement MX Pas de joker pour l'enregistrement MX Un joker pour l'enregistrement MX est présent
enregistrement MX peut être résolu L'adresse IP de l'enregistrement MX a été trouvée L'adresse IP de l'enregistrement MX ne peut pas être résolue
Le MX représentant le nom du serveur ne possède pas d'adresse IP.
cohérence entre enregistrements MX et ANY Enregistrements MX et ANY cohérents Enregistrements MX et ANY incohérents
Test si le mail est envoyé via un MX ou un A/AAAA zonecheck-3.0.5/locale/test/nameserver.en000066400000000000000000000053041226210254100203760ustar00rootroot00000000000000 address in a private network Address is not part of a private subnet Address is part of a private subnet IETF RFC1918 (3. Private Address Space) The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets: 10/8, 172.16/12, 192.168/16.
address shouldn't be part of a bogon prefix Address is not listed on the bogon list Address listed on the bogon list http://www.cymru.com/Bogons/ A bogon prefix is a route that should never appear in the Internet routing table. A packet routed over the public Internet (not including over VPN or other tunnels) should never have a source address in a bogon range. These are commonly found as the source addresses of DDoS attacks.
The address belongs to a bogon prefix.
zonecheck-3.0.5/locale/test/nameserver.fr000066400000000000000000000054011226210254100204010ustar00rootroot00000000000000 adresse dans un réseau privé Aucune adresse n'a été allouée dans un réseau privé L'adresse a été allouée dans un réseau privé IETF RFC1918 (3. Private Address Space) The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets: 10/8, 172.16/12, 192.168/16.
adresse faisant partie de la liste des 'bogon' Aucune adresse ne fait partie des 'bogon' Présence d'adresses listées parmi les 'bogon' http://www.cymru.com/Bogons/ A bogon prefix is a route that should never appear in the Internet routing table. A packet routed over the public Internet (not including over VPN or other tunnels) should never have a source address in a bogon range. These are commonly found as the source addresses of DDoS attacks.
Classé parmi les 'bogon': .
zonecheck-3.0.5/locale/test/ns.en000066400000000000000000000071201226210254100166450ustar00rootroot00000000000000 IETF RFC1912 (p.7) Having NS records pointing to a CNAME is bad and may conflict badly with current BIND servers. In fact, current BIND implementations will ignore such records, possibly leading to a lame delegation. There is a certain amount of security checking done in BIND to prevent spoofing DNS NS records. Also, older BIND servers reportedly will get caught in an infinite query loop trying to figure out the address for the aliased nameserver, causing a continuous stream of DNS requests to be sent. NS record present NS record found No NS record found on server
NS authoritative answer The NS answer is authoritative The NS answer is not authoritative
NS name has a valid domain/hostname syntax NS name syntax is correct NS name syntax is not correct
NS is not an alias NS is not an alias NS is not allowed to point to a CNAME alias
coherence between NS and ANY records NS and ANY agree NS and ANY request disagree
NS can be resolved IP addresses of the zone nameserver have been found The IP addresses of the zone nameserver can't be found
The IP address for was not known.
zonecheck-3.0.5/locale/test/ns.fr000066400000000000000000000074441226210254100166630ustar00rootroot00000000000000 IETF RFC1912 (p.7) Having NS records pointing to a CNAME is bad and may conflict badly with current BIND servers. In fact, current BIND implementations will ignore such records, possibly leading to a lame delegation. There is a certain amount of security checking done in BIND to prevent spoofing DNS NS records. Also, older BIND servers reportedly will get caught in an infinite query loop trying to figure out the address for the aliased nameserver, causing a continuous stream of DNS requests to be sent. présence d'un enregistrement NS Enregistrement NS présent sur le serveur Aucun enregistrement NS présent sur le serveur
réponse faisant autorité pour le NS La réponse pour le NS fait autorité La réponse pour le NS ne fait pas autorité
la syntaxe du NS réprésente un nom/domaine valide la syntaxe du NS est correcte la syntaxe du NS n'est pas correcte
l'enregistrement NS n'est pas un alias L'enregistrement NS n'est pas un alias L'enregistrement NS ne peut pas être un alias (CNAME)
cohérence entre enregistrements NS et ANY Enregistrements NS et ANY cohérents Enregistrements NS et ANY incohérents
enregistrement NS peut être résolu L'adresse IP du serveur de noms a été trouvée L'adresse IP du serveur de noms n'existe pas
L'adresse IP pour n'a pas été trouvée.
zonecheck-3.0.5/locale/test/rootserver.en000066400000000000000000000061651226210254100204470ustar00rootroot00000000000000 IETF RFC2870 (p.1) The Internet Corporation for Assigned Names and Numbers (ICANN) has become responsible for the operation of the root servers. The ICANN has appointed a Root Server System Advisory Committee (RSSAC) to give technical and operational advice to the ICANN board. The ICANN and the RSSAC look to the IETF to provide engineering standards. root-servers list present Root-servers found Root-servers are not available
root-servers list identical to ICANN Root-servers list is consistent with ICANN Root-servers list is not consistent with ICANN
The root-server list () is not identicall to ICANN list ().
root-servers addresses identical to ICANN Root-servers IP addresses are consistent with ICANN Root-servers IP addresses are not consistent with ICANN
The root-server addresses () are not the same as the ICANN addresses ().
zonecheck-3.0.5/locale/test/rootserver.fr000066400000000000000000000064571226210254100204600ustar00rootroot00000000000000 IETF RFC2870 (p.1) The Internet Corporation for Assigned Names and Numbers (ICANN) has become responsible for the operation of the root servers. The ICANN has appointed a Root Server System Advisory Committee (RSSAC) to give technical and operational advice to the ICANN board. The ICANN and the RSSAC look to the IETF to provide engineering standards. existence de la liste des root servers Les "Root Servers" sont disponibles Les "Root Servers" ne sont pas disponibles
liste des Root Servers identique à celle de l'ICANN La liste des "Root Servers" est cohérente avec celle de l'ICANN La liste des "Root Servers" est incohérente avec celle de l'ICANN
La list des 'root-servers' () n'est pas identique a celle de l'ICANN ().
adresses IP des "Root Servers" identiques à celles de l'ICANN Les adresses des "Root Servers" sont cohérentes avec celles de l'ICANN Les adresses des "Root Servers" sont incohérentes avec celles de l'ICANN
Les adresses () du "Root Server" ne sont pas les même que celles de l'ICANN ().
zonecheck-3.0.5/locale/test/soa.en000066400000000000000000000300721226210254100170110ustar00rootroot00000000000000 IETF RFC1034 (p.9), RFC1912 (p.3) Email addresses are converted by using the following rule: local-part@mail-domain ==> local-part.mail-domain if local-part contains a dot in should be backslashed (for 'bind'). <zcconst name="registry"/> registry policy The registry requires the SOA fields to be inside a defined range: the 'expire' should be between and , the 'minimum' between and , the 'refresh' between and , and at last the 'retry' between and . SOA record present SOA record found No SOA record found on server
SOA authoritative answer The SOA answer is authoritative The SOA answer is not authoritative
misused '@' characters in SOA contact name No misuse of '@' character in SOA contact name The contact name contains the character '@'
illegal characters in SOA contact name No illegal characters in SOA contact name The contact name contains illegal characters
illegal characters in SOA master nameserver No illegal characters in SOA master nameserver The SOA master nameserver contains illegal characters
fully qualified master nameserver in SOA The SOA master nameserver is fully qualified The SOA master nameserver is not fully qualified
The master nameserver () is certainly missing the final dot in the configuration file.
serial number of the form YYYYMMDDnn The serial number follows the form YYYYMMDDnn The format of the serial number is not YYYYMMDDnn RFC1912 (p.3) The recommended syntax is YYYYMMDDnn (YYYY=year, MM=month, DD=day, nn=revision number).
The serial doesn't seem to be in the YYYYMMDDnn format.
SOA 'expire' between and The 'expire' is between and The 'expire' period should be between and
The expire value is and should be between and .
SOA 'minimum' between and The 'minimum' is between and The 'minimum' period should be between and
The minimum value is and should be between and .
SOA 'refresh' between and The 'refresh' is between and The 'refresh' period should be between and
The refresh value is and should be between and .
SOA 'retry' between and The 'retry' is between and The 'retry' period should be between and
The retry value is and should be between and .
SOA 'retry' lower than 'refresh' The 'retry' is lower than the 'refresh' The 'retry' period must be lower than the 'refresh' period IETF RFC1912 (p.4) The 'retry' value is typically a fraction of the 'refresh' interval.
The retry ( sec) should be lower than the refresh ( sec).
SOA 'expire' at least 7 times 'refresh' The 'expire' is at least 7 times the 'refresh' The 'expire' period must be at least 7 times greater than 'refresh'
The expire ( sec) is not at least 7 times greater than the refresh ( sec), you should correct one of them.
SOA master is not an alias The SOA master is not an alias SOA master is not allowed to point to a CNAME alias
The master () is a CNAME alias to .
coherence between SOA and ANY records SOA and ANY agree SOA and ANY request disagree
excessive drift of serial number with primary nameserver Acceptable or no drift of serial number with primary nameserver Excessive drift of serial number with primary nameserver
The expected value for the serial (taking drift into account) should have been more than , but is instead of as on ).
coherence of serial number with primary nameserver The serial number is consistent with primary nameserver The serial number is not consistent with primary nameserver
got serial instead of as on .
coherence of administrative contact with primary nameserver The contact is consistent with primary nameserver The contact is not consistent with primary nameserver
got contact instead of as on .
coherence of master with primary nameserver The master is consistent with primary nameserver The master is not consistent with primary nameserver
Got master instead of as on .
coherence of SOA with primary nameserver The SOA is consistent with primary nameserver The SOA is not consistent with primary nameserver
zonecheck-3.0.5/locale/test/soa.fr000066400000000000000000000320331226210254100170150ustar00rootroot00000000000000 IETF RFC1034 (p.9), RFC1912 (p.3) Email addresses are converted by using the following rule: local-part@mail-domain ==> local-part.mail-domain if local-part contains a dot in should be backslashed (for 'bind'). Politique du registre <zcconst name="registry"/> Le registre demande que les champs du SOA soient à l'interieur d'un interval défini: le champ 'expire' doit être entre et , le champ 'minimum' entre et , le champ 'refresh' entre et , et enfin le champ 'retry' entre et . présence d'un enregistrement SOA Enregistrement SOA trouvé Aucun enregistrement SOA présent sur le serveur
réponse faisant autorité pour le SOA La réponse pour le SOA fait autorité La réponse pour le SOA ne fait pas autorité
mauvaise utilisation du caractère '@' dans le 'contact' du SOA Aucune mauvaise utilisation du caractere '@' dans le 'contact' du SOA Le contact contient le caractère '@'
caractères illégaux dans le contact du SOA Aucun caractère illégal dans le contact du SOA Le contact contient des caractères illégaux
caractères illégaux dans le 'master' du SOA Aucun caractère illégal dans le 'master' du SOA Le 'master' du SOA contient des caractères illégaux
nom de serveur pleinement qualifié dans le 'master' du SOA Le 'master' est pleinement qualifié Le nom du serveur dans le 'master' du SOA n'est pas pleinement qualifié
Le point ('.') final est certainement manquant dans le fichier de configuration pour le serveur () indiqué en tant que maître dans le SOA.
numéro de série de la forme AAAAMMJJnn Le numéro de série suit bien la forme AAAAMMJJnn Le numéro de série n'est pas de la forme AAAAMMJJnn RFC1912 (p.3) The recommended syntax is YYYYMMDDnn (YYYY=year, MM=month, DD=day, nn=revision number).
Le numéro de série ne semble pas être au format AAAAMMJJnn.
champ 'expire' du SOA entre et Le champ 'expire' du SOA est entre et Le champ 'expire' doit être entre et
La valeur du champ 'expire' est et devrait être entre et .
champ 'minimum' du SOA entre et Le champ 'minimum' du SOA est entre et Le champ 'minimum' doit être entre et
La valeur du champ 'minimum' est et devrait être entre et .
champ 'refresh' du SOA entre et Le champ 'refresh' du SOA est entre et Le champ 'refresh' doit être entre et
La valeur du champ 'refresh' est et devrait être entre et .
champ 'retry' du SOA entre et Le champ 'retry' du SOA est entre et Le champ 'retry' doit être entre et
La valeur du champ 'retry' est et devrait être entre et .
champ 'retry' du SOA inférieur à celui du 'refresh' Le champ 'retry' du SOA inférieur à celui du 'refresh' Le champ 'retry' doit être inférieur à celui du 'refresh' IETF RFC1912 (p.4) The 'retry' value is typically a fraction of the 'refresh' interval.
La valeur du champ 'retry' est de sec, et devrait être inférieure au 'refresh' ( sec).
champ 'expire' est au moins 7 fois celui du 'refresh' Le champ 'expire' est au moins 7 fois celui du 'refresh' Le champ 'expire' doit être au moins 7 fois celui du 'refresh'
La valeur du champ 'expire' est de sec, et devrait être 7 fois plus grande que celle du 'refresh' ( sec).
champ 'master' du SOA n'est pas un alias Le champ 'master' du SOA n'est pas un alias Le champ 'master' du SOA ne doit pas pointer sur un alias CNAME
Le serveur maître () indiqué dans le SOA est un alias CNAME sur .
cohérence entre enregistrements SOA et ANY Enregistrements SOA et ANY cohérents Enregistrements SOA et ANY incohérents
dérive excessive du numéro de série avec celui du serveur primaire Dérive inexistant ou acceptable du numéro de série avec celui du serveur primaire Dérive excessive du numéro de série avec celui du serveur primaire
La valeure attendue pour le numéro de série (en prenant en consideration une éventuelle dérive) aurait due être supérieure à , mais elle est de contrairement à celui indiqué sur qui est de ).
cohérence du numéro de série avec celui du serveur primaire Le numéro de série est cohérent avec celui du serveur primaire Le numéro de série n'est pas cohérent avec celui du serveur primaire
Le numéro de série obtenu () est différent de celui indiqué sur ().
cohérence du contact administratif avec celui du serveur primaire Le contact est cohérent avec celui du serveur primaire Le contact n'est pas cohérent avec celui du serveur primaire
Le contact obtenu () est différent de celui indiqué sur ().
cohérence du champ 'master' du SOA avec celui du serveur primaire Le champ 'master' du SOA est cohérent avec celui du serveur primaire Le champ 'master' du SOA est incohérent avec celui du serveur primaire
Le serveur maître indiqué dans le SOA () est différent de celui indiqué sur ().
cohérence du SOA avec celui du serveur primaire Le SOA est cohérent avec celui du serveur primaire Le SOA est incohérent avec celui du serveur primaire
zonecheck-3.0.5/locale/zc.en000066400000000000000000000137101226210254100156640ustar00rootroot00000000000000
generic warning w fatal f info i ok o testing unexpected line error perfect quit abort details references elements form name sec
all servers
single Ref Adv SUCCESS (but %d warning(s)) SUCCESS FAILURE FAILURE (and %d warning(s)) zone ns primary secondary IPs Zone information Progress Test results Final status Progression Tests Time Speed T/s N/A problem while opening/reading file: %s
Input method '%s' unsupported Input method '%s' suspicious PROGNAME: version %s No mapping able to process '%s'
check '%s' unavailable Unknown profile '%s' Unknown preset '%s' Error in preset '%s'
Nameserver (%s) is not a hostname Address (%s) is not an IP address
Absolute domain name required One domainname expected The domain %s has not been found through the local resolver Unable to find a SOA record for that domain Unable to find primary nameserver (SOA) Unable to find nameservers (NS) Unable to identify primary nameserver (NS vs SOA) The nameserver %s is an IP address and should be a name Unable to find nameserver IP address(es) for %s Given IP address(es) for %s not matching DNS records Selected output class doesn't support '%s' %s not supported on that host Unknown modifier '%s' for '%s' option IP address expected for the local resolver Print the requests done by tha test: class '%s' doesn't derive from %s test '%s' defined in classes '%s' and '%s' check '%s' defined int class '%s' and '%s' too many arguments (%s arguments) have been given to the option %s
server failure answer refused from server domain doesn't exist query not implemented on server
Unknown algorithm Deprecated algorithm
zonecheck-3.0.5/locale/zc.fr000066400000000000000000000144431226210254100156750ustar00rootroot00000000000000
générique avertissement a fatal f info i ok o teste inattendu ligne erreur parfait quitte interrompt détails références éléments formulaire nom sec
tous les serveurs
domaine simple Réf Conseil SUCCÈS (mais %d avertissement(s)) SUCCÈS ÉCHEC ÉCHEC (et %d avertissement(s)) zone ns primaire secondaire IPs Information sur la Zone Progression Résultat des tests Statut final Progression Tests Temps Vitesse T/s N/A problème à l'ouverture/lecture du fichier: %s
méthode d'entrée '%s' non supportée méthode d'entrée '%s' douteuse PROGNAME: version %s Impossible d'établir une correspondance pour '%s'
Test de vérification '%s' inconnu Profile '%s' inconnu Préinitialisation '%s' inconnue Erreur dans la préinitialisation '%s'
Le serveur de nom (%s) n'est pas un nom de machine L'adresse renseignée (%s) n'est pas une adresse IP
Nom de domaine absolument qualifié attendu Un nom de domaine (et un seul) attendu Le domaine %s n'a pas été trouvé à partir du résolveur local Impossible de trouver d'enregistrement SOA pour ce domaine Impossible de trouver le serveur de nom primaire (SOA) Impossible de trouver les serveurs de noms (NS) Impossible d'identifier le serveur de nom primaire (NS vs SOA) Le serveur de nom %s est une adresse IP et devrait être un nom Impossible de trouver les adresses IP de %s Addresses IP donnees pour %s ne corrspondent pas aux enregistrement du DNS La sortie ne supporte pas la classe '%s' %s n'est pas supporté sur cette machine Modificateur '%s' inconnu pour l'option '%s' Addresse IP attendue pour le resolveur local Affichage des requêtes effectuées pour ce test: classe '%s' ne dérive pas de %s test '%s' défini dans les classes '%s' et '%s' vérification '%s' définie dans les classes '%s' et '%s' trop d'arguments (%s arguments) ont été passé à l'option %s
échec du serveur réponse refusée par le serveur le domaine n'existe pas requête non mise en oeuvre sur le serveur
algoritme inconnu algoritme déprecié
zonecheck-3.0.5/man/000077500000000000000000000000001226210254100142365ustar00rootroot00000000000000zonecheck-3.0.5/man/zonecheck.1000066400000000000000000000351361226210254100163010ustar00rootroot00000000000000.\" $Id: zonecheck.1,v 1.24 2011/03/11 16:09:17 kmkaplan Exp $ . .\" .\" CONTACT : zonecheck@nic.fr .\" AUTHOR : Stephane D'Alu .\" .\" CREATED : 2003/08/26 10:20:35 .\" REVISION : $Revision: 1.24 $ .\" DATE : $Date: 2011/03/11 16:09:17 $ .\" .\" CONTRIBUTORS: (see also CREDITS file) .\" .\" .\" LICENSE : GPL v3 (or MIT/X11-like after agreement) .\" COPYRIGHT : AFNIC (c) 2003 .\" .\" This file is part of ZoneCheck. .\" .\" ZoneCheck is free software; you can redistribute it and/or modify it .\" under the terms of the GNU General Public License as published by .\" the Free Software Foundation; either version 3 of the License, or .\" (at your option) any later version. .\" .\" ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, .\" Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA .\" . . .de c .\" this is like a comment request when escape mechanism is off .. . .eo . .c --------------------------------------------------------------------- . .c .de List . TP 2m . nop \)\[bu] .. . .ec .\" End of macro definitions . . .TH ZONECHECK 1 "26 January 2003" .SH NAME zonecheck \- DNS zone checking tool .SH SYNOPSIS .na .B zonecheck [ .B \-hqV ] [ .B \-voet .I opt ] [ .B -46 ] [ .B \-c .I conf ] .br .ti +10 [ .B \-n .I nslist ] [ .B \-s .I key ] .I domainname .br .ad .SH DESCRIPTION .LP The DNS is a critical resource for every network application, quite important to ensure that a zone or domain name is correctly configured in the DNS. \fIZoneCheck\fP is intended to help solving misconfigurations or inconsistencies usually revealed by an increase in the latency of the application, up to the output of unexpected/inconsistant results. . .SH OPTIONS .IP \fINOTE:\fB It doesn't necessary make sense to combine some options together, if that case happens the most recent option will be taken into account, silently discarding the others. .TP \fB--lang\fR \fIlang\fR Select another language (en, fr, ...). The syntax is the same as for the environment variable \fILANG\fR. . .TP \fB--debug\fR, \fB-d\fR \fIlvl\fR Select the debugging messages to print or activate debugging code. This parameter will override the value of the environment variable \fIZC_DEBUG\fR. .br The available options are: 0x0001 : Initialisation 0x0002 : Localization / Internationalisation 0x0004 : Configuration 0x0008 : Autoconf 0x0010 : Loading tests 0x0020 : Tests performed 0x0040 : Debugging messages from tests 0x0400 : Information about cached object 0x0800 : Debugger itself 0x1000 : Crazy Debug, don't try this at home! 0x2000 : Dnsruby library debugging messages 0x4000 : Disable caching 0x8000 : Don't try to rescue exceptions .TP \fB--help\fR, \fB-h\fR Show a short description of the different options available in \fIZoneCheck\fR. . .TP \fB--version\fR, \fB-V\fR Display the version and exit. . .TP \fB--batch\fR, \fB-B\fR \fIfilename\fR Depreciated option. You can use this script instead : .br for domain in `cat list_dom`; do echo "Testing $domain" zonecheck $domain done . .TP \fB--config\fR, \fB-c\fR \fIfilename\fR Specify the location of the configuration file (default is \fIzc.conf\fR). . .TP \fB--testdir\fR \fIdirectory\fR Location of the directory holding the tests definition. . .TP \fB--profile\fR, \fB-P\fR \fIprofilename\fR Force uses of profile \fIprofilename\fR. . .TP \fB--category\fR, \fB-C\fR \fIcatlist\fR Limit the test to perform to the categories specified by \fIcatlist\fR. The syntax for the catgory description is as follow: allow=[+|] disallow=[-|!] subcomponent=: separator=, ex: dns:soa,!dns,+ don't perform DNS tests that are not SOA related . .TP \fB--test\fR, \fB-T\fR \fItestname\fR \fItestname\fR is the test to perform. In this case failing to pass the test is considered as fatal. . .TP \fB--testlist\fR List all the tests available. . .TP \fB--testdesc\fR \fIdesctype\fR Give a description of the test, the possible values for \fIdesctype\fR are \fBname\fR, \fBsuccess\fR, \fBfailure\fR, \fBexplanation\fR. . .TP \fB--resolver\fR, \fB-r\fR \fIresolver\fR Resolver to use (only IP address is accepted) for finding the information about the tested zone, by default the name servers used are the one specified in \fI/etc/resolv.conf\fR. Note that for finding the name servers the zone should already have been delegated. . .TP \fB--ns\fR, \fB-n\fR \fInslist\fR List of nameservers for the domain. Nameservers name are separated by a semicolon, the name can be followed by the equal sign and its IP addresses separated by a colon. .br This can give the following example: ns1;ns2=ip1,ip2;ns3=ip3 . .TP \fB--securedelegation\fR, \fB-s\fR \fI[dsordnskey]\fR Force the execution of the full DNSSEC profile. Arguments are optional. You can precise the Trust Anchor of your zone by giving the DNSKEY or the DS and the algorithm used to hash your key. Several Trust Anchors can be specified, separated by commas (in that case, they _all_ have to match.) .br This can give the following example: \fBDNSKEY:af1Bs0F+4rg-g19,DS:eAg7P4J1qfMg:SHA-1 \fP \fBDS:eAg7P4J1qfMg:SHA-1\fP \fBDS-RDATA:5991 8 2 46DB8A99F9125B1F88AAC74DF7EC3FFCCC13CE7412C3BEBB2CB93BED4A05A960\fP \fBDNSKEY:af1Bs0F+4rg-g19\fP . .TP \fB--quiet\fR, \fB-q\fR Don't display extra titles. . .TP \fB--one\fR, \fB-1\fR Only display the most relevant message in a compact format. . .TP \fB--tagonly\fR, \fB-g\fR Display only tag. This option should be used for scripting. . .TP \fB--verbose\fR, \fB-v\fR \fIoptions\fR Display extra information, they can be prefix by '-' or '!' to remove the effect, available options are: . .RS .TP \fBintro\fR, \fBi\fR Print a short summary about the domain name and its nameservers. .TP \fBtestname\fR, \fBn\fR Print the name of the test when reporting a test status. .TP \fBexplain\fR, \fBx\fR Print an explanation for failed tests (reference to RFC, ...). .TP \fBdetails\fR, \fBd\fR Print a detailed description of the failure (name or value of the resource involved). .TP \fBreportok\fR, \fBo\fR Report test even if they passed. .TP \fBfatalonly\fR, \fBf\fR Only print fatal errors. .TP \fBtestdesc\fR, \fBt\fR Print the test description before performing it. .TP \fBcounter\fR, \fBc\fR Display a test progression bar (this option is not always available according to the output media). . .IP \fINOTE:\fB \fBtestdesc\fR and \fBcounter\fR are mutually exclusive. .RE . .TP \fB--output\fR, \fB-o\fR \fIoptions\fR Output rendering/format selection, avalaible options are: .RS .TP \fBbyseverity\fR, \fBbs\fR [default] Output is sorted/merged by severity. .TP \fBbyhost\fR, \fBbh\fR Output is sorted/merged by host. .TP \fBtext\fR, \fBt\fR [default] Output plain text. .TP \fBhtml\fR, \fBh\fR Output HTML. .TP \fBxml\fR, \fBx\fR .br Output XML. (experimental) . .IP \fINOTE:\fB The following set are mutually exclusive: [\fBbyseverity\fR|\fBbyhost\fR] and [\fBtext\fR|\fBhtml\fR]. .RE . .TP \fB--error\fR, \fB-e\fR \fIoptions\fR Behaviour in case of error, available options are: .RS .TP \fBallfatal\fR, \fBaf\fR All error are considered as fatals. .TP \fBallwarning\fR, \fBaw\fR All error are considered as warnings. .TP \fBdfltseverity\fR, \fBds\fR [default] Use the severity associated with the test. .TP \fBstop\fR, \fBs\fR [default] Stop on the first fatal error. .br \fIWARNING:\fR the current implementation stop on the first error but for each server. .TP \fBnostop\fR, \fBns\fR Never stop (even on fatal error). This generally result in a lot of errors or unexpected results due to the previous fatal error. . .IP \fINOTE:\fB The following set are mutually exclusive: [\fBallfatal\fR|\fBallwarning\fR|\fBdfltseverity\fR] and [\fBstop\fR|\fBnostop\fR]. .RE . .TP \fB--transp\fR, \fB-t\fR \fIoptions\fR Transport/routing layer selection, available options are: .RS .TP \fBipv4\fR, \fB4\fR [default] Use the IPv4 routing protocol. .TP \fBipv6\fR, \fB6\fR [default] Use the IPv6 routing protocol. .TP \fBudp\fR, \fBu\fR Use the UDP transport layer. .TP \fBtcp\fR, \fBt\fR Use the TCP transport layer. .TP \fBstd\fR, \fBs\fR [default] Use the UDP with fallback to TCP for truncated messages. . .IP \fINOTE:\fB \fBudp\fR, \fBtcp\fR and \fBstd\fR are mutually exclusive. .RE . .TP \fB--edns\fR \fI[always|never|auto]\fR Activate/Deactivate the use of EDNS for all queries. Three possible values: always, never, auto. Auto : automatically determine if the domain and the route to name servers can carry EDNS queries. . .TP \fB--ipv4\fR, \fB-4\fR Only check the zone with IPv4 connectivity. . .TP \fB--ipv6\fR, \fB-6\fR Only check the zone with IPv6 connectivity. . .TP \fB--preset\fR \fIname\fR Use of a preset configuration defined in the zc.conf configuration file. . .TP \fB--option\fR \fIoptions\fR Set extra options. The syntax is: -,-opt,opt,opt=foo .RS .TP \fBihtml\fR Generate HTML pages that are suitable for inclusion (for HTML output). .TP \fBnojavascript\fR Remove generation of javascript (for HTML output). . .SH "ENVIRONMENT" .TP .I LANG Specify the lang and eventually the encoding to use to display messages. For examples: fr, fr_CA, fr.latin1, fr_CA.utf8, ... .TP .I ZC_CONFIG_DIR Directory where the configuration file and the different profiles are located. .TP .I ZC_CONFIG_FILE Name of the configuration file to use (defaul to zc.conf), it is override by the \fB--config\fR option. .TP .I ZC_LOCALIZATION_DIR Directory where all the localization files are located. .TP .I ZC_TEST_DIR Directory where all the tests are located, it is override by the \fB--testdir\fR option. .TP .I ZC_HTML_PATH Path relative to the web server to use when generating HTML pages. .TP .I ZC_DEBUG The variable as the same effect as the \fBdebug\fR parameter, but its main advantage is that it is taken into account from the beginning of the program. .TP .I ZC_INPUT The variable as the same effect as the undocumented \fBINPUT\fR parameter, it allows to chose the input interface used by \fIZoneCheck\fR, the currently supported values are: \fBcli\fR, \fBcgi\fR and \fBinetd\fR. But other interfaces doesn't accept the same parameters as the one described here. .TP .I ZC_IP_STACK Restrict the IP stack available to IPv4 or IPv6, for that set it respectively to 4 or 6. This is particularly useful if you have an IPv6 stack on your computer but don't have the connectivity, in that case define ZC_IP_STACK=4. .TP .I ZC_XML_PARSER If ruby-libxml is installed, this parser will be used instead of rexml for speed improvement, but you can force the use of rexml by setting ZC_XML_PARSER to rexml. .TP .IP \fINOTE:\fB The following variables are mainly useful when it is not possible for the user to specify alternative value with the selected input interface: \fIZC_CONFIG_DIR\fR, \fIZC_CONFIG_FILE\fR, \fIZC_LOCALIZATION_DIR\fR, \fIZC_TEST_DIR\fR. Such a case happen when using the cgi interface, and you don't want the user to read an arbitrary configuration file, but as the provider of the service you want to use another configuration. . .SH "EXIT STATUS" The following exit status can be reported by \fIZoneCheck\fR: .TP 0 Everything went fine, no fatal errors were reported, the domain configuration is correct. .TP 1 The program completed but some tests failed with a fatal severity, the domain is NOT correctly configured. .TP 2 The program completed but some tests failed due with a fatal severity due to \fItimeout\fR occuring, the domain has been considered as NOT correctly configured, but you could want to check again later. \fIThis is currently not implemented.\fR .TP 3 The user aborted the program before it's completion. .TP 4 An error which is not directly related to the tests performed has occured (ie: something went wrong). .TP 9 The user (you?) didn't bother reading the man page... . .SH "FILES" .TP \fB\fI/usr/local/etc/zonecheck/zc.conf\fB\fR The default configuration file. .TP \fB\fI/usr/local/etc/zonecheck/*.profile\fB\fR The test sequence to use for different domains. .TP \fB\fI/usr/local/libexec/zc/test\fB\fR Contains the code of the tests performed by ZoneCheck. .TP \fB\fI/usr/local/libexec/zc/locale\fB\fR Contains the different translations. .TP \fB\fI/usr/local/libexec/zc/www\fB\fR Contains a website sample for the web interface. . .SH EXAMPLES .LP Test the domain_name with IPv6 only connectivity, print a summary information about the tested domain as well as explanations and details of failed tests. .RS .nf \fBzonecheck -6 --verbose=i,x,d domain_name\fP .fi .RE .LP Ask for the 'error' message associated with the test 'soa'. .RS .nf \fBzonecheck --testdesc error -T soa\fP .fi .RE .LP Only print tests which have failed and the result (succeed/failed), this would be ideal for giving people, through email fir example, a short description of why their domains are not correctly configured. .RS .nf \fBzonecheck -q -vn,d,x,f domain_name\fP .fi .RE .LP If you want to test your domain, you will certainly like to use these parameters (the use of IPv4 only as been forced because now people have computer with IPv6 stack but very few have the IPv6 connectivity, so autodetection will failed). .RS .nf \fBzonecheck -4 -vi,x,d,c domain_name\fP .fi .RE . .SH "SEE ALSO" \fIRFC 1033\fR, \fIRFC 1034\fR, \fIRFC 1035\fR, \fBdig\fR(1) . .SH "AUTHORS" Stephane D'Alu with the help of people working at AFNIC is the author of this version, but don't forget also to take a look at the CREDITS file available in the distribution. . .SH "HISTORY" ZoneCheck was initiated and developed by engineers working at NIC France (INRIA's service) to check the correct configuration of a zone before delegating a domain name under .fr. Its development continued at AFNIC, which took over the activities of NIC France on January 1 1998. ZoneCheck-1.* was created in 1995 by Benoit Grange and has been maintained by him until 1997. The prototype was a script using the dig command, which evolved into a perl program based on the DNS resolver Resolv5. Vincent Gillet maintained the programme in 1998. This task has been taken over by Erwan Mas and Philippe Lubrano from 1998 until now. ZoneCheck-2.* is a rewrite from scratch done in ruby at the end of 2002 by Stephane D'Alu, so as to create a modular and extensible version. And is the current version of ZoneCheck. . .SH "BUGS" Please send problems, bugs, questions, desirable enhancements, source code contributions, by using the interface provided by: .LP .RS http://savannah.nongnu.org/projects/zonecheck .RE .LP You can also consult the \fIZoneCheck\fP homepage for more information: .LP .RS http://www.zonecheck.fr/ .RE . .\" Local Variables: .\" mode: nroff .\" End: zonecheck-3.0.5/test/000077500000000000000000000000001226210254100144425ustar00rootroot00000000000000zonecheck-3.0.5/test/axfr.rb000066400000000000000000000030471226210254100157330ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: axfr.rb,v 1.10 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.10 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNetworkAddress ## ## Check domain NS records ## class AXFR < Test with_msgcat 'test/axfr.%s' #-- Checks -------------------------------------------------- # DESC: Zone transfer is possible def chk_axfr(ns, ip) true end # DESC: Zone transfer is not empty def chk_axfr_empty(ns, ip) true end # DESC: Zone transfer containts only valid labels def chk_axfr_valid_labels(ns, ip) true end end end zonecheck-3.0.5/test/connectivity.rb000066400000000000000000000105451226210254100175120ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: connectivity.rb,v 1.24 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.24 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ##### # # WARN: # - 'chk_icmp' contains system dependant 'ping' command # although -q and -c option seems to be fairly standard, # unfortunately 'ping' is not part of POSIX # # OPEN: # - 'chk_udp' perhaps used a SOA request instead of a 'server status' # in case the tested DNS uses view # # BUGFIX: # - chk_udp: recvfrom reject datagram bigger than the requested size # instead of copying the beginning # using the NResolv::DNS::UDPSize instead of 1 byte # require 'framework' require 'timeout' module CheckNetworkAddress ## ## Check nameserver connectivity (ICMP, UDP, TCP) ## ## - as request are directly made to the DNS (no CacheManager) ## the tests won't be affected by the transport flags ## class Connectivity < Test with_msgcat 'test/connectivity.%s' def initialize(*args) super(*args) @ping4_cmd = const('ping4') @ping6_cmd = const('ping6') end #-- Checks -------------------------------------------------- # DESC: Test TCP connectivity with DNS server def chk_tcp(ns, ip) # The idea is to open a TCP connection # if no one is listening => Errno::ECONNREFUSED # if there is a firewal (timeout) => Errno::EINVAL # Errno::ECONNRESET # The total timeout has been forced to 8 seconds # as with the chk_udp test msg_dr = Dnsruby::Message::new(@domain.name.to_s,"ANY") rawmsg_dr = msg_dr.encode() sock = nil begin timeout(8) { sock = TCPSocket::new(ip.to_s, 53) sock.write([rawmsg_dr.length].pack('n')) sock.write(rawmsg_dr) lenhdr = sock.read(2) return false if lenhdr.nil? || lenhdr.size != 2 len = lenhdr.unpack('n')[0] reply = sock.read(len) } true rescue Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EINVAL, TimeoutError false ensure sock.close unless sock.nil? end end # DESC: Test UDP connectivity with DNS server def chk_udp(ns, ip) # The idea is to send 25 'query' concerning the domain in 5 seconds # if we received one answer within 8 seconds (dont care about # its content, we consider it sucessful) msg_dr = Dnsruby::Message::new(@domain.name.to_s,"ANY") rawmsg_dr = msg_dr.encode() sock = nil thr = nil begin case ip when Dnsruby::IPv4 protocol = Socket::AF_INET when Dnsruby::IPv6 protocol = Socket::AF_INET6 else protocol = nil raise ArgumentError, 'Argument should be an address' end sock = UDPSocket::new(protocol) sock.connect(ip.to_s, 53) thr = Thread::new { (1..25).each { sock.write(rawmsg_dr) ; sleep(0.2) } } timeout(8) { sock.recv(512) } true rescue Errno::ECONNREFUSED, TimeoutError false ensure thr.kill unless thr.nil? sock.close unless sock.nil? end end # DESC: Test if host is alive (watch for firewall) def chk_icmp(ns, ip) # Build ping command ping_tmpl = case ip when Dnsruby::IPv4 then @ping4_cmd when Dnsruby::IPv6 then @ping6_cmd else raise 'INTERNAL: Unknown address format' end ping_cmd = ping_tmpl % [ ip.to_s ] # Do ping dbgmsg(ns, ip) { "Executing: #{ping_cmd}" } system(ping_cmd) end end end zonecheck-3.0.5/test/dnssec.rb000066400000000000000000000225031226210254100162500ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: dnssec.rb,v 1.11 2011/03/11 16:09:18 kmkaplan Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.11 $ # DATE : $Date: 2011/03/11 16:09:18 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' require 'time' module CheckDNSSEC ## ## Check domain NS records ## class DNSSEC < Test with_msgcat 'test/dnssec.%s' #-- Checks -------------------------------------------------- def chk_edns(ns, ip) # begin msg = Dnsruby::Message::new(@domain.name, "ANY") optrr = Dnsruby::RR::OPT.new(4096) optrr.dnssec_ok = true msg.add_additional(optrr) msg.do_caching = false resolver = Dnsruby::Resolver::new({:nameserver => ip.to_s}) resolver.do_caching = false resolver.dnssec = false ret = resolver.send_message(msg) resolver = nil return false if ret.nil? || ret.additional.empty? ret.additional.each { |add| return true if add.type == "OPT" && add.payloadsize > 1024 } return false # rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout # return false # end end def chk_has_soa_rrsig(ns, ip) ret = rrsig(ip,"SOA") is_not_empty = ! ret.empty? #return {"dig" => ret.to_s} unless is_not_empty return is_not_empty end def chk_one_dnskey(ns, ip) ! dnskey(ip).empty? end def chk_several_dnskey(ns, ip) dnskey(ip).size >= 2 end def chk_zsk_and_ksk(ns, ip) zsk = false ksk = false dnskey(ip).each { |key| zsk = true if key.flags%2 == 1 ksk = true if key.flags%2 == 0 } #return { "dig" => dnskey(ip) } unless zsk && ksk return zsk && ksk end def chk_algorithm(ns,ip) rrsig(ip,"SOA").each {|sig| if [Dnsruby::Algorithms.RSASHA1, Dnsruby::Algorithms.RSASHA256, Dnsruby::Algorithms.RSASHA512, Dnsruby::Algorithms.RSASHA1_NSEC3_SHA1, Dnsruby::Algorithms.DSA, Dnsruby::Algorithms.DSA_NSEC3_SHA1].include?(sig.algorithm) return true end } return {"error" => $mc.get('dnssec:algorithm:unknown')} end def chk_key_length(ns,ip) keys = dnskey(ip) keys.each {|key| pkey = key.public_key case key.algorithm when Dnsruby::Algorithms.RSASHA1 if key.key_length < 1024 && !(key.sep_key?) return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA 1"} elsif key.key_length < 2048 && key.sep_key? return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA 1"} end when Dnsruby::Algorithms.RSASHA256 if key.key_length < 1024 && !(key.sep_key?) return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA 256"} elsif key.key_length < 2048 && key.sep_key? return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA 256"} end when Dnsruby::Algorithms.RSASHA512 if key.key_length < 1024 && !(key.sep_key?) return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA 512"} elsif key.key_length < 2048 && key.sep_key? return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA 512"} end when Dnsruby::Algorithms.RSASHA1_NSEC3_SHA1 if key.key_length < 1024 && !(key.sep_key?) return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA1 NSEC3 SHA1"} elsif key.key_length < 2048 && key.sep_key? return {"keylength" => key.key_length.to_s, "algo" => "RSA SHA1 NSEC3 SHA1"} end when Dnsruby::Algorithms.DSA if key.key_length < 1024 && !(key.sep_key?) return {"keylength" => key.key_length.to_s, "algo" => "DSA"} elsif key.key_length < 2048 && key.sep_key? return {"keylength" => key.key_length.to_s, "algo" => "DSA"} end when Dnsruby::Algorithms.DSA_NSEC3_SHA1 if key.key_length < 1024 && !(key.sep_key?) return {"keylength" => key.key_length.to_s, "algo" => "DSA NSEC3 SHA1"} elsif key.key_length < 2048 && key.sep_key? return {"keylength" => key.key_length.to_s, "algo" => "DSA NSEC3 SHA1"} end end } true end def chk_soa_rrsig_expiration(ns,ip) sig = rrsig(ip,"SOA")[0] return true if Time::now.to_i < sig.expiration - 0.1 * (sig.expiration - sig.inception) { "date" => Time.at(sig.expiration) } end def chk_soa_rrsig_validity_period(ns,ip) sig = rrsig(ip,"SOA")[0] min = const('rrsig:validityperiod:min').to_i max = const('rrsig:validityperiod:max').to_i return true if (sig.expiration - sig.inception) > min && (sig.expiration - sig.inception) > sig.ttl && (sig.expiration - sig.inception) < max { "period" => (sig.expiration - sig.inception), "min" => min, "max" => max, "ttl" => sig.ttl } end def chk_verify_soa_rrsig(ns,ip) begin sv = Dnsruby::SingleVerifier::new(Dnsruby::SingleVerifier::VerifierType::ANCHOR) soa = soa(ip).resource soa_rrsig = rrsig(ip,"SOA")[0].resource return false if soa_rrsig.nil? key = nil dnskey(ip).each { |keyTemp| key = keyTemp.resource if keyTemp.resource.key_tag == soa_rrsig.key_tag } soa_rrset = Dnsruby::RRSet::new(soa) soa_rrset.add(soa_rrsig) return false if key.nil? || soa_rrset.nil? return sv.verify_rrset(soa_rrset,key) rescue Dnsruby::VerifyError => e return false end end def chk_ds_and_dnskey_coherence(ns,ip) # Find all given DS otherwise return false if given_ds && !given_ds.all? {|ds| if ds.digest_type && ds.digestbin && ds.key_tag && ds.algorithm dnskey(ip).detect {|keytemp| ds.check_key(keytemp) } else dnskey(ip).detect {|keytemp| dstemp = Dnsruby::RR.create({ :name => @domain.name, :type => Dnsruby::Types.DS, :digest => ds.digest, :digest_type => ds.digest_type, :digestbin => ds.digestbin, :key_tag => keytemp.key_tag, :algorithm => keytemp.algorithm}) dstemp.check_key(keytemp) } end } return false end # Find all given DNSKEY otherwise return false if given_dnskey && !given_dnskey.all? {|dnskey| dnskey(ip).detect {|keytemp| keytemp.key == dnskey.key && keytemp.sep_key? } } return false end return true end def tst_dnssec_policy(ns,ip) if is_dnssec_mandatory? if edns == "never" raise ArgumentError, 'Conflict between --edns never and --securedelegation, try with --edns always or auto' end return "full" else unless edns == "never" begin ret = rrsig(ip,"SOA") is_not_empty = ! ret.empty? return "off" unless is_not_empty return "lax" if is_not_empty rescue Dnsruby::ResolvError => e return "off" rescue Dnsruby::ResolvTimeout => e return "off" end else return "off" end end end def tst_a_ds_or_dnskey_is_given(ns,ip) if given_ds.nil? && given_dnskey.nil? return "false" else return "true" end end end end zonecheck-3.0.5/test/generic.rb000066400000000000000000000166111226210254100164100ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: generic.rb,v 1.33 2011/03/08 14:07:26 kmkaplan Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.33 $ # DATE : $Date: 2011/03/08 14:07:26 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckGeneric ## ## Check syntax validity of the domain name ## class DomainNameSyntax < Test with_msgcat 'test/generic.%s' #-- Checks -------------------------------------------------- # DESC: A domainname should only contains A-Z a-Z 0-9 '-' '.' def chk_dn_sntx @domain.name.to_s =~ /^[A-Za-z0-9\-\.]*$/ end # DESC: A domainname should not countain a double hyphen unless it is an ACE prefix def chk_dn_dbl_hyph name = @domain.name.to_s.gsub(/(xn--)/,'') (!(name =~ /--/)) end # DESC: A domainname should not start or end with an hyphen def chk_dn_orp_hyph ! (@domain.name.to_s =~ /(^|\.)-|-(\.|$)/) end end ## ## Check basic absurdity with the nameserver IP addresses ## class ServerAddress < Test with_msgcat 'test/generic.%s' #-- Initialization ------------------------------------------ def initialize(*args) super(*args) @cache.create(:ip, :by_subnet) end #-- Shortcuts ----------------------------------------------- def ip @cache.use(:ip) { ip = @domain.ns.collect { |ns, ips| ips } ip.flatten! ip } end def ns_from_ip(ip) @domain.ns.each { |ns, ips| return ns if ips.include?(ip) } nil end def by_subnet @cache.use(:by_subnet) { nethosts = {} ip.each { |i| net = case i # decide of subnet size: when Dnsruby::IPv4 then prefix_of(i,28) # /28 for IPv4 when Dnsruby::IPv6 then prefix_of(i,64) # /64 for IPv6 end nethosts[net] = [ ] unless nethosts.has_key?(net) nethosts[net] << i } nethosts } end #-- Checks -------------------------------------------------- # DESC: Addresses should be distincts def chk_ip_distinct # Ok all addresses are distincts return true if ip == ip.uniq # Create data for failure handling hosts = {} @domain.ns.each { |ns, ips| ips.each { |i| hosts[i.to_s] = [ ] unless hosts.has_key?(i.to_s) hosts[i.to_s] << ns.to_s } } hosts.delete_if { |k, v| v.size < 2 } hosts.each { |k, v| # Got at least 1 entry as ip != ip.uniq return { 'ip' => k.to_s, 'ns' => v.join(', ').to_s } } end # DESC: Addresses should avoid belonging to the same network def chk_ip_same_net # Only keep list of hosts on same subnet same_net = by_subnet.dup.delete_if { |k, v| v.size < 2 } # Ok all hosts are on different subnets return true if same_net.empty? # Create output data for failure subnetlist = [] same_net.each { |k, v| hlist = (v.collect { |i| ns = ns_from_ip(i) }).join(', ') prefix = case k when Dnsruby::IPv4 then 28 when Dnsruby::IPv6 then 64 end subnetlist << "#{k}/#{prefix} (#{hlist})" } return { 'subnets' => subnetlist.join(', ').to_s } end # DESC: Addresses should avoid belonging ALL to the same network # WARN: Test is wrong in case of IPv4 and IPv6 def chk_ip_all_same_net # Ok not all hosts are on the same subnet return true unless ((by_subnet.size == 1) && (by_subnet.values[0].size > 1)) # Create output data for failure subnet = by_subnet.keys[0] prefix = case subnet when Dnsruby::IPv4 then 28 when Dnsruby::IPv6 then 64 end return { 'subnet' => "#{subnet.to_s}/#{prefix.to_s}" } end # DESC: Addresses should avoid belonging ALL to the same AS def chk_all_same_asn asn = ip.collect { |addr| name = '' case addr when Dnsruby::IPv4 name = ('%d.%d.%d.%d' % addr.address.unpack('CCCC').reverse) + '.asn.routeviews.org.' when Dnsruby::IPv6 name = addr.address.unpack("H32")[0].split(//).reverse.join(".") + '.asn.routeviews.org.' else raise ArgumentError, 'Argument should be an address' end aname = Dnsruby::Name::create(name) begin txtres = @cm[nil].txt(aname) (txtres[0].nil?) ? nil : (txtres[0].strings[0]) rescue Dnsruby::NXDomain nil end } asn.uniq! asn.size > 1 ? true : { 'asn' => asn[0].to_s } end end ## ## Check for nameserver! ## class NameServers < Test with_msgcat 'test/generic.%s' #-- Checks -------------------------------------------------- # DESC: A domain should have a nameserver! def chk_one_ns @domain.ns.length >= 1 end # DESC: A domain should have at least 2 nameservers def chk_several_ns @domain.ns.length >= 2 end end ## ## ## class Delegation < Test with_msgcat 'test/generic.%s' #-- Initialisation ------------------------------------------ def initialize(*args) super(*args) @querysize = const('delegation_query_size').to_i end #-- Checks -------------------------------------------------- def chk_delegation_udp512 # TODO dummyttl = 3600 msg = Dnsruby::Message::new(".", "NS") @domain.ns.each { |ns, ips| rr = Dnsruby::RR::IN::NS::new(ns) rr.type = "NS" rr.klass = "IN" rr.name = @domain.name rr.ttl = dummyttl msg.add_authority(rr) } excess = (msg.encode.size + @querysize-1) - 512 return true if excess <= 0 { 'excess' => excess.to_s } end def chk_delegation_udp512_additional dummyttl = 3600 msg = Dnsruby::Message::new(".", "NS") @domain.ns.each { |ns, ips| rr = Dnsruby::RR::IN::NS::new(ns) rr.type = "NS" rr.klass = "IN" rr.ttl = dummyttl rr.name = @domain.name msg.add_answer(rr) if ns == @domain.name || ns.subdomain_of?(@domain.name) ips.each { |ip| if ip.class == Dnsruby::IPv4 rr2 = Dnsruby::RR::IN::A::new(ip) rr2.name = ns rr2.type = "A" else if ip.class == Dnsruby::IPv6 rr2 = Dnsruby::RR::IN::AAAA::new(ip) rr2.name = ns rr2.type = "AAAA" else rr2 = Dnsruby::RR::IN::A::new(ip) rr2.name = ns rr2.type = "A" end end rr2.klass = "IN" rr2.ttl = dummyttl msg.add_additional(rr2) } end } rawmsg = msg.encode excess = (rawmsg.size + @querysize-1) - 512 return true if excess <= 0 { 'excess' => excess.to_s } end end end zonecheck-3.0.5/test/interop.rb000066400000000000000000000040471226210254100164540ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: interop.rb,v 1.6 2010/06/08 08:57:35 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/09/23 15:33:12 # REVISION : $Revision: 1.6 $ # DATE : $Date: 2010/06/08 08:57:35 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNetworkAddress ## ## Check nameserver interoperability ## class Interop < Test with_msgcat 'test/interop.%s' #-- Shortcuts ----------------------------------------------- def dflt_exception(ip, name=@domain.name) a_exception = nil begin a(ip, name) rescue Dnsruby::ResolvError => a_exception rescue Dnsruby::ResolvTimeout => a_exception end a_exception end def validate_record(ns, ip) begin yield [ns, ip] rescue Dnsruby::NotImp rescue Dnsruby::ResolvError => e return false if e.class != dflt_exception(ip).class rescue Dnsruby::ResolvTimeout => e return false if e.class != dflt_exception(ip).class end true end #-- Checks -------------------------------------------------- # DESC: def chk_cname(ns, ip) true end # DESC: def chk_aaaa(ns, ip) validate_record(ns, ip) { aaaa(ip, @domain.name) } end end end zonecheck-3.0.5/test/loopback.rb000066400000000000000000000047721226210254100165730ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: loopback.rb,v 1.19 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/09/11 11:20:17 # REVISION : $Revision: 1.19 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNetworkAddress ## ## Check for loopback network delegation/resolution ## class Loopback < Test with_msgcat 'test/loopback.%s' #-- Constants ----------------------------------------------- IPv4LoopbackName = Dnsruby::IPv4::create("127.0.0.1").to_name IPv6LoopbackName = Dnsruby::IPv6::create("::1").to_name #-- Helper -------------------------------------------------- def ipv4_delegated?(ip) (!soa(ip, Dnsruby::Name::create(IPv4LoopbackName.labels[1..-1])).nil? || !soa(ip, Dnsruby::Name::create(IPv4LoopbackName.labels[2..-1])).nil? || !soa(ip, Dnsruby::Name::create(IPv4LoopbackName.labels[3..-1])).nil? ) end def ipv6_delegated?(ip) !soa(ip, Dnsruby::Name::create(IPv6LoopbackName.labels[1..-1])).nil? end #-- Checks -------------------------------------------------- # DESC: loopback network should be delegated def chk_loopback_delegation(ns, ip) case ip when Dnsruby::IPv4 then return ipv4_delegated?(ip) when Dnsruby::IPv6 then return ipv4_delegated?(ip) && ipv6_delegated?(ip) end false end # DESC: loopback host reverse should exists def chk_loopback_host(ns, ip) case ip when Dnsruby::IPv4 then return !ptr(ip, IPv4LoopbackName).empty? when Dnsruby::IPv6 then return !ptr(ip, IPv4LoopbackName).empty? && !ptr(ip, IPv6LoopbackName).empty? end false end end end zonecheck-3.0.5/test/mail.rb000066400000000000000000000150471226210254100157200ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: mail.rb,v 1.40 2010/10/22 14:21:22 bortzmeyer Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/09/25 19:14:21 # REVISION : $Revision: 1.40 $ # DATE : $Date: 2010/10/22 14:21:22 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # TODO: remove temporary hack where we are looking at the local resolver # due to bestresolverip not correctly implemented # require 'timeout' require 'framework' require 'mail' module CheckExtra ## ## Check domain NS records ## class Mail < Test with_msgcat 'test/mail.%s' CONNECTION_TIMEOUT = 20 #-- Initialisation ------------------------------------------ def initialize(*args) super(*args) @fake_dest = const('fake_mail_dest') @fake_from = const('fake_mail_from') @fake_user = const('fake_mail_user') @fake_host = const('fake_mail_host') @timeout_open = const('smtp:open:timeout').to_i @timeout_session = const('smtp:session:timeout').to_i end #-- Shortcuts ----------------------------------------------- def bestmx(name) begin pref, exch = 65536, nil mxlist = mx(bestresolverip(name), name) mxlist = mx(nil, name) if mxlist.empty? return nil if mxlist.nil? mxlist.each { |m| if m.preference < pref pref, exch = m.preference, m.exchange end } exch rescue Dnsruby::NXDomain nil end end def mhosttest(mdom, mhost, dbgio=nil) # Mailhost and IP mip = addresses(mhost, bestresolverip(mhost))[0] mip = addresses(mhost, nil)[0] if mip.nil? raise "No host servicing mail for domain #{mdom}" if mip.nil? # Execute test on mailhost mrelay = ZoneCheck::Mail::new(mdom, mip.rdata.to_s, dbgio) mrelay.open(@timeout_open) begin Timeout::timeout(@timeout_session) { mrelay.banner mrelay.helo(@fake_host) mrelay.fake_info(@fake_user, @fake_dest, @fake_from) yield mrelay mrelay.quit } ensure mrelay.close end end def openrelay(mdom, mhost) status = nil begin mhosttest(mdom, mhost) { |mrelay| return status = mrelay.test_openrelay } ensure dbgmsg { [ "not an openrelay : #{DBG.status2str(status, false)}", " on domain #{mdom.to_s} using relay #{mhost.to_s}" ] } end end def testuser(user, mdom, mhost) status = nil dbgio = [] begin mhosttest(mdom, mhost, dbgio) { |mrelay| return status = mrelay.test_userexists(user) } ensure dbgmsg { [ "mail for user #{user.to_s} : #{DBG.status2str(status)}", " on domain #{mdom.to_s} using relay #{mhost.to_s}" ] + dbgio } end end #-- Checks -------------------------------------------------- # DESC: Check that the best MX for hostmaster is not an openrelay def chk_mail_openrelay_hostmaster # TODO rname = soa(bestresolverip).rname mdom = Dnsruby::Name::create(".") mdom = Dnsruby::Name::create(rname.labels[1..-1]) if rname.labels.size > 1 mhost = bestmx(mdom) || mdom return true unless openrelay(mdom, mhost) { 'mailhost' => mhost.to_s, 'hostmaster' => "#{rname[0].string}@#{mdom.to_s}", 'from_host' => @fake_from.to_s, 'to_host' => @fake_dest.to_s } end # DESC: Check that the best MX for the domain is not an openrelay def chk_mail_openrelay_domain # TODO mdom = @domain.name mhost = bestmx(mdom) || mdom return true unless openrelay(mdom, mhost) { 'mailhost' => mhost.to_s, 'from_host' => @fake_from.to_s, 'to_host' => @fake_dest.to_s } end # DESC: Check that hostmaster address is valid def chk_mail_delivery_hostmaster # TODO rname = soa(bestresolverip).rname mdom = Dnsruby::Name::new(rname.labels[1..-1]) user = "#{rname[0].string}@#{mdom}" mxlist = mx(bestresolverip(mdom), mdom) mxlist = mx(nil, mdom) if mxlist.empty? mxlist.sort! { |a,b| a.preference <=> b.preference } if mxlist.empty? return true if testuser(user, mdom, mdom) else mxlist.each { |m| begin return true if testuser(user, mdom, m.exchange) rescue TimeoutError, Errno::ECONNREFUSED end } end { 'hostmaster' => user.to_s, 'mxlist' => mxlist.collect { |mx| mx.exchange.to_s}.join(', ')} end # DESC: check for MX or A def chk_mail_mx_or_addr ip = bestresolverip begin !mx(ip).empty? || !addresses(@domain.name, ip).empty? rescue Dnsruby::NXDomain false end end # DESC: Check that postmaster address is valid def chk_mail_delivery_postmaster # TODO mdom = @domain.name user = "postmaster@#{mdom}" mxlist = mx(bestresolverip(mdom), mdom) mxlist = mx(nil, mdom) if mxlist.empty? mxlist.sort! { |a,b| a.preference <=> b.preference } if mxlist.empty? return true if testuser(user, mdom, mdom) else mxlist.each { |m| begin return true if testuser(user, mdom, m.exchange) rescue TimeoutError, Errno::ECONNREFUSED end } end return false { 'postmaster' => user.to_s, 'mxlist' => mxlist.collect { |mx| mx.exchange.to_s }.join(', ') } end # DESC: def chk_mail_hostmaster_mx_cname rname = soa(bestresolverip).rname mdom = Dnsruby::Name::create(rname.labels[1..-1]) if rname.labels.size > 1 mhost = bestmx(mdom) return true if mhost.nil? # No MX ! is_cname?(mhost) end #-- Tests --------------------------------------------------- # def tst_mail_delivery begin ip = bestresolverip if !mx(ip).empty? then 'MX' elsif !addresses(@domain.name, ip).empty? then 'A' else 'nodelivery' end rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout return 'nodelivery' end end end end zonecheck-3.0.5/test/misc.rb000066400000000000000000000100121226210254100157140ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: misc.rb,v 1.37 2010/06/23 12:51:35 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.37 $ # DATE : $Date: 2010/06/23 12:51:35 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ##### # # TODO: # - move these functions into another file # require 'framework' module CheckNetworkAddress ## ## ## class Misc < Test with_msgcat 'test/misc.%s' #-- Checks -------------------------------------------------- # DESC: def chk_ns_reverse(ns, ip) #ip_name = Dnsruby::Name::create(ip) ip_name = ip.to_name srv = rec(ip) ? ip : nil begin return ! ptr(srv, ip_name).empty? rescue Dnsruby::NXDomain return false end end def chk_ns_matching_reverse(ns, ip) #ip_name = Dnsruby::Name::create(ip) ip_name = ip.to_name srv = rec(ip) ? ip : nil begin ptrlist = ptr(srv, ip_name) rescue Dnsruby::NXDomain return false end return true if ptrlist.empty? ptrlist.each { |rev| seen = { rev => true } name = rev.rdata return true if name == ns while name = is_cname?(name, ip) if seen[name] then raise "Loop in CNAME chain when looking for #{rev.ptrdname}" else seen[name] = true end return true if name == ns end } false end # DESC: Ensure coherence between given (param) primary and SOA def chk_given_nsprim_vs_soa(ns, ip) mname = soa(ip).mname if @domain.ns[0][0] != mname @domain.ns[1..-1].each { |nsname, | return { 'given_primary' => @domain.ns[0][0].to_s, 'primary' => mname.to_s } if nsname == mname } end true end # DESC: Ensure coherence between given (param) nameservers and NS def chk_given_ns_vs_ns(ns, ip) nslist_from_ns = ns(ip).collect{ |n| n.domainname.to_s.downcase } nslist_from_param = @domain.ns.collect { |n, ips| n.to_s.downcase } return true if nslist_from_ns.unsorted_eql?(nslist_from_param) { 'list_from_ns' => nslist_from_ns.sort.join(', ').to_s, 'list_from_param' => nslist_from_param.sort.join(', ').to_s } end # DESC: Ensure that a server is not recursive def chk_not_recursive(ns, ip) ! rec(ip) end # DESC: Ensure that a server claiming to be recursive really is it def chk_correct_recursive_flag(ns, ip) return true unless rec(ip) namespace = case ip when Dnsruby::IPv4 then "in-addr.arpa." when Dnsruby::IPv6 then "ip6.arpa." else nil end dbgmsg(ns, ip) { 'asking SOA for: ' + [ @domain.name.labels[-1] || Dnsruby::Name::create(".").to_s, Dnsruby::Name::create(namespace).to_s ].join(', ') } soa(ip, @domain.name.labels[-1] || Dnsruby::Name::create(".")) && soa(ip, Dnsruby::Name::create(namespace)) end # # DESC: # def chk_rir_inetnum(ns, ip) # true # end # # DESC: # def chk_rir_route(ns, ip) # true # end #-- Tests --------------------------------------------------- # def tst_recursive_server(ns, ip) begin rec(ip) ? 'true' : 'false' rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout return 'false' end end end end zonecheck-3.0.5/test/mx.rb000066400000000000000000000060411226210254100154140ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: mx.rb,v 1.25 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.25 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNetworkAddress ## ## Check domain MX record ## class MX < Test with_msgcat 'test/mx.%s' #-- Checks -------------------------------------------------- # DESC: MX entries should exists def chk_mx(ns, ip) ! mx(ip).empty? end # DESC: MX answers should be authoritative def chk_mx_auth(ns, ip) mx(ip, @domain.name) # request should be done twice mx(ip, @domain.name, true)[0].aa # so we need to force the cache end # DESC: Ensure coherence between MX and ANY def chk_mx_vs_any(ns, ip) mx_from_any = any(ip, Dnsruby::RR::IN::MX) return true if mx_from_any.empty? # MX not necessary in ANY mx(ip).unsorted_eql?(mx_from_any) end # DESC: MX exchanger should have a valid hostname syntax def chk_mx_sntx(ns, ip) mx(ip).each { |m| if ! is_valid_hostname?(m.exchange) return false end } true end # DESC: MX record should not point to CNAME alias def chk_mx_cname(ns, ip) mx(ip).each { |m| if cname = is_cname?(m.exchange, ip) return { 'mx' => m.exchange.to_s, 'cname' => cname.to_s } end } true end # DESC: MX exchange should be resolvable def chk_mx_ip(ns, ip) mx(ip).each { |m| mx_name = m.exchange return { 'mx' => mx_name.to_s } unless is_resolvable?(mx_name, ip, @domain.name) } true end # DESC: check for absence of wildcard MX def chk_mx_no_wildcard(ns, ip) host = const('inexistant_hostname') host_fq = Dnsruby::Name::create(host + "." + @domain.name.to_s) begin mx(ip, host_fq).empty? rescue Dnsruby::NXDomain return true end end #-- Tests --------------------------------------------------- def tst_mail_by_mx_or_a(ns, ip) begin if !mx(ip).empty? then 'MX' elsif !addresses(@domain.name, ip).empty? then 'A' else 'nodelivery' end rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout return 'nodelivery' end end end end zonecheck-3.0.5/test/nameserver.rb000066400000000000000000000076511226210254100171470ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: nameserver.rb,v 1.21 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.21 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNameServer ## ## Check accessibility of nameserver ## ## - these tests are performed without contacting the nameserver ## (see modules CheckNetworkAddress for that) ## class ServerAccess < Test with_msgcat 'test/nameserver.%s' BOGON_IP = Dnsruby::IPv4::create('127.0.0.2') #-- Initialization ------------------------------------------ def initialize(*args) super(*args) @cache.create(:ip) end #-- Shortcuts ----------------------------------------------- def ip(ns) @cache.use(:ip, ns) { @domain.ns.assoc(ns)[1] } end #-- Checks -------------------------------------------------- # DESC: Nameserver IP addresses should be public! def chk_ip_private(ns) ip(ns).each { |addr| case addr when Dnsruby::IPv4 # 10.0.0.0 - 10.255.255.255 (10/8 prefix) # 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) # 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) bytes = addr.address.unpack('CCCC') return false if (((bytes[0] == 10)) || ((bytes[0] == 172) && (bytes[1]&0xf0 == 16)) || ((bytes[0] == 192) && (bytes[1] == 168))) when Dnsruby::IPv6 # TODO return false if false else raise ArgumentError, 'Argument should be an address' end } return true end #-- Checks -------------------------------------------------- # DESC: Nameserver IP addresses should not be local def chk_ip_local(ns) ip(ns).each { |addr| case addr when Dnsruby::IPv4 # 127.0.0.0 - 127.255.255.255 (127/8 prefix) bytes = addr.address.unpack('CCCC') return false if (bytes[0] == 127) when Dnsruby::IPv6 # TODO return false if false else raise ArgumentError, 'Argument should be an address' end } return true end # DESC: def chk_ip_bogon(ns) bogon = [] ip(ns).each { |addr| name = "" case addr when Dnsruby::IPv4 name = ('%d.%d.%d.%d' % addr.address.unpack('CCCC').reverse) + '.bogons.cymru.com.' when Dnsruby::IPv6 name = addr.address.unpack("H32")[0].split(//).reverse.join(".") + '.bogons.cymru.com.' else raise ArgumentError, 'Argument should be an address' end bname = Dnsruby::Name::create(name) begin case addr when Dnsruby::IPv4 @cm[nil].addresses(bname).each { |baddr| if baddr == BOGON_IP bogon << addr break end } end rescue Dnsruby::NXDomain => e end } return true if bogon.empty? { 'addresses' => bogon.collect{|e| e.to_s}.join(', ').to_s } end end end zonecheck-3.0.5/test/ns.rb000066400000000000000000000043531226210254100154140ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: ns.rb,v 1.21 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.21 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNetworkAddress ## ## Check domain NS records ## class NS < Test with_msgcat 'test/ns.%s' #-- Checks -------------------------------------------------- # DESC: NS entries should exists def chk_ns(ns, ip) ! ns(ip).empty? end # DESC: NS answers should be authoritative def chk_ns_auth(ns, ip) ns(ip, @domain.name) # request should be done twice ns(ip, @domain.name, true)[0].aa # so we need to force the cache end # DESC: Ensure coherence between NS and ANY def chk_ns_vs_any(ns, ip) ns(ip).unsorted_eql?(any(ip, Dnsruby::RR::IN::NS)) end # DESC: NS record should have a valid hostname syntax def chk_ns_sntx(ns, ip) ns(ip).each { |n| if ! is_valid_hostname?(n.rdata) return false end } true end # DESC: NS record should not point to CNAME alias def chk_ns_cname(ns, ip) ns(ip).each { |n| return false if is_cname?(n.rdata, ip) } true end # DESC: NS host should be resolvable def chk_ns_ip(ns, ip) ns(ip).each { |n| unless is_resolvable?(n.rdata, ip, @domain.name) return { 'name' => n.rdata.to_s } end } true end end end zonecheck-3.0.5/test/rootserver.rb000066400000000000000000000105551226210254100172070ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: rootserver.rb,v 1.21 2010/06/08 09:15:40 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.21 $ # DATE : $Date: 2010/06/08 09:15:40 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' require 'yaml' module CheckNetworkAddress class RootServerList def initialize(rootserver) @rootserver = { } rootserver.each { |k, v| @rootserver[Dnsruby::Name::create(k)] = v.collect { |addr| if addr =~ Dnsruby::IPv4::Regex Dnsruby::IPv4::create(addr) elsif addr =~ Dnsruby::IPv6::Regex Dnsruby::IPv6::create(addr) end } } end def [](idx) ; @rootserver[idx] ; end def size ; @rootserver.size ; end def each ; @rootserver.each { |k,v| yield(k,v) } ; end def keys ; @rootserver.keys ; end def self.from_hintfile(filename=nil) filename = "#{$zc_config_dir}/rootservers" if filename.nil? File::open(filename) { |io| return RootServerList::new(YAML::load(io)) } end ICANN = RootServerList::new({ 'a.root-servers.net.' => [ '198.41.0.4' ], 'b.root-servers.net.' => [ '128.9.0.107' ], 'c.root-servers.net.' => [ '192.33.4.12' ], 'd.root-servers.net.' => [ '128.8.10.90' ], 'e.root-servers.net.' => [ '192.203.230.10' ], 'f.root-servers.net.' => [ '192.5.5.241' ], 'g.root-servers.net.' => [ '192.112.36.4' ], 'h.root-servers.net.' => [ '128.63.2.53' ], 'i.root-servers.net.' => [ '192.36.148.17' ], 'j.root-servers.net.' => [ '192.58.128.30' ], 'k.root-servers.net.' => [ '193.0.14.129' ], 'l.root-servers.net.' => [ '199.7.83.42' ], 'm.root-servers.net.' => [ '202.12.27.33' ] }) Default = (Proc::new { rootserver = ICANN if f = $rootserver_hintfile begin rootserver = RootServerList.from_hintfile(f) rescue YAML::ParseError,SystemCallError => e Dbg.msg(DBG::CONFIG, "Unable to read/parse rootserver hint file (#{e})") end end rootserver }).call @@current = Default def self.current=(rs) ; @@current = rs ; end def self.current ; @@current ; end end class RootServer < Test with_msgcat 'test/rootserver.%s' #-- Checks -------------------------------------------------- # DESC: root server list should be available def chk_root_servers(ns, ip) ! ns(ip, Dnsruby::Name::create(".")).nil? end # DESC: root server list should be coherent with ICANN def chk_root_servers_ns_vs_icann(ns, ip) rs_list = ns(ip, Dnsruby::Name::create(".")).collect { |n| n.domainname} ref_list = RootServerList.current.keys unless rs_list.unsorted_eql?(ref_list) return { 'rs_list' => rs_list.collect{|e| e.to_s}.join(', '), 'ref_list' => ref_list.collect{|e| e.to_s}.join(', ') } end true end # DESC: root server addresses should be coherent with ICANN def chk_root_servers_ip_vs_icann(ns, ip) RootServerList.current.each { |rs, ips| rs_addr = [] addresses(rs, ip).each{ |rr| rs_addr << rr.address } unless rs_addr.unsorted_eql?(ips) return { 'rs' => rs.to_s, 'rs_addr' => rs_addr.collect{|e| e.to_s}.join(', '), 'ref_addr' => ips.collect{|e| e.to_s}.join(', ') } end } true end end end zonecheck-3.0.5/test/soa.rb000066400000000000000000000205351226210254100155560ustar00rootroot00000000000000# ZCTEST 1.0 # $Id: soa.rb,v 1.37 2010/06/17 09:46:17 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.37 $ # DATE : $Date: 2010/06/17 09:46:17 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'framework' module CheckNetworkAddress ## ## Check domain SOA record ## class SOA < Test with_msgcat 'test/soa.%s' #-- Initialisation ------------------------------------------ def initialize(*args) super(*args) @soa_expire_min = const('soa:expire:min').to_i @soa_expire_max = const('soa:expire:max').to_i @soa_minimum_min = const('soa:minimum:min').to_i @soa_minimum_max = const('soa:minimum:max').to_i @soa_refresh_min = const('soa:refresh:min').to_i @soa_refresh_max = const('soa:refresh:max').to_i @soa_retry_min = const('soa:retry:min').to_i @soa_retry_max = const('soa:retry:max').to_i @soa_drift_days = const('soa:serial:drift_days').to_i @soa_drift_ticks = const('soa:serial:drift_ticks').to_i end #------------------------------------------------------------ def is_serial_rfc1912?(serial) # Parse the serial into YYYYMMDDnn format year = serial / 1000000; serial %= 1000000 month = serial / 10000 ; serial %= 10000 day = serial / 100 idx = serial % 100 # If year seems too far away in the past or in the future return false if (year < 1950) || (year > 2100) # Check that the given date is valide begin return [ Date::new(year, month, day), idx ] rescue ArgumentError return false end end #-- Tests --------------------------------------------------- # DESC: SOA entries should exists def chk_soa(ns, ip) ! soa(ip).nil? end # DESC: SOA answers should be authoritative def chk_soa_auth(ns, ip) #soa(ip, @domain.name) # request should be done twice soa(ip, @domain.name, true).aa # so we need to force the cache end # DESC: SOA email address shouldn't have an '@' def chk_soa_contact_sntx_at(ns, ip) soa(ip).rname[0].to_s !~ /@/ end # DESC: SOA email address should have a valid syntax def chk_soa_contact_sntx(ns, ip) is_valid_mbox_address?(soa(ip).rname) end # DESC: SOA master should have a valid hostname syntax def chk_soa_master_sntx(ns, ip) is_valid_hostname?(soa(ip).mname) end # DESC: SOA master should be fully qualified def chk_soa_master_fq(ns, ip) return true if soa(ip).mname.absolute? { 'mname' => soa(ip).mname.to_s } end # DESC: SOA master should not point to CNAME alias def chk_soa_ns_cname(ns, ip) return true unless name = is_cname?(soa(ip).mname, ip) { 'master' => soa(ip).mname.to_s, 'alias' => name.to_s } end # DESC: recommanded format for serial is YYYYMMDDnn def chk_soa_serial_fmt_YYYYMMDDnn(ns, ip) serial = soa(ip).serial return true if is_serial_rfc1912?(serial) { 'serial' => serial.to_s } end # DESC: recommanded expire def chk_soa_expire(ns, ip) soa_expire = soa(ip).expire if (soa_expire >= @soa_expire_min) && (soa_expire <= @soa_expire_max) then true else { 'expire' => soa_expire.to_s } end end # DESC: recommanded minimum def chk_soa_minimum(ns, ip) soa_minimum = soa(ip).minimum if (soa_minimum >= @soa_minimum_min) && (soa_minimum <= @soa_minimum_max) then true else { 'minimum' => soa_minimum.to_s } end end # DESC: recommanded refresh def chk_soa_refresh(ns, ip) soa_refresh = soa(ip).refresh if (soa_refresh >= @soa_refresh_min) && (soa_refresh <= @soa_refresh_max) then true else { 'refresh' => soa_refresh.to_s } end end # DESC: recommanded retry def chk_soa_retry(ns, ip) soa_retry = soa(ip).retry if (soa_retry >= @soa_retry_min) && (soa_retry <= @soa_retry_max) then true else { 'retry' => soa_retry.to_s } end end # DESC: coherence between 'retry' and 'refresh' def chk_soa_retry_refresh(ns, ip) return true if soa(ip).retry <= soa(ip).refresh { 'retry' => soa(ip).retry.to_s, 'refresh' => soa(ip).refresh.to_s } end # DESC: coherence between 'expire' and 'refresh' def chk_soa_expire_7refresh(ns, ip) return true if soa(ip).expire >= 7 * soa(ip).refresh { 'expire' => soa(ip).expire.to_s, 'refresh' => soa(ip).refresh.to_s } end # DESC: Ensure coherence between SOA and ANY def chk_soa_vs_any(ns, ip) soa(ip) == any(ip, Dnsruby::RR::IN::SOA)[0] end # DESC: coherence of serial number with primary def chk_soa_coherence_serial(ns,ip) begin serial_ref = (soa(@domain.ns[0][1][0]).nil?) ? nil : soa(@domain.ns[0][1][0]).serial rescue Dnsruby::ResolvError,Dnsruby::ResolvTimeout => e raise e,"#{e.to_s} on primary server (#{@domain.ns[0][0].to_s},#{@domain.ns[0][1][0]})" end serial_other = (soa(ip).nil?) ? nil : soa(ip).serial return true if serial_ref.nil? || serial_other.nil? || serial_ref >= serial_other { 'serial_ref' => serial_ref.to_s, 'host_ref' => "#{@domain.ns[0][0].to_s}/#{@domain.ns[0][1][0].to_s}", 'serial_this' => serial_other.to_s } end # DESC: check unreasonnable drift of serial number with primary def chk_soa_drift_serial(ns,ip) begin serial_ref = soa(@domain.ns[0][1][0]).serial rescue Dnsruby::ResolvError,Dnsruby::ResolvTimeout => e raise e,"#{e.to_s} on primary server (#{@domain.ns[0][0].to_s},#{@domain.ns[0][1][0]})" end serial_other = soa(ip).serial return true if serial_ref <= serial_other # we don't test that if d = is_serial_rfc1912?(serial_ref) newdate = d[0] - @soa_drift_days serial_min = newdate.year * 1000000 + newdate.month * 10000 + newdate.day * 100 else serial_min = serial_ref - @soa_drift_ticks end return true if serial_other >= serial_min # XXX: possible wrapping { 'serial_min' => serial_min.to_s, 'serial_ref' => serial_ref.to_s, 'host_ref' => "#{@domain.ns[0][0].to_s}/#{@domain.ns[0][1][0].to_s}", 'serial_this' => serial_other.to_s } end # DESC: coherence of contact with primary def chk_soa_coherence_contact(ns,ip) begin rname_ref = soa(@domain.ns[0][1][0]).rname rescue Dnsruby::ResolvError,Dnsruby::ResolvTimeout => e raise e,"#{e.to_s} on primary server (#{@domain.ns[0][0].to_s},#{@domain.ns[0][1][0]})" end rname_other = soa(ip).rname return true if rname_ref == rname_other { 'rname_ref' => rname_ref.to_s, 'host_ref' => "#{@domain.ns[0][0].to_s}/#{@domain.ns[0][1][0].to_s}", 'rname_this' => rname_other.to_s } end # DESC: coherence of master with primary def chk_soa_coherence_master(ns,ip) begin mname_ref = soa(@domain.ns[0][1][0]).mname rescue Dnsruby::ResolvError,Dnsruby::ResolvTimeout => e raise e,"#{e.to_s} on primary server (#{@domain.ns[0][0].to_s},#{@domain.ns[0][1][0]})" end mname_other = soa(ip).mname return true if mname_ref == mname_other { 'mname_ref' => mname_ref.to_s, 'host_ref' => "#{@domain.ns[0][0].to_s}/#{@domain.ns[0][1][0].to_s}", 'mname_this' => mname_other.to_s } end # DESC: coherence of soa with primary def chk_soa_coherence(ns,ip) begin serial_ref = soa(@domain.ns[0][1][0]).serial rescue Dnsruby::ResolvError,Dnsruby::ResolvTimeout => e raise e,"#{e.to_s} on primary server (#{@domain.ns[0][0].to_s},#{@domain.ns[0][1][0]})" end serial_other = soa(ip).serial return true if serial_ref != serial_other soa(@domain.ns[0][1][0]) == soa(ip) end end end zonecheck-3.0.5/www/000077500000000000000000000000001226210254100143075ustar00rootroot00000000000000zonecheck-3.0.5/www/html/000077500000000000000000000000001226210254100152535ustar00rootroot00000000000000zonecheck-3.0.5/www/html/form.html.en000066400000000000000000000515731226210254100175200ustar00rootroot00000000000000 Zone Check
Lang: EN / FR

ZoneCheck

The ZoneCheck program (freely available here for download) performs several tests on your zone (ie: domain) to ensure that it is correctly configured and can be safely delegated, providing a certain quality to your domain (see the benefit section).

For detailed information on how to fill this form see the help section.
The time required to completely verify a zone can take from 30 seconds up to 5 minutes depending on the network speed of the server being accessed. If it takes more than a minute it generally means we are encountering problems accessing your nameservers (configuration error, firewall, ...) and are waiting for timeout.

Zone information

Zone
Primary
IPs
Secondary
IPs
Secondary
IPs
Secondary
IPs
Secondary
IPs
Secondary
IPs
Secondary
IPs
Secondary
IPs

Options

Output
zone summary
test name
explanations
details
progress bar
description
nothing
report
format
language
Error report
default error
all fatals
all warnings
don't stop on fatal
fatal only
report ok
profile
Extra tests performed
mail delivery
zone transfer
RIR databases
Transport layer
IPv4
STD
UDP
TCP
DNSSEC
DNSSEC tests
Hash Algorithm:
DS:
DNSKEY:

Benefit

Among the tests performed you can find checking for:
  • authoritative nameserver for your zone, ensuring you will be able to use your domain from outside your network.
  • correct list of secondary nameservers, so that if your primary nameserver is temporarily unreachable, you will still be visible on the internet;
  • check for mail delivery, so that you don't become the prey of spammers and become blacklisted

Help

Form

Zone Information
Zone
The domain (ie: zone) that should be tested (ie: the domain name that you want to register).
Primary
The nameserver that is considered as primary (the one in the SOA record if it is public).
Secondary
The secondary nameservers (all the NS records associated with the zone, except for the one listed above).
IPs
List of IP addresses associated with the nameserver.
  • they are only required if they can't be resolved (ie: they are in the zone that you want to register).
  • if you have several addresses you must use a space or a comma as the separator.
  • the form accepts IPv4 and IPv6 addresses.
Options: Output
zone summary
Includes a summary about the zone and its nameservers in the generated report
test name
Includes the name of the test that has been performed when reporting errors
explanations
Includes an explanation (when the test failed) about the purpose of the test and why you should fix it.
details
Includes details (when the test failed) about the culprit elements.
progress bar
Display information about the test progression using a a progress bar (require javascript and Mozilla or IE5+ for correct rendering).
description
Give a short description of the test when it is performed.
nothing
Don't display information about the test progression.
report
Select the type of generated report you want.
format
Select the format in which you want the report (HTML or plain text).
language
Select the language that you want the report generated in.
Options: Error report
default error
Errors are reported with the default severity associated with them.
all fatals
All errors are considered fatals.
all warnings
All errors are considered warnings.
don't stop on fatal
Keep going even after encountering a fatal error (this could lead to some unexpected results).
report ok
Report test that passed.
Options: Extra tests performed
mail delivery
Perform extra checking on mail delivery for typical mail accounts (hostmaster, postmaster, ...) associated with domain names.
zone transfer
Perform additional tests on the zone retrieved after a zone transfer.
RIR databases
Check that IP addresses used are registered in the RIR databases
Options: Transport layer
IPv4, IPv6
Select the routing layer (if none are selected it will default to IPv4 and IPv6).
STD, UDP, TCP
Select the transport layer you want for interrogating your nameservers.
Option: DNSSEC
DNSSEC tests
Set the DNSSEC tests policy to mandatory, if not tests will be warnings
DS and Hash Algorithm
Gives the hash of the public key and the algorithm used to do that
The hash of the key must be encoded in hexadecimal (blanks are removed). The Hash Algorithm is the number given by IANA and corresponding to the algorithm.
DNSKEY
Gives the public key used as a Security Entry Point. The key must be encoded in base64 (blanks will be removed).

Results

  • the word generic means that the error is eitheir unrelated or present on all nameservers,
  • when an error is between [brackets], this means that the test failed for external reasons. The reasons are displayed next to it.

Valid CSS! Valid HTML 4.01! Release: $Name: ZC-3_0_5 $
Last modified: Thu Feb 19 14:44:11 CET 2004 zonecheck-3.0.5/www/html/form.html.fr000066400000000000000000000536701226210254100175250ustar00rootroot00000000000000 Zone Check
Lang: EN / FR

ZoneCheck

Le programme ZoneCheck (librement disponible ici en téléchargement) effectue plusieurs tests sur la zone (domaine) afin de s'assurer que celle-ci est correctement configurée et peut être déléguée sans risque, fournissant un certain degré de qualité à votre domaine (voir la section sur les bénéfices).

Pour une information détaillée sur la manière de remplir le formulaire, voyez la section sur l'aide.
Le temps nécessaire à une vérification complète du domaine peut prendre de 30 secondes jusqu'à 5 minutes selon la vitesse du réseau pour accéder aux serveurs. Si la vérification prend plus d'une minute, cela signifie qu'il y a eu des problèmes pour accéder aux serveurs (erreur de configuration, firewall, ...) et que le programme est en attente de timeouts.

Information sur la zone

Zone
Primaire
IPs
Secondaire
IPs
Secondaire
IPs
Secondaire
IPs
Secondaire
IPs
Secondaire
IPs
Secondaire
IPs
Secondaire
IPs

Options

Sortie
résumé sur la zone
nom du test
explications
détails
barre de progression
description
rien
report
format
language
Rapport d'erreurs
sévérité par défaut
tout fatal
tout avertissement
continue après fatal
erreurs fatales uniquement
affiche ok
profile
Test supplémentaires effectués
distribution du courrier
transfert de zone
bases de données RIR
Transport layer
IPv4
STD
UDP
TCP
DNSSEC
tests DNSSEC
Algorithm de Hashage:
DS:
DNSKEY:

Bénéfices

Parmis les tests effectués on peut trouver :
  • serveur fait autorité pour la zone, assurant qu'il est possible d'utiliser le domaine à l'extérieur de votre réseau ;
  • liste des serveurs secondaires corrects, de telle manière que si le serveur primaire est temporairement injoignable, le domaine reste encore visible depuis l'internet ;
  • vérification de la distribution du courrier, afin de ne pas devenir la proie des spammers et finir en liste noire

Aide

Formulaires

Information sur la zone
Zone
Le domaine qui doit être testé (le nom de domaine qui doit être enregistré).
Primaire
Le serveur de noms qui est considéré comme primaire (celui qui figure dans l'enregistrement du SOA, si celui-ci est public).
Secondaire
Le serveur de noms secondaire (tous les enregistrement NS associés avec le domaine), à l'exception de celui listé ci-dessus.
IPs
Liste des adresses IP associées avec le serveur de noms.
  • elles sont uniquement requises si elles ne peuvent être déduites (elles sont dans la zone qui est actuellement en cours d'enregistrement),
  • s'il y a plusieurs adresses, elle doivent être séparées par un espace ou une virgule,
  • le formulaire accepte aussi bien les adresses IPv4 qu'IPv6 (à l'exception des compatibles et mappées).
Option: Sortie
résumé sur la zone
Inclus un résumé sur la zone et ces serveurs de noms dans le rapport généré
nom du test
Inclus le nom du test qui a été réalisé
explications
Inclus une explication sur la raison du test et pourquoi il doit être corrigé (quand le test a échoué).
détails
Inclus des détails sur les éléments coupables (quand le test a échoué).
barre de progression
Affiche des informations à propos du déroulement des tests en utilisant une barre de progression (nécessite javascript et Mozilla ou IE5+ pour un rendu correct).
description
Donne une courte description sur le test effectué.
rien
N'affiche aucune information sur la progression des tests.
rapport
Sélectionne le type de rapport qui doit être généré.
format
Sélectionne le format dans lequel le rapport doit être généré (HTML ou texte simple).
langue
Sélectionne la langue dans laquelle le rapport doit être généré.
Option: rapport d'erreurs
sévérité par défaut
Les erreurs sont rapportées avec le degré de sévérité associé au test.
tout fatal
Toute erreur est considérée comme fatale.
tout avertissement
Toute erreur est considérée comme un avertissement.
continue après fatal
Continue même après avoir rencontré une erreur fatale (cela peut conduire à des rsésultats inattendus).
affiche ok
Affiche les tests qui sont passés sans erreur.
Option: tests supplémentaires effectués
distribution du courier
Effectue des vérifications supplémentaires sur la distribution du courrier pour des comptes utilisateurs typiques (hostmaster, postmaster, ...) associés avec les noms de domaine.
transfert de zone
Effectue un transfert de zone sur lequel des tests supplémentaires sont effectués.
bases de données RIR
Vérifie que les adresses IP sont bien enregistrées dans la base des RIR
Option: couche de transport
IPv4, IPv6
Sélectionne la couche de routage (si aucune n'est sélectionnée le défaut est de prendre IPv4 et IPv6).
STD, UDP, TCP
Sélectionne la couche de transport à utiliser pour interroger les serveurs de noms.
Option: DNSSEC
tests DNSSEC
Rend obligatoire les tests DNSSEC, ou les mets tous en avertissement
DS et Algorithme de Hachage
Précise le condensat de la clé à utiliser comme point d'entrée sécurisé de la zone et précise l'algorithme utilisé.
Le condensat de la clé doit être encodé en hexadecimal (les espaces seront supprimés). L'algorithme de hashage doit être un nombre correspondant à l'algorithme.
DNSKEY
Précise la clé à utiliser comme point d'entrée sécurisé de la zone. La clé doit être encodé en base64 (les espaces seront supprimés).

Résultats

  • le mot générique signifie que l'erreur est soit ind�pendante soit présente sur tous les serveurs de noms,
  • lorsqu'une erreur est entre [crochets], cela signifie que le test a échoué pour une raison externe (cette raison est affichée à côté).

Valid CSS! Valid HTML 4.01! Distribution: $Name: ZC-3_0_5 $
Last modified: Wed Aug 25 16:26:08 CEST 2010 zonecheck-3.0.5/www/img/000077500000000000000000000000001226210254100150635ustar00rootroot00000000000000zonecheck-3.0.5/www/img/details.png000066400000000000000000000006371226210254100172240ustar00rootroot00000000000000PNG  IHDR(-SgAMA aPLTEєo ]7SNj'߰φ(EG`~$h.L,Gw";W*HKe/Iqý4QD^&AN`tRNS@fbKGDH pHYs  ~tIMEP#~IDATxc`&/SUWeyyUaJeY$2@U&'# "A6&vYq+?b%.1nIuuTJba0a3 \IENDB`zonecheck-3.0.5/www/img/element.png000066400000000000000000000007011226210254100172200ustar00rootroot00000000000000PNG  IHDR(-SPLTE;gˎ(o ujRQ|#MoCՖ1 `eLɅb'ݝ1{G|'Ty"rUWҕk*/ZzDvKܦŋ(S_s U}IDATxc` d XPXe@P@KHMGGMSSI]TD549ęl8DEDT4m06FVUzh.5d @ +)IENDB`zonecheck-3.0.5/www/img/fatal.png000066400000000000000000000011711226210254100166600ustar00rootroot00000000000000PNG  IHDR(-SPLTE~$:`Cf΅s7Q9iPU({Qܨ>mzUbɍ)Bi\ڼbI q ?.Fyfޛ,Ԓ5\n(F`XT2ѓ*vS1qLɡڞ8+p ֚6Z&k0Tw"߭^niI:eU+~Bt̏)ЉKsPԕ+ך3`0sׅ^tRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>UIDATxc`)U)SfRgײ啄55B"$,|EiiM}cccN @>1[:1XX)A)DUy%l•\C#7Ɉ@{{55k..yGA==&#mGO#A6XjYv lJ@E> vRV VR2fJr^ @u&&V` #`4@3IIENDB`zonecheck-3.0.5/www/img/gear.png000066400000000000000000000011131226210254100165030ustar00rootroot00000000000000PNG  IHDR(-SPLTE,Lȍ+h##zxmW3˗PI]/D b՜=ң?my(!V}dq>ܟ8au6͂v;œ>`O3fکVґ2fJܯŁU̙31J}֜Bw&riBh5\X2ި~8-bSGڣDup>NYh<ME_~&^:eeq͜RAō@z;ЋSנ18ԠIaެi~>tRNS@fbKGDH pHYs  ~tIME )?VIDATxc`Q ,0Ts&8DB02XNCOQ#P^ݛAGҌ ( d 0sRsbUvkRP1asie+*m`qQr45fփ9ULDA 78'MdYIENDB`zonecheck-3.0.5/www/img/info.png000066400000000000000000000006511226210254100165260ustar00rootroot00000000000000PNG  IHDR(-SPLTED~$f|W䳰wuqPOL{Ԕߞ1VffffNj'þksqnԕ*~ыq c9LZYV›m̓փ\ʸywtTRP\PqftRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>UIDATxmoB0pe"snShmjs'>:ﳌs_&@ޒ FzT&%}u6Dp8gB>WwHN=]^~c2=bG}{7F^& ~(u @IENDB`zonecheck-3.0.5/www/img/light.png000066400000000000000000000011721226210254100167010ustar00rootroot00000000000000PNG  IHDR#&yPLTEЉ1fzyeޭAϓ؜Qьܧs̓Օ8գJӏl`֌={׮ԒR[ў-ftRNS@fbKGDH pHYs  ~tIME  (rIDATx͔ю EA)b5TA636->>Op fyPZoZ0dNyaL2((aq<D߻w:nQ KijPMԉ8Lm˾f`M$E P_㓔E)' #[\bGOϥ﹘a(`B5q,w;x3Iȼ c-0A&<<+g]ҖkeF8{fHlz>CG8Cd<XHA.+m#Bgt,mT)Շ:-"j%pkED}Pϳf֗^}{XPj1 PP` ~&Dw?֟/?T(x"IENDB`zonecheck-3.0.5/www/img/logo.png000066400000000000000000000147571226210254100165470ustar00rootroot00000000000000PNG  IHDR>؊gAMA abKGD pHYs``zxEtIME "e8lIDATxwUǿ&# H A FbfEѰ+quUE:$1,*"(!I<]U=3==TսNYs=-J5Ju"Rx2 -T"sSxZs+tAHa0^8 Vp<д26WoȗlQ4p+a=nGCAfK$O vShJ17"qqAsstq̈́|ٯ}q,qbEY]ƃGEP-kU.3ꂟXKFUO&n^V81B;\h^ B9Ƞ%4  Oa3Z`e!a|ɶEv5کKX9 Q q8[gjU]&S+ "!܎'eep\ bB@@끳NA1f2 .zTXWƸ:an/{g\mNp|0( $t2fe* a`PE!D֒:q!|=G*L dk>_+_y =GFln`9il~fF"Qne gn!S^ ~D]CPrR|*~뉙ؘrPe&Q^Tٴ57H0ʍ}-ek\$eX̵5"lN>@^S16g%Qx(`Y QG KU&<4k KX7`u师rZ0J'jڃ*ZDQo"6#mXnaе2Z?SC#=Yb#w(fSYtR Kqn&hM !fv8Cn7b;!mɭ,|W{3ys)ެ\šȍT[yB-3 ssdp'li25V ENI Gyxn"'@h+Ө,<]]Fk5ơw3K^%N`˧j-,q9FQZAiޓL̛ fŽ":֙`Ayq gp #~B#L"( Ɍu̐T' i c\ۘP`M N!#(qcȬ(4YdBإeSߴ'Aq7XZ.XM;]p%?Y 0,^[tFՆ(FJ` ("1VoPmah=um?)l.z"d`D7o{{m2*X]?,uNw039$vԙ쩏jW&Zraiu;hQliʥUTnղHM"@j=E }#^T gPr h'h-*WNv1әs$l/ "\\|:aKíleUԻMS 3 SGl_G(3zdCТt:}/ !+/Yy[FUOCh㬮PF3be^u דMsf BLBHGkE3Utv(Û>U(ؙ: \ՠ^t@+}Wy;Uv+\l\\O)Gr#EE0 fhfv$}g)Q`xt"tq^r*B&p (k9r-o0fQ>x`ǗҘP?CB39!xN?C|3+$R+0Pܵ^xfIl hUY819HќRv98Pc9 VnX_de__z8T*eJu5eMWb _:Cf8bT{ ca,{jܨ)t=LEXe{u!ÌQ08ᶋ~[yvcs`%;D$ԑ%DPc?)C?'XYu1VQY&IfB"G@96)qlP^uaxdfr*} 4b !38iĨJg)պP-{8xJ)SOPd*I]٥Y/qJBU.cpY')~'$/b9OD[f)ts;,Z3.{yc7HԄ,|ƇaE""إRe3r<}#{aO*s!_GU'n[x t`3G0R6@m0a2S~?D }2'2ΩNT_Ͻb\pw`*1sev -ijwo [ՄxV;ȲaySy^7\(0܆ak!1r-׫==W݃RkugYxb|[KS>3xDId>M~K'tΉ](ңء1mG2տ1VWFbUn22m'rrlS0Om|U=G,vί<@W홻& ç|53YNű>wliIʙ \%'"SUg^liL dR@)f:m9iChR+L%\'œɶ_vŨ'[VE =~`C{aoE#iey3grI{(`$!OAl +_Ay#ot+\ +Lzx~B˔uӻߺOw'3kS!_+Δ ![\p칤 M {اU:;ش>tYPx ŝV·Utkp1eطngbVSa!lS0S23=}%܃pmt)sr໎JƠKqg&1>N5 왑s%O"~ɡ'O%)!yr:B-GD9TFLR }/3_6֞6/Nzb6툙xZoKvJq%wܡ+scG&m4:?d&§,dpYc l O+';gBa\i"~3W`(k㟂:/wV /rwVvpDZ9 my9 J/ V@xSg  0ِC5WηWB=yhTQ}c}bM^)A@} Z0ڒ0K˅yo7oUځwWvhE2y22J/C-~B&ӐFs;Sb룞5oV);7udl˶;.8h&Uy7,=x+Є"lrHf3ر_Q&^ @(sd<Bϓ~ ,7p{9(ᄍprۥɴC?YMv&bKS)Ť>o@",K h2 1a8`{I񄴶 B 4P| /i@Hs 䢾hӼ- U78.{4$s*MB$G ߰JkLD9%pj sbt׵B gt 2 )}ot=5fVq%GL~3Kt^t2|Ћw.{9VUu0 9 `9ʭ9apj9VJAelFPF͗&TEvd[*ݗzPҒHLOlvͻ쁗*gHSڳ` ">)2@yJ) rP((`D ȅt 0'8%|W8L'R;uy0Vt&|.6(wW=PR’XTiߎŪ`*\'zۦ'VwlF 46WG1mуuZ,yaDI/D5+iF \F Q,%.yPFbީgG %A9|Vi%]{~?3+8T޺5F`H$(/Yxյ!t3h_C) L`6n .Fj2l&Le&R;M G7隟Ε(/bRp^4Rge(í@}(>CdR#b |SpP6(>މaB^S5jM ^-iא|V?i79a>*j\x+:a(مU0`=ruIX 27(g&p^PL:UP E:%ya^ZEbETElZZ_ãÍnuK *n<)e k5a@ λ}Ejo2ʸ`GA9 3`\A:(,dd(!]GuQXa x[2#"hx?),y);m<BsƐEqj{W_K 7B٤f ф3@f 2psS򵀆V^.<,ݺ$<񤺽T&4m4 E%@rxG OÊE\#:k!Gn8 C$+vJSrhIU9̫٩-KUcj Hci`չհQrQsMsE^`[2Np3۵z'E8|ZȆYb )(+V=r ]vc6 "8h6E c$dCHe_!X)|lO{TF PgjOsXr>v2W:N{B:aX2LĮIQY:ʼnj&QfI]Tb%}^((-\GBa3H\tʘhx =x޿mbNY rQ P:uBX$CɉEF?}&{mu%]S)q'4g-yTVH yAM0e7=<F2]I|yNm 8"H'K%(o/Ёu\PgI+~c彰"D.l@OG FVT-=)>ol(E*OG*dU%uL 8 2$2ė˞$ӎe$8,~ ,3ˢGV-" I7ucKc(c.a6$"2N䰒d;&Hs9nExoZb҄%,oNoCH+–~u +dPH1ݸ9poH/I&YraU.liI3$+:K%i㱜y}"k(QPZ"܉נ%{IgHNj*B$-(5ې1ZJ0(,,aEXIp] t> yD0!KjXx1MPQZPE~܋o ؔ!4"/3#E5*XD%FmBֺs+MKs*X3|1|Až Gl nv(IMAB&LAI{7*&Yӥ"'lZ*y#.b5/jq6ezf}H:lbl1ǦY.ve7JL!LZKWrbFJ kt1bW+"9t)p AhS(r}cn+*ཅdN(]H3/N!h 6[R^Зç#J:uuG(m`b͠R>Ci.X4A(`'e}6H <>y_ܴ;_Օ˖)$EDr!&9dc5I]\w|ynIENDB`zonecheck-3.0.5/www/img/loupe.png000066400000000000000000000006141226210254100167160ustar00rootroot00000000000000PNG  IHDR(-SPLTEєo ]7SNj'߰φ(EG`~$h.L,Gw";W*HKe/Iqý4QD^&AN`tRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>U~IDATxc`&/SUWeyyUaJeY$2@U&'# "A6&vYq+?b%.1nIuuTJba0a3 \7PYIENDB`zonecheck-3.0.5/www/img/notepad.png000066400000000000000000000015671226210254100172340ustar00rootroot00000000000000PNG  IHDR#&yVPLTEٚ/k¼nKdž=fhf;(}ך]O€A6ѵtHZΧ3{9q1Sī|Jנ@rAĵHŽݚǬxZńޱˁ;3딵 iݥHfBB}ؔOʥݝ1X܍8fwtiT;勷sNK mtRNS@fbKGDH pHYs  ~tIME wVIDATxS@p*J"(d *E'"r+:Z4i҆5b}_7VO!$ 0Tv"MQ>:`z=$P=TaYNj2Z_b #vMkURkG5Z1msor4u #.\Ud 7Lb>`܄ű@'a:۠|k>X` za G9~($pyL Z[HLUC`A8J -%I9UekD!T"8W93M* yF:[^h?dKcX֒l!'V168[|Jo;7X[.IENDB`zonecheck-3.0.5/www/img/ok.png000066400000000000000000000011021226210254100161740ustar00rootroot00000000000000PNG  IHDR(-SPLTEtԈKqʸ6bĿϭ~2f̓FYa#yڟТӻ|HRF<|n@Kq+a#KM%GGO/7K #M5# T03SfqbU*hle#Y[љK9o/vUp(y7yIENDB`zonecheck-3.0.5/www/img/primary.png000066400000000000000000000005631226210254100172600ustar00rootroot00000000000000PNG  IHDR(-SuPLTE1fXz#g͐*W=:\֘%Mlۜ3otQˆ&ADЊxPlbas!؝φ;j&ˏ*GtRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>UzIDATxڍ aGaaʬ{G)fKVՅ1#M7-#la\HiOJ1 = %@aj/0h'C'~l՘xIENDB`zonecheck-3.0.5/www/img/ref.png000066400000000000000000000003761226210254100163530ustar00rootroot00000000000000PNG  IHDRRPLTEf}RHtRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>U_IDATx- 0 lN @bJ#6ISNc( 3D/\  X$ "ŻoPma*2!?}3-LIENDB`zonecheck-3.0.5/www/img/secondary.png000066400000000000000000000005671226210254100175700ustar00rootroot00000000000000PNG  IHDR(-SuPLTE1fXz#g͐*W=:\֘%Mlۜ3otQˆ&ADxPlφbas!؝;jЊ&ˏ*GptRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>U~IDATxڍ E:Kc4brKXܓ̂cAa?w>m,i<&ڟR$eGSRsiZ-F#`u^2Gt'8 s_]C:i{IENDB`zonecheck-3.0.5/www/img/warning.png000066400000000000000000000007311226210254100172370ustar00rootroot00000000000000PNG  IHDR(-SPLTE.,y\Bt٭d1Vڬy"wՔ\̢\fF?*ޱP.styU?1fI>l辈-֤ؑ8t)eآHą4[ Q`/؜R«慵ٵ{!BƊ'2K6^fGJ&YݣV4tRNS@ftEXtSoftwaregif2png 2.4.4J=;gIFg>UIDATxc`{4*5BPr`F櫙i(RC2AאRD !`k-c%@[ƀ IPD$W"`c&`%<2`2`M&*2P /!RN z` 0G[ދIENDB`zonecheck-3.0.5/www/img/zc-fav.png000066400000000000000000000007101226210254100167550ustar00rootroot00000000000000PNG  IHDR(-SsBITO`PLTE ڡ jS$y:l0}p\UEܡJWſwM%N ciΞ%6! tRNSv pHYs  ~tEXtCreation Time04/01/03'!tEXtSoftwareMacromedia Fireworks 4.0&'uIDATxOG0 ^N6u(DJ lK@𓘊KG>J!;|֖jsJgFDL0}:Rf! zUSUh5z/S .IENDB`zonecheck-3.0.5/www/img/zone.png000066400000000000000000000010121226210254100165360ustar00rootroot00000000000000PNG  IHDR(-SPLTEBȑ)\sQOa5y"qTp 1ߜ-nCh%gLd0{9 xcYғ*2jIχƊ'qԩv!ec7P~$;mG|ZDckٙ.ZΑ*ܜ1kIcUIDATxmkBP%*щCKQ%hjS1oϳRhUS[<6tOӎ"*g#tY'hX{M]G@QHs1 :]Ӳ`Q75S.^> 5[Ȃ7 C6[g3EIBo2<#Í?HIENDB`zonecheck-3.0.5/www/js/000077500000000000000000000000001226210254100147235ustar00rootroot00000000000000zonecheck-3.0.5/www/js/formvalidation.js000066400000000000000000000032571226210254100203060ustar00rootroot00000000000000// $Id: formvalidation.js,v 1.10 2010/06/01 15:36:07 chabannf Exp $ // // CONTACT : zonecheck@nic.fr // AUTHOR : Stephane D'Alu // // CREATED : 2003/02/26 18:38:10 // REVISION : $Revision: 1.10 $ // DATE : $Date: 2010/06/01 15:36:07 $ // // CONTRIBUTORS: (see also CREDITS file) // // // LICENSE : GPL v3 (or MIT/X11-like after agreement) // COPYRIGHT : AFNIC (c) 2003 // // This file is part of ZoneCheck. // // ZoneCheck is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // function zc_form_setlocale(emptyzone) { zc_form_l_emptyzone = emptyzone; } function zc_form_validate(form) { var zone = form["zone"].value; zone = zone.replace(/^\s+/,'').replace(/\s+$/,''); if (zone.length == 0) { alert(zc_form_l_emptyzone); return false; } else { return true; } } function zc_form_clear(form) { var i; if (form["zone"]) form["zone"].value = ""; for (i = 0 ; form["ns"+i] ; i++) form["ns" +i].value = ""; for (i = 0 ; form["ips"+i] ; i++) form["ips" +i].value = ""; return 0; } zonecheck-3.0.5/www/js/popupmenu.js000066400000000000000000000125431226210254100173160ustar00rootroot00000000000000// $Id: popupmenu.js,v 1.13 2010/06/01 15:36:07 chabannf Exp $ // // CONTACT : zonecheck@nic.fr // AUTHOR : Stephane D'Alu // // CREATED : 2003/02/18 14:33:14 // REVISION : $Revision: 1.13 $ // DATE : $Date: 2010/06/01 15:36:07 $ // // CONTRIBUTORS: (see also CREDITS file) // // // LICENSE : GPL v3 (or MIT/X11-like after agreement) // COPYRIGHT : AFNIC (c) 2003 // // This file is part of ZoneCheck. // // ZoneCheck is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // sanity check if (zc_publish_path == null) alert("ZoneCheck internal error: zc_publish_path not initialized"); /* * ZC_Popup */ function ZC_Popup(id, title) { this.id = id; this.title = title this.menu = null; this.item = []; } ZC_Popup.prototype.create = function() { var row, cell, link; var self = this var table = document.createElement('TABLE'); var tbody = document.createElement('TBODY'); table.appendChild(tbody); table.cellSpacing = 1; table.className = "zc-popup"; table.id = this.id; // XXX: not working table.style.visibility = 'hidden'; table.style.position = "absolute"; // title bar row = document.createElement('TR'); row.className = 'zc-title'; cell = document.createElement('TD'); cell.className = 'zc-title'; cell.colSpan = 7; if (this.title) cell.innerHTML = this.title; row.appendChild(cell); cell = document.createElement('TD'); cell.colSpan = 1; cell.align = 'right'; link = document.createElement('A'); link.href = '#'; link.onclick = function() { self.hide(); return false; }; link.onmouseover = function() { window.status = "close"; return true; }; link.onmouseout = function() { window.status = ""; return true; }; var x = document.createTextNode('x'); link.appendChild(x); cell.appendChild(link); row.appendChild(cell); tbody.appendChild(row); // items for (var i = 0 ; i < this.item.length ; i++) { row = document.createElement('TR'); row.className = "zc-item"; cell = document.createElement('TD'); cell.colSpan = 8; cell.align = 'left'; cell.innerHTML = this.item[i][0]; cell.onclick = this.item[i][1]; row.appendChild(cell); tbody.appendChild(row); } document["body"].appendChild(table); this.menu = table; } ZC_Popup.prototype.hide = function() { this.menu.style.visibility = 'hidden'; } ZC_Popup.prototype.show = function(x, y) { var left = document.body.scrollLeft; var top = document.body.scrollTop; if (this.menu.offsetWidth + x > document.body.clientWidth) { left += document.body.clientWidth - this.menu.offsetWidth; } else { left += x; } if (this.menu.offsetHeight + y > document.body.clientHeight) { top += document.body.clientHeight - this.menu.offsetHeight; } else { top += y; } this.menu.style.left = left + "px"; this.menu.style.top = top + "px"; this.menu.style.visibility = 'visible'; } ZC_Popup.prototype.add = function(label, func) { this.item.push([label, func]) } /***********************************************************************/ function zc_contextmenu_setlocale(l10n_testname, l10n_details, l10n_references, l10n_elements) { zc_l10n_testname = l10n_testname; zc_l10n_details = l10n_details; zc_l10n_references = l10n_references; zc_l10n_elements = l10n_elements; } function zc_contextmenu_start() { var hidefunc = function (className, tagName) { var elt = document.getElementsByTagName(tagName); for (var i = 0 ; i < elt.length ; i++) { if (elt[i].className == className) { if (elt[i].style.display == "none") { elt[i].style.display = elt[i].style.display_old; } else { elt[i].style.display_old = elt[i].style.display; elt[i].style.display = "none"; } } } }; var ctx = new ZC_Popup("zc_contextmenu", "+/-"); ctx.add(""+ " "+zc_l10n_testname, function () { hidefunc('zc-name', 'DIV'); }); ctx.add(""+ " "+zc_l10n_details, function () { hidefunc('zc-details', 'UL'); }); ctx.add(""+ " " +zc_l10n_references, function () { hidefunc('zc-ref', 'UL'); }); ctx.add(""+ " "+zc_l10n_elements, function () { hidefunc('zc-element', 'UL'); }); ctx.create(); document.oncontextmenu = function(event) { if (event == null) // fucking IE event = window.event; // ok, it hasn't been standardize ctx.show(event.clientX, event.clientY); return false; }; } zonecheck-3.0.5/www/js/progress.js000066400000000000000000000167241226210254100171370ustar00rootroot00000000000000// $Id: progress.js,v 1.20 2010/06/01 15:36:07 chabannf Exp $ // // CONTACT : zonecheck@nic.fr // AUTHOR : Stephane D'Alu // // CREATED : 2002/10/02 13:58:17 // REVISION : $Revision: 1.20 $ // DATE : $Date: 2010/06/01 15:36:07 $ // // CONTRIBUTORS: (see also CREDITS file) // // // LICENSE : GPL v3 (or MIT/X11-like after agreement) // COPYRIGHT : AFNIC (c) 2003 // // This file is part of ZoneCheck. // // ZoneCheck is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /** * convert a time in sec into a string * possible formats are 'mm:ss', 'hh:mm:ss' or '--:--' */ function zc_sec_to_timestr(sec) { if (sec < 0) return "--:--"; hrs = Math.floor(sec / 3600); sec %= 3600; min = Math.floor(sec / 60); sec %= 60; if (sec < 10) sec = "0" + sec; if (hrs > 0) { if (min < 10) min = "0" + min; return hrs + ":" + min + ":" + sec; } else { return min + ":" + sec; } } /** * convert a speed into a string (2 digits after the coma) */ function zc_speed_tostr(speed) { if (speed < 0) return "--.--"; speed = speed * 100; cnt = Math.floor(speed) % 100; if (cnt < 10) cnt = "0" + cnt; unt = Math.floor(speed / 100); return unt + "." + cnt; } /** * switch off elements */ function zc_element_off(id) { document.getElementById(id).style.display = "none"; } /** * remove id (so that it can be reused) */ function zc_element_clear_id(id) { document.getElementById(id).id = ""; } /*======================================================================*/ /** * initialize locale for the progress bar (ie: internationalisation) */ function zc_pgr_setlocale(tprogress, progress, test, speed, time, na) { zc_pgr_l_title_progress = tprogress; zc_pgr_l_progress = progress; zc_pgr_l_test = test; zc_pgr_l_speed = speed; zc_pgr_l_time = time; zc_pgr_l_na = na; } /** * quiet mode (no titles) */ function zc_pgr_setquiet(quiet) { zc_pgr_quiet = quiet; } /** * start progress bar */ function zc_pgr_start(count) { zc_pgr_starttime = (new Date()).getTime(); zc_pgr_processed = 0; zc_pgr_last_processed = -1; zc_pgr_ticks = 0; zc_pgr_totaltime = 0; zc_pgr_totalsize = count; zc_pgr_barsize = 300; zc_pgr_tickersize = 40; s = ""; if (! zc_pgr_quiet) { s += "

" + zc_pgr_l_title_progress + "

"; } s += "
"; s += "
"; s += ""; // titles s += ""; s += ""; s += "" s += ""; s += ""; s += ""; s += ""; // progress bar information s += ""; s += ""; if (zc_pgr_totalsize <= 0) { // infinit s += ""; s += ""; s += ""; } else { // limited s += ""; s += ""; s += ""; } s += ""; s += ""; s += ""; s += ""; s += ""; // spacer s += ""; // check description s += ""; s += "
" + zc_pgr_l_progress + "  " + zc_pgr_l_test + "    " + zc_pgr_l_speed + "    " + zc_pgr_l_time + "  
 
"; s += "
"; s += "
"; document.write(s); zc_pgr_setdesc("..."); zc_pgr_update(); // fire updater 2 times per second zc_pgr_timeoutid = setInterval("zc_pgr_updater()", 500); } /** * update the progress bar */ function zc_pgr_update() { // speed speed = zc_pgr_totaltime ? (1000*zc_pgr_processed/zc_pgr_totaltime) : -1.0; if (zc_pgr_totalsize > 0) { // percent done pct = Math.ceil(100 * zc_pgr_processed / zc_pgr_totalsize); // compute spent time nowtime = (new Date()).getTime(); zc_pgr_totaltime = nowtime - zc_pgr_starttime; // estimated time eta = speed < 0 ? -1.0 : Math.ceil((zc_pgr_totalsize - zc_pgr_processed) / speed); // pctsize = zc_pgr_barsize * pct / 100; document.getElementById("zc-pgr-pct" ).innerHTML = pct + "% "; document.getElementById("zc-pgr-pct1" ).style.width = pctsize; document.getElementById("zc-pgr-pct2" ).style.width = zc_pgr_barsize-pctsize; document.getElementById("zc-pgr-eta" ).innerHTML = zc_sec_to_timestr(eta); } else { pos0 = (2 * zc_pgr_ticks) % (zc_pgr_barsize * 2 - zc_pgr_tickersize); pos2 = zc_pgr_barsize-zc_pgr_tickersize - pos0; document.getElementById("zc-pgr-pct0" ).style.width = pos0; document.getElementById("zc-pgr-pct2" ).style.width = pos2; document.getElementById("zc-pgr-eta" ).innerHTML = zc_pgr_l_na; } document.getElementById("zc-pgr-proc" ).innerHTML = zc_pgr_processed; document.getElementById("zc-pgr-speed").innerHTML = zc_speed_tostr(speed); } /** * */ function zc_pgr_setdesc(desc) { document.getElementById("zc-pgr-desc" ).innerHTML = desc; } /** * */ function zc_pgr_updater() { // don't tick if nothing has changed if (zc_pgr_processed != zc_pgr_last_processed) { zc_pgr_ticks += 1; zc_pgr_last_processed = zc_pgr_processed; } // update zc_pgr_update(); } /** * process element in progress bar */ function zc_pgr_process(desc) { zc_pgr_processed += 1; // one more zc_pgr_setdesc(desc); // set description } /** * finish progress bar */ function zc_pgr_finish() { // remove timeout handler for updater clearTimeout(zc_pgr_timeoutid); // remove progress bar if (! zc_pgr_quiet) { zc_element_off("zc-pgr-title"); zc_element_clear_id("zc-pgr-title" ); } zc_element_off("zc-pgr-pbar" ); zc_element_clear_id("zc-pgr-pbar" ); zc_element_clear_id("zc-pgr-pbar-out"); zc_element_clear_id("zc-pgr-pbar-in" ); zc_element_clear_id("zc-pgr-pct" ); zc_element_clear_id("zc-pgr-pct0" ); zc_element_clear_id("zc-pgr-pct1" ); zc_element_clear_id("zc-pgr-pct2" ); zc_element_clear_id("zc-pgr-proc" ); zc_element_clear_id("zc-pgr-speed" ); zc_element_clear_id("zc-pgr-eta" ); zc_element_clear_id("zc-pgr-desc" ); } zonecheck-3.0.5/www/style/000077500000000000000000000000001226210254100154475ustar00rootroot00000000000000zonecheck-3.0.5/www/style/zc.css000066400000000000000000000213631226210254100166020ustar00rootroot00000000000000/* $Id: zc.css,v 1.40 2010/06/01 15:36:07 chabannf Exp $ * * CONTACT : zonecheck@nic.fr * AUTHOR : Stephane D'Alu * * CREATED : 2002/08/02 13:58:17 * REVISION : $Revision: 1.40 $ * DATE : $Date: 2010/06/01 15:36:07 $ * * CONTRIBUTORS: (see also CREDITS file) * Alix Guillard * * LICENSE : GPL v3 (or MIT/X11-like after agreement) * COPYRIGHT : AFNIC (c) 2003 * * This file is part of ZoneCheck. * * ZoneCheck is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #lang { float: right; margin-left: 0; } #beta { margin: 0; z-index: 0; color: red; text-align: center; font-style: italic; font-size: 50pt; } body { background: white; color: #333333; font-family: Arial, Helvetica, sans-serif; } .paragraph { font-size: 12px; text-align: justify; } .line { font-size: 12px; } td, li, ul { font-size: 12px; } h1 { font-size: 18px; color: #f7ad31; font-weight: bold; } h1#logo { text-align: center; } h2 { font-size: 14px; color: #1341af; font-weight: bold; } h3 { font-size: 12px; color: #1341af; font-weight: bold; } /* TABLE[rules=rows] TD { border-top: solid } TABLE[rules=rows] { //border-collapse: collapse; border: solid #0066B2; border-color: #0066B2; } */ img.zc-logo { /* float: left; margin-left: 0; */ } .zc-warning { padding: 5px 5px 5px 5px; background-color: #f0ece5; border-left: solid #f5b13d; } .zc-error { padding: 5px 5px 5px 5px; background-color: #f0ece5; border-left: solid #ff5809; } ul.zc-ref { font-size: 12px; margin-left: 2ex; margin-right: 150px; background-color: #f0ece5; padding: 8px 8px 8px 2em; border: 2px solid #f7ad31; -moz-border-radius: 10px; } ul.zc-ref p { margin: 0; } span.zc-ref { font-weight: bold; } span.zc-ref a { color: inherit; text-decoration: none; } span.zc-ref a:hover { color: inherit; text-decoration: underline; } ul.zc-details { font-size: 12px; margin-left: 2ex; margin-right: 150px; background-color: #f0ece5; padding: 8px 8px 8px 2em; border: 2px solid #f7ad31; -moz-border-radius: 10px; } ul.zc-details p { margin: 0; } div.zc-zinfo { padding-left: 5ex; } /* * Progress bar */ div#zc-pgr-pbar { margin-left: 5ex; } table#zc-pgr-pbar-out { border: 1px solid black; -moz-border-radius: 10px; } table#zc-pgr-pbar-in { margin: 5px; } #zc-pgr-pct0 { border-color: black; } #zc-pgr-pct1 { background-color: #123456; border-color: black; } #zc-pgr-pct2 { border-color: black; } /* */ UL.zc-test { padding-left: 5ex; list-style-type: none; } /* * The diagnostic box */ div.zc-diag { padding-left: 5ex; } div.zc-diag div.zc-name { font-size: 12px; color: #333333; font-weight: bold; } div.zc-diag div.zc-msg { font-size: 12px; color: #1341af; font-weight: bold; } div.zc-diag1 table tr.zc-title { background-color: #ddeeee; } div.zc-status { padding-left: 5ex; font-weight: bold; } h3.zc-diagsec { color: red; } /* Output table: Zone information */ table.zc-domain { border-collapse: collapse; border: solid #0066b2; -moz-border-radius: 10px; } table.zc-domain td { vertical-align: top; padding: 5px; border-color: #0066b2; } tr.zc-zone { background-color: #e6ebf0; font-weight: bold; } tr.zc-ns-sec { font-family: Arial, Helvetica, sans-serif; background-color: #f0ece5; } tr.zc-ns-prim { background-color: #e4dcca; } /* Zone information */ .zc-domain { border-collapse: collapse; border: solid #0066b2; -moz-border-radius: 10px; width: 665px; } .zc-domain .line { width: 665px; clear: both; font-family: Arial, Helvetica, sans-serif; background-color: #f0ece5; height: 35px; } .zc-domain .label { vertical-align: top; padding: 5px; border-color: #0066b2; width: 85px; float: left; } .zc-domain .input { vertical-align: top; padding: 5px; border-color: #0066b2; width: 200px; float: left; } .zc-domain .input input { width: 200px; } .zc-domain .IPlabel { vertical-align: top; padding: 5px; border-color: #0066b2; width: 35px; float: left; } .zc-domain .IPinput { vertical-align: top; padding: 5px; border-color: #0066b2; width: 300px; float: left; } .zc-domain .IPinput input { width: 300px; } .zc-domain #zoneInput { width: 555px; } .zc-domain #zoneInput input { width: 555px; } #zc-zone { background-color: #e6ebf0; font-weight: bold; } #zc-ns-prim { background-color: #e4dcca; } /* Options */ div.zc-options { border-collapse: collapse; border: solid #f5b13d; background-color: #f0ece5; width: 500px; height: auto; } div.zc-options div.line { width: 500px; height: 25px; font-size: 12px; } div.zc-options div.column { padding: 2px 1ex; width: 150px; float: left; } div.zc-options div.doubleColumn { padding: 2px 1ex; width: 325px; float: left; } div.zc-options div.tripleColumn { padding: 2px 1ex; width: 490px; float: left; } div.zc-options div.zc-title { background-color: #e4dcca; width: 500px; height: 20px; font-size: 12px; clear: both; } div.zc-options div#line13 { height: 120px; } input#ha { width: 20px; } input#ds { width: 295px; } /* Help */ .zc-help { width: 880px; border: solid #333333; border-collapse: collapse; clear: both } .zc-help .line { border-color: #333333; width: 880px; clear: both; border-top: solid; border-width: 1px; min-height: 15px; } .zc-help #firstTitle { border: 0px; } .zc-help .zc-key { vertical-align: top; padding-left: 2px; width: 120px; float: left; } .zc-help .zc-value { padding-right: 2px; vertical-align: top; width: 750px; float: left; } .zc-help .zc-title { background-color: #e4dcca; border-top: solid; font-style: italic; } /* Popups */ table.zc-popup { background-color: #f0ece5; color: #333333; border: 3px groove #1341af; border-collapse: collapse; } table.zc-popup tr.zc-title { background-color: #1341af; } table.zc-popup tr.zc-title td { color: #f5b13d; } table.zc-popup tr.zc-title td.zc-title { font-weight: bold; } table.zc-popup tr.zc-title a { color: #f5b13d; font-weight: bold; text-decoration: none; } table.zc-popup tr.zc-title a:hover { color: #ff5809; } table.zc-popup tr.zc-item:hover { background-color: #e4dcca; cursor: pointer; } /* .bleu { color: #0066b2 } .bleuvif { color: #1341AF } .orange { color: #f5b13d } .orangevif { color: #FF5809 } .creme { color: #f0ece5 } .cremefonce { color: #e4dcca } */ zonecheck-3.0.5/www/zonecheck.conf.in000066400000000000000000000016061226210254100175370ustar00rootroot00000000000000# $Id: zonecheck.conf.in,v 1.2 2010/06/01 15:36:07 chabannf Exp $ ScriptAlias @HTML_PATH@/cgi-bin/ @CGIDIR@/ Options ExecCGI Order allow,deny Allow from all AliasMatch ^@HTML_PATH@/?$ @LIBEXEC@/@PROGNAME@/www/html/form.html AliasMatch ^@HTML_PATH@/(en|fr)/?$ @LIBEXEC@/@PROGNAME@/www/html/form.html.$1 AliasMatch ^@HTML_PATH@/(en|fr)/(.*)$ @LIBEXEC@/@PROGNAME@/www/html/$2.$1 Alias @HTML_PATH@/js/ @LIBEXEC@/@PROGNAME@/www/js/ Alias @HTML_PATH@/style/ @LIBEXEC@/@PROGNAME@/www/style/ Alias @HTML_PATH@/img/ @LIBEXEC@/@PROGNAME@/www/img/ Alias @HTML_PATH@/ @LIBEXEC@/@PROGNAME@/www/html/ Options Includes MultiViews Order allow,deny Allow from all zonecheck-3.0.5/zc/000077500000000000000000000000001226210254100140775ustar00rootroot00000000000000zonecheck-3.0.5/zc/cache.rb000066400000000000000000000065671226210254100155050ustar00rootroot00000000000000# $Id: cache.rb,v 1.14 2010/06/23 12:03:26 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.14 $ # DATE : $Date: 2010/06/23 12:03:26 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'sync' require 'dbg' ## ## ## class Cache Nothing = Object::new # Another way to express nil # # Initialize the cache mechanisme # def initialize(name='0x%x'%__id__) @name = name @mutex = Sync::new @list = {} end # # Is caching enabled? # def enabled? ! $dbg.enabled?(DBG::NOCACHE) end # # Clear the items (all if none specified) # def clear(*items) @mutex.synchronize { # Clear item content list = items.empty? ? @list.keys : items list.each { |item| # Sanity check if ! @list.has_key?(item) raise ArgumentError, "Cache item '#{item}' not defined" end # Clear @list[item] = {} } } end # # Define cacheable item # def create(*items) items.each { |item| # Sanity check if @list.has_key?(item) raise ArgumentError, "Cache item '#{item}' already defined" end # Create item @list[item] = {} } end # # Use a cacheable item # def use(item, args=nil, force=false) # Sanity check if ! @list.has_key?(item) raise ArgumentError, "Cache item '#{item}' not defined" end # Caching enabled? return yield unless enabled? # Compute key to use for retrieval key = case args when NilClass then nil when Array then case args.length when 0 then nil when 1 then args[0] else args end else args end # Retrieve information computed, r = nil, nil begin @mutex.synchronize { r = @list[item][key] computed = force || r.nil? if computed r = yield r = Nothing if r.nil? @list[item][key] = r end r = nil if r == Nothing } rescue Sync_m::Err::UnknownLocker => e $dbg.msg(DBG::INIT) { "An error occured on the cache mutex: " + e } end # Debugging information $dbg.msg(DBG::CACHE_INFO) { l = case args when NilClass then "#{item}" when Array then case args.length when 0 then "#{item}" when 1 then "#{item}[#{args[0].to_s}]" else "#{item}[#{args.collect{|e| e.to_s}.join(',')}]" end else "#{item}[#{args.to_s}]" end if computed then "computed(#{@name}): #{l}=#{r}" else "cached (#{@name}): #{l}=#{r}" end } # Returns result r end end endzonecheck-3.0.5/zc/cachemanager.rb000066400000000000000000000303561226210254100170310ustar00rootroot00000000000000# $Id: cachemanager.rb,v 1.40 2010/06/17 09:46:17 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.40 $ # DATE : $Date: 2010/06/17 09:46:17 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ##### # # TODO: # - add a close/destroy function to destroy the cachemanager and free # the dns resources # module ZoneCheck require 'sync' require 'cache' require 'timeout' ## ## The CacheManager ## class CacheManager ## ## Proxy an Dnsruby::RR class ## ## This will allow to add access to extra fields that are normally ## provided only in the DNS message header: ## - ttl : time to live ## - aa : authoritative answer ## - ra : recursivity available ## - r_name : resource name ## class ProxyResource attr_reader :ttl, :aa, :ra, :r_name, :resource # # Initialize proxy # def initialize(resource, ttl, name, header) @resource = resource @ttl = ttl @r_name = name @aa = header.aa @ra = header.ra end # # Save the class method for later use # alias _class class # # Equality should work with proxy object or real object # def eql?(other) return false unless self.class == other.class other = other.instance_eval('@resource') if respond_to?(:_class) @resource == other end alias == eql? # # Redefine basic methods (hash, class, ...) to point to the # real object # def hash ; @resource.hash ; end def to_s ; @resource.to_s ; end def class ; @resource.class ; end def kind_of?(k) ; @resource.kind_of?(k) ; end alias instance_of? kind_of? alias is_a? kind_of? # # Direct all unknown methods to the real object # def method_missing(method, *args) @resource.method(method).call(*args) end end attr_reader :all_caches, :all_caches_m, :root, :query_mode attr_accessor :edns, :domain_name def clear @cache.clear end def query_mode=(param) @query_mode = param case param when "tcp" @resolver.use_tcp = true @resolver.no_tcp = false when "udp" @resolver.use_tcp = false @resolver.no_tcp = true when "std" @resolver.use_tcp = false @resolver.no_tcp = false end end private def initialize(root, resolver) # Root node propagation @root = root.nil? ? self : root @all_caches = root.nil? ? {} : root.all_caches @all_caches_m = root.nil? ? Sync::new : root.all_caches_m # Resolver @resolver = resolver @resolver.do_caching = false @resolver.dnssec = false @edns = false @query_mode = "std" @edns_enabled = nil # Cached items @cache = Cache::new @cache.create(:address, :soa, :any, :ns, :mx, :cname, :a, :aaaa, :ptr, :rec, :dnskey, :rrsig) end def get_resources(name, resource, rec=true, exception=false, dnssec=false, edns=true, cnames={}) msg = Dnsruby::Message::new(name.to_s, resource) msg.do_caching = false msg.header.rd = rec if @edns == "always" || (@edns == "auto" && edns) || (@edns == "autofailed" && dnssec) optrr = Dnsruby::RR::OPT.new(4096) if dnssec optrr.dnssec_ok = dnssec end msg.add_additional(optrr) end begin res = [] ret = @resolver.send_message(msg) ret.answer.each {|rr| if (rr.type == "CNAME") && resource != "AXFR" && resource != "CNAME" && resource != "ANY" if cnames.size > 5 raise "Max CNAME lookup reached" elsif cnames[name.to_s] raise "CNAME loop on #{name.to_s}" else cnames[name.to_s] = true res = res + get_resources(rr.cname, resource, rec, exception, dnssec, edns, cnames) end else res << ProxyResource::new(rr,rr.ttl,rr.name,ret.header) end } return res rescue Dnsruby::ResolvError => e if @edns == "auto" && !dnssec case e when Dnsruby::ServFail, Dnsruby::Refused, Dnsruby::NotImp then @edns = "autofailed" return get_resources(name, resource, rec, exception, dnssec, false, cnames) when Dnsruby::NXDomain then raise e,"(#{resource} #{name})" if exception return [] else raise e,"(#{resource} #{name})" end else if e == Dnsruby::NXDomain raise e,"(#{resource} #{name})" if exception return [] else raise e,"(#{resource} #{name})" end end rescue Dnsruby::ResolvTimeout => e if @edns == "auto" && !dnssec @edns = "autofailed" return get_resources(name, resource, rec, exception, dnssec, edns, cnames) else raise e,"(#{resource} #{name})" end end nil end def get_resource(name, resource, rec=true, exception=false, dnssec=false, edns=true) res = get_resources(name, resource, rec, exception, dnssec, edns) return nil if res.nil? return res[0] end public def [](ip) begin @all_caches_m.synchronize { # Is the root asked? return @root if ip.nil? # Sanity check unless ip.nil? || (ip.class == Dnsruby::IPv4 || ip.class == Dnsruby::IPv6 ) raise 'Argument should be an Address' end # Retrieve/Create the cachemanager for the address ip = ip.to_s if (ic = @all_caches[ip]).nil? resolver = Dnsruby::Resolver::new({:nameserver => ip}) ic = CacheManager::new(@root,resolver) ic.domain_name = @domain_name ic.init(@edns, @query_mode, @resolver.retry_times, @resolver.retry_delay, @resolver.query_timeout) @all_caches[ip] = ic end ic } rescue Sync_m::Err::UnknownLocker => e $dbg.msg(DBG::INIT) { "An error occured on the cachemanager mutex: " + e } end end def init(edns, query_mode, retry_times, retry_delay, query_timeout) @edns = edns self.query_mode = query_mode @resolver.retry_times = retry_times @resolver.retry_delay = retry_delay @resolver.query_timeout = query_timeout if edns == "auto" begin status = Timeout::timeout(3) { msg = Dnsruby::Message::new(@domain_name, "ANY") optrr = Dnsruby::RR::OPT.new(4096) optrr.dnssec_ok = true msg.add_additional(optrr) msg.do_caching = false @resolver.do_caching = false ret = @resolver.send_message(msg) unless ret.nil? || ret.additional.empty? ret.additional.each { |add| if add.type == "OPT" && add.payloadsize > 1024 @edns = edns break end } end } @edns = "auto" rescue Dnsruby::ResolvError @edns = "autofailed" rescue Dnsruby::ResolvTimeout @edns = "autofailed" rescue Timeout::Error @edns = "autofailed" end end return @edns end # Create the root information cache def self.create(resolver) CacheManager::new(nil, resolver) end #-- Shortcuts ---------------------------------------------------- def addresses(host) case host when String if host =~ Dnsruby::IPv4.Regex host = Dnsruby::IPv4::create(host) elsif host =~ Dnsruby::IPv6.Regex host = Dnsruby::IPv6::create(host) else host = Dnsruby::Name::create(host) end addresses(host) when Dnsruby::IPv4 [ host ] when Dnsruby::IPv6 [ host ] when Dnsruby::Name @cache.use(:address, host) { getaddresses(host) } else raise ArgumentError, 'Expecting Address or DNS Name' end end def getaddresses(name) ret = [] error_count = 0; begin ret += get_resources(name.to_s,"A") rescue Dnsruby::NXDomain => e error = e error_count += 1 end begin ret += get_resources(name.to_s,"AAAA") rescue Dnsruby::NXDomain error_count += 1 end raise error if error_count == 2 && !(error.nil?) return ret end # ANY records def any(domainname, resource=nil, force=nil) res = @cache.use(:any, domainname, force) { get_resources(domainname, "ANY") } if resource.nil? return res else nres = [ ] res.each { |r| nres << r if r.class == resource } return nres end end # SOA record def soa(domainname, force=nil) @cache.use(:soa, domainname, force) { get_resource(domainname, "SOA") } end # NS records def ns(domainname, force=nil) @cache.use(:ns, domainname, force) { get_resources(domainname, "NS") } end # MX record def mx(domainname, force=nil) @cache.use(:mx, domainname, force) { get_resources(domainname, "MX") } end # A record def a(name, force=nil) @cache.use(:a, name, force) { get_resources(name, "A") } end # AAAA record def aaaa(name, force=nil) @cache.use(:aaaa, name, force) { get_resources(name, "AAAA") } end # CNAME record def cname(name, force=nil) @cache.use(:cname, name, force) { get_resource(name, "CNAME") } end # PTR records def ptr(name, force=nil) @cache.use(:ptr, name, force) { get_resources(name, "PTR") } end # TXT record def txt(name, force=nil) @cache.use(:ptr, name, force) { get_resources(name, "TXT") } end def dnskey(name, force=false) @resolver.dnssec = true begin ret = @cache.use(:dnskey, name, force) { get_resources(name,"DNSKEY") } ret.delete_if {|res| res.class != Dnsruby::RR::IN::DNSKEY } @resolver.dnssec = false return ret rescue => e @resolver.dnssec = false raise e ensure @resolver.dnssec = false end end def rrsig(name, resource, force=false) if resource.nil? resource = "RRSIG" end ret = @cache.use(:rrsig, [name,resource], force) { get_resources(name,resource, true, false, true) } ret.delete_if {|res| res.class != Dnsruby::RR::IN::RRSIG } return ret end #-- Shortcuts ---------------------------------------------------- def rec(domainname, force=nil) @cache.use(:rec, domainname, force) { soa = soa(domainname, force) raise Dnsruby::ResolvError, 'Domain doesn\'t exists' if soa.nil? soa.ra } end end endzonecheck-3.0.5/zc/config.rb000066400000000000000000000305471226210254100157020ustar00rootroot00000000000000# $Id: config.rb,v 1.42 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/07/19 07:28:13 # REVISION : $Revision: 1.42 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'framework' require 'ext/myxml' require 'instructions' ## ## Hold the information about the zc.conf configuration file ## class Config Warning = 'w' # Warning severity Fatal = 'f' # Fatal severity Info = 'i' # Informational Skip = 'S' # Don't run the test Ok = 'o' # Reserved Profile_Automatic = 'automatic' Preset_Default = 'default' E_PROFILE = 'profile' # XML Elements E_CONFIG = 'config' # . E_PRESET = 'preset' # . E_PARAM = 'param' # . E_CASE = 'case' # . E_WHEN = 'when' # . E_ELSE = 'else' # . E_CONST = 'const' # . E_MAP = 'map' # . E_RULES = 'rules' # . E_CHECK = 'check' # . E_TEST = 'test' # . A_NAME = 'name' # XML attributes A_LONGDESC = 'longdesc' # . A_VALUE = 'value' # . A_ZONE = 'zone' # . A_PROFILE = 'profile' # . A_TEST = 'test' # . A_CLASS = 'class' # . A_SEVERITY = 'severity' # . A_CATEGORY = 'category' # . TestSeqOrder = [ CheckGeneric.family, CheckNameServer.family, CheckNetworkAddress.family, CheckExtra.family, CheckDNSSEC.family ] def self.severity2tag(severity) case severity when NilClass then 'ok' when Config::Info then 'info' when Config::Warning then 'warning' when Config::Fatal then 'fatal' else raise ArgumentError, "unknown severity: #{severity}" end end # # Create a full filename from a configfile # XXX: unix specific '/' def self.cfgfile(configfile) if configfile =~ /^\// then configfile else $zc_config_dir + '/' + configfile end end ## Configuration error ## (unknown test, ordering problem, file not found) ## class ConfigError < StandardError end ## ## Syntax error, while parsing the file ## class SyntaxError < ConfigError attr_reader :path, :line def initialize(string=nil, path=nil, line=nil) super(string) if string @path, @line = path, line end end ## ## Hold mapping information between a 'zone' and a 'profile' ## class ZoneMapping def initialize @data = {} end # Store a new mapping def []=(zone, profilename) zone = Dnsruby::Name::create(zone) $dbg.msg(DBG::CONFIG, "adding mapping: #{zone} -> #{profilename}") @data[zone] = profilename end # Returns the best mapping for a zone (longuest match) def [](zone) depth, profilename = -1, nil @data.each { |tld, name| next unless zone.subdomain_of?(tld) && (depth < tld.labels.size) depth, profilename = tld.labels.size, name } profilename end # Iterate on all the couple |zone, profile| def each(&bloc) @data.each &bloc end def include?(profilename) @data.each {|zone,profile| return true if profile == profilename } return false end end ## ## Store the different preset ## class Presets def initialize @data = {} end # Store a new profile def <<(preset) $dbg.msg(DBG::CONFIG, "adding preset: #{preset.name}") @data[preset.name] = preset end # Retrieve a profile by its name def [](name) @data[name] end # Iterate on |preset| def each(&block) @data.each_value &block end end ## ## Store the different profiles ## class Profiles def initialize @data = {} end # Store a new profile def <<(profile) $dbg.msg(DBG::CONFIG, "adding profile: #{profile.name}") @data[profile.name] = profile end # Retrieve a profile by its name def [](name) @data[name] end # Iterate on |profile| def each(&block) @data.each_value &block end end ## ## Store constants and allow inheritence from parent ## class Constants attr_reader :parent def initialize(parent = nil) @parent = parent @data = {} end def []=(name, value) $dbg.msg(DBG::CONFIG, "adding constant: #{name}") @data[name] = value end def [](name) @data[name] || (@parent ? @parent[name] : nil) end def fetch(name) begin @data.fetch(name) rescue IndexError if @parent then @parent.fetch(name) else raise IndexError, "Unable to fetch ZoneCheck constant '#{name}'" end end end end class Preset attr_reader :name def initialize(name, params) @name = name @data = params end def [](name) @data[name] end end class Profile attr_reader :name, :rules, :constants, :longdesc def validate(testmanager) @rules.each_value { |rules| rules.validate(testmanager) } end def initialize(name, constants, rules, longdesc) @name, @constants, @rules, @longdesc = name, constants, rules, longdesc end def self.from_xmlprofile(xmlprofile, parent=nil) profilename = xmlprofile[A_NAME] longdesc = xmlprofile[A_LONGDESC] constants = Constants::new(parent.constants) rules = {} $dbg.msg(DBG::CONFIG, "processing profile: #{profilename}") xmlprofile.each(E_CONST) { |element| name = element[A_NAME] value = element[A_VALUE] constants[name]=value.untaint } xmlprofile.each(E_RULES) { |element| klass = element[A_CLASS] rules[klass] = parse_block(element) } self::new(profilename, constants, rules, longdesc) end #-- [private] ----------------------------------------------- private def self.parse_block(rule) block = Instruction::Block::new rule.each { |elt| next unless elt.kind_of?(MyXML::Node::Element) block << case elt.name when E_CHECK then parse_check(elt) when E_CASE then parse_case(elt) end } block end def self.parse_check(xmlelt) name, severity, category = xmlelt[A_NAME], xmlelt[A_SEVERITY], xmlelt[A_CATEGORY] block = Instruction::Block::new xmlelt.each { |elt| case elt.name when E_CHECK block << parse_check(elt) end } #puts "Check #{name} : #{xmlelt.inspect}" $dbg.msg(DBG::CONFIG, "creating instruction check: #{name}") Instruction::Check::new(name, severity, category, block) end def self.parse_case(xmlelt) when_stmt, else_stmt = {}, nil testname = xmlelt[A_TEST] xmlelt.each { |elt| next unless elt.kind_of?(MyXML::Node::Element) case elt.name when E_WHEN when_stmt[elt[A_VALUE]] = parse_block(elt) when E_ELSE else_stmt = parse_block(elt) end } $dbg.msg(DBG::CONFIG, "creating instruction test: #{testname}") Instruction::Switch::new(testname, when_stmt, else_stmt) end end # # Initializer # def initialize(test_manager) @test_manager = test_manager end # # Set the overriding configuration profile # def overrideconf(testlist) rules = {} # Order the check by class (or family) testlist.each { |checkname| # Ensure that the check is currently available if ! @test_manager.has_check?(checkname) raise ArgumentError, $mc.get('config:check_unknown') % [ checkname ] end # Ordering (rules[@test_manager.family(checkname)] ||= []) << checkname } # Create a fake configuration fakeprofile = "<#{E_PROFILE} #{A_NAME}=\"override\" #{A_LONGDESC}=\"profile generated to only check a particular set of tests\">\n" TestSeqOrder.each { |family| next unless rules[family] fakeprofile += "<#{E_RULES} #{A_CLASS}=\"#{family}\">\n" rules[family].each { |checkname| fakeprofile += "<#{E_CHECK} #{A_NAME}=\"#{checkname}\" #{A_SEVERITY}=\"#{Fatal}\" #{A_CATEGORY}=\"\"/>\n" } fakeprofile += "\n" } fakeprofile += "\n" fakeconf = "" + "\n" fakeconf += '' + "\n" fakeconf += "<#{E_CONFIG}>" + fakeprofile + "" # Register it as an override profile xmlprofile = MyXML::Document::new(fakeconf).root.child(E_PROFILE) @profile_override = Profile::from_xmlprofile(xmlprofile, self) end # # Read the configuration file # def load(configfile) clear # Parse the configuration file cfgfile = Config.cfgfile(configfile) $dbg.msg(DBG::CONFIG, "loading main configuration: #{configfile}") $dbg.msg(DBG::CONFIG, "reading file: #{cfgfile}") io, main = nil, nil begin io = File::open(cfgfile) main = MyXML::Document::new(io) rescue SystemCallError # for the Errno::ENOENT error raise ConfigError, $mc.get('problem_file') % configfile rescue REXML::ParseException => e raise SyntaxError::new(e.message, cfgfile, e.line) ensure io.close unless io.nil? end main.root.each(E_CONST) { |element| name = element[A_NAME] value = element[A_VALUE] @constants[name] =value.untaint } main.root.each(E_MAP) { |element| zone = element[A_ZONE] profile = element[A_PROFILE] @mapping[zone] = profile.untaint } main.root.each(E_PRESET) { |preset| presetname = preset[A_NAME] params = {} preset.each(E_PARAM) { |param| name = param[A_NAME] value = param[A_VALUE] params[name] = value } @presets << Preset::new(presetname, params) } Dir[ Config.cfgfile('*.profile')].each { |cfgfile| filename = cfgfile.split('/')[-1] profilename = filename.gsub(/\.profile$/, '') next if @profiles[profilename] #next unless @mapping.include?(profilename) || filename == configfile $dbg.msg(DBG::CONFIG, "loading profile: #{filename}") $dbg.msg(DBG::CONFIG, "reading file: #{cfgfile}") io = nil begin io = File::open(cfgfile) doc = MyXML::Document::new(io) rescue SystemCallError # for the Errno::ENOENT error raise ConfigError, $mc.get("problem_file") % cfgfile rescue REXML::ParseException => e raise SyntaxError::new(e.message, cfgfile, e.line) end doc.root.each(E_PROFILE) { |xmlprofile| @profiles << Profile::from_xmlprofile(xmlprofile, self) } } end # # Validate the loaded configuration file # (ie: check the existence of all used methods chk_* and tst_*) # def validate(testmanager) @profiles.each { |c| c.validate(testmanager) } end # # Force use of a particular profile # def profilename=(name) name = nil if name == Profile_Automatic if !name.nil? && @profiles[name].nil? raise ConfigError, $mc.get('config:unknown_profile') % name end @profilename = name end # # Retrieve the bet profile for the zone # def profile(zone) pfile = selected_profile = @profiles[@profilename || @mapping[zone]] if pfile.nil? && zone == Dnsruby::Name::create(".") pfile = selected_profile = @profiles["default"] end if @profile_override # Ensure that the constants from the 'selected' profile # will be used even in overrided profile pfile = Profile::new(@profile_override.name, selected_profile.constants, @profile_override.rules, @profile_override.longdesc) end pfile end attr_reader :constants, :profiles, :presets, :profilename #-- [private] --------------------------------------------------------- private # # Clear the current configuration # (used in: initialize and load) # def clear @constants = Constants::new @profiles = Profiles::new @presets = Presets::new @mapping = ZoneMapping::new @profile_override = nil @profilename = nil end end endzonecheck-3.0.5/zc/console.rb000066400000000000000000000055511226210254100160740ustar00rootroot00000000000000# $Id: console.rb,v 1.11 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/03/17 10:54:53 # REVISION : $Revision: 1.11 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # XXX: NEED CLEANUP # module ZoneCheck class Console ## ## Exception: requested encoding is not possible (conversion lose) ## class EncodingError < StandardError end ## ## ## class IOConv def initialize(console, io, ctl=nil) @io = io @console = console end def puts(*args) @io.puts *args.collect { |e| @console.conv_to(e.to_s) } end def print(*args) @io.print *args.collect { |e| @console.conv_to(e.to_s) } end def printf(*args) @io.printf *args.collect { |e| case e when String then @console.conv_to(e) else e end } end def method_missing(method, *args) @io.method(method).call(*args) end end attr_reader :stdin, :stdout, :stderr attr_reader :encoding attr_reader :ctl def initialize(stdin=$stdin, stdout=$stdout, stderr=$stderr) # Initialize conversion enconding engine @iconv = nil begin require 'iconv' rescue LoadError => e @iconv = false end @encoding = 'UTF-8' # @ctl = { 've' => "\033[?25h", # show cursor 'vi' => "\033[?25l", # hide cursor 'ce' => "\033[K" # clear end of line } # @stdin = IOConv::new(self, stdin) @stdout = IOConv::new(self, stdout, @ctl) @stderr = IOConv::new(self, stderr, @ctl) end def encoding=(encoding) return true if @encoding == encoding # Nothing to change return false if @iconv == false # Don't support convertion @iconv = case encoding when NilClass, 'UTF-8' then nil else Iconv::new(encoding, 'UTF-8') end @encoding = encoding || 'UTF-8' end def conv_to(msg) begin return @iconv ? @iconv.iconv(msg) : msg rescue Iconv::Failure, Iconv::InvalidCharacter => e raise EncodingError, "Can't do full conversion to #{@encoding}" end end end endzonecheck-3.0.5/zc/data/000077500000000000000000000000001226210254100150105ustar00rootroot00000000000000zonecheck-3.0.5/zc/data/catalog.xml000066400000000000000000000011621226210254100171440ustar00rootroot00000000000000 zonecheck-3.0.5/zc/data/config.dtd000066400000000000000000000066331226210254100167620ustar00rootroot00000000000000 zonecheck-3.0.5/zc/data/logo.png000066400000000000000000000151011226210254100164540ustar00rootroot00000000000000PNG  IHDR}osBITOPLTE1kscci{11111!L{11t1s111! qk1mkc1ccc1i)ckckccckckcc!Iscccj9(yckckkskki2}sckcsscϞcc}fkiscsckƎNBcciccsski)csk]sic̻9#sriwxtRNSU"wf3D"D3DݪDUfUw"w"f3DfwU"33D"Nn pHYs  ~!tEXtSoftwareMacromedia Fireworks 4.0&'utEXtCreation Time05/07/04_4g}IDATx\ [Ő)2 'pOl*(^`kP[[omI U*%I07y+ ǦWrduWV7xu7B MZfde6WՖԝrQUR^ҬO^oФ?V7<յnVria^u_z(nN"2{2(D˕΢!W%LfeS9@.+x`pnU* PqlC#A 7{}Afʜ5I}k-oMgsKo4뼲nh\u+:Vd^}Q_vS noo-z4MyR<+pO``԰sv֧Th*Z%K9] Qn0w'PC/*7ϼ8HU&hWir'%^Ը.W3<< )9aNn)N.A]S+>V!Tm2']| -!?&cg6 +.#^PUTZ AZ9:>% b8#D^=\˕},{Y:E͵Uf"IWHo.%lϯЉ9gkj2reog ,)S.\hX,8ݭXgx"؈Sceebz;W^H.ZƷjvrWA`*Ti]^VGbRI:S.s=FcĴZE5["%*ͥ}SRgIˋ{f 1]Whm: vezTCkl ςSGÑߪenǿY$Mde5ug]ӝQ7u׬~34U|ZAFJ2nUSm1吊ڷ}fW>gSOƼA 8`[A}'rłŕiZ+U;4)u?K7#wF;lU#R;o|/smŪԥNk 8 \N3LshwI N7,{x;B\N=(cPEzucԣHo96ѹ֒'i.^2+vSiutcB*WZ;oGIrnϤ[ZL5MHR ĭkCI=bVQTb󥲹?x3 O"O)iBBwTv *M<Gu3:Ţ$23qO[g'꼠WXpfm7V4<`?˘N:3QcoFXλ[=ӯmU"{n6rMCY}gv|~]=b *;IQ+69!YZZ: ^Jn{"HnE_xpτXd *DR ;PBui8Jِ1lsE$ݘ5'eZfϭY,,@5$G)'ڿHZMglYm9'h}[c9\ԡ蹅iR:oSG;AkgzW,@f؞#w4/L٤N.~ J?+˦Q_[c t8r>i}+|S>8ͪIǯK1Rlno3Ba yXݒǦM\/"7nVFpwzyf'۾ejcs--6+3wCꭨHkB>N3tS65#m$eA]cO1z[Ss fo"^XΏ3tl & 1Η:qSn*zGki=0gu׎_I‚͖YaIǒX,LbN$aJsvEif4ZA2 b'_gݶ| $,,, W3Wʼn_%w##]3S0¾4gtFzKSe@eS&s $E#=Qw$2^:__oBpHH//į }̺+nvϟIqgY+`4[2LFak.}_@/x0?R'$0|Y98kXmoR^%p3FkU{q?ptG gCw_iEl~Í넱 >hUUM*4t& Mpɒ[K_MojT cHqc@1Ah< 2âyHq# 4$:HM'a5'|, /߮9Y@{ym?p\:~TP rtPm*.ymɄHLx6&XM5UsHkxg3S"8- ,=@,]*}cg uxL+yM+aH¶f[t8./;6L!D81ެrOR -+n$qgJbHᴛx#/<òQbGiJ&u:rz,VxWhܠlx WYmA[O,3+ZnDw/蹘XɭkKaK=E!y7dV8 I='}!v&.q̇&2.}*MNci^hmr Yʼn=8li] (%7ZS)R zx*ڽ7w@b{ĥԸGp-*Uuܣyov1྾N4J1Q$;|1e0|Dsa|!9Ҕv[R.id_@ܮ'ё ARp3I(cy)KWt$9Kz1qd]Zϑ5ǯ*RK crO>QǶR1}/:eү/_ 2bK[z0" ɟQgUz!yuc赹pv\ss]J#X֣W_VL|ՋL]+ڼ?LQ1`𸸋 u4h՛~x5zg3b87+2Ϋ^E`wJ%Kpzi-ߡbo;{x,chWynj*xC.H8qSG<OGUPh&Mk3H7p3.ZRo^7J5!wUSZ0%vf 9yD8Kh 8:KbN$V' 5בmcvm1(K 0R#) ë:ˠ$aX]~F$5Ĥ =>]b r!qOX:֎jrя]}yԱ: @r3IY\T'Y] ]n:J6+3A 'ՒB:LKMS0?{kFsVxˏ0Nӂ3[wЊ=BDv'q>0^OA\q/_jRX$ "'ZRV+PTQ7X՞k+=Ȝiѝ١k0·߃8U/Laٖ;>c(s&Ad.XciDzֲ萲_aܔ{1[f 1ZO5'T n6h)ah{V _Qݷ]wbp_Z: nvE*(Br)X*?S DDzRAѠ;( guCLӏ'U6"ۤ dGl"}l*؈d0zM4YC+ReE'a(OpuSÌ(reJ|",Hщ?s.yl6YUt~6BW;΂] + 9N[ QQȂdw;[2!`\TU? .5'.mxǶ E?iu|3>;#ߗ=HltcG];eQv_"y!tMsŋuzQ?*M˫ɷ|V̯_ǥ3w܊rW___? )S/IENDB`zonecheck-3.0.5/zc/data/logo.rb000066400000000000000000000544061226210254100163060ustar00rootroot00000000000000# $Id: logo.rb,v 1.6 2010/06/01 15:36:07 chabannf Exp $ # # AUTHOR : Stephane D'Alu # CREATED : 2002/08/02 13:58:17 # # COPYRIGHT: AFNIC (c) 2003 # CONTACT : zonecheck@nic.fr # LICENSE : GPL v2 (or MIT/X11-like after agreement) # # $Revision: 1.6 $ # $Date: 2010/06/01 15:36:07 $ # # CONTRIBUTORS: (see also CREDITS file) # - All graphics are from: David Barou module ZCData module XPM Logo = [ "202 104 22 1", " c None", ". c #2E2E2E", "+ c #1D69FD", "@ c #FEA616", "H c #FAA212", "$ c #84AFF8", "% c #5E5E5E", "& c #A2C2E1", "* c #F5D297", "= c #022296", "- c #E7E5DF", "; c #FEAF30", "> c #C3974D", ", c #FEFEFE", "' c #709DF1", ") c #A4C4FE", "! c #1661FD", "~ c #5B95FA", "{ c #4E4E4E", "] c #C1D6FE", "^ c #297DFD", "/ c #F9C162", "{%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%", "{{%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,**///////////////////////////////////////////////////////////////////////*-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,*;@H@HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH;-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,/HHHHHHHHHHHHHHHH;/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*//HHHHHHHHHHHHHHHHHHHHHH/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,*HHH@HHHHHHHHHH/-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-/HHHHHHHHHHHHHHHHHHH/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,/HHHHH@HHHHHH;-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*HHHHHHHHHHHHHHHH@@*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,/@@H@H@HHHH@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;HHHHHHHHHHH@@@HH*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,@HHHHH@@@@@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;@@@@@@@@@@@HHH;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,*@HHHHHHHH@*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,HHHHHHHHHHHHHH*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,*@@HHHHHH@;,,,,,,,,,,,,,,,,,,,,,,,-)$~~-,,,,,,,,,,,,,,,,,,,,/HHHHHHHHHHH@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,*@HHHHHH@;,,,,,,,,,,,,,,,,,,,]'~^^^^^^$,,,,,,,,,,,,,,,,,,,/@@HHHHHHHHHH/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,*@@@@@@HH,,,,,,,,,,,,,,,,,$^^^^^^^^^^',,,,,,,,,,,,),,,,,/@HH@@@@@@@@@*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,/HHHHHHH-,,,,,,,,,,,,,]~^^^^^^^+^^^^~,,,,,,,,,,,'^^&,,;@@HHHHHHHHH@-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,/HHHHHH*,,,,,,,,,,,,,)^^^^^^^^^^^^^~]],,,,,,,,]^^^^~H@@HHHHHHHHH;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,@H@HHH*,,,,,,,,,,,,,,$^^^^+^^^^+^^^^^^^~~$-,-^^^^~HHHH@HHHHHH@/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,*@H@@;,,,,,,,,,,,,,,,$-^^^^^+^^^^^+^^^^^^^^~^^^^>HHHH@H@@@@@H*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,-HHHH*,,,,,,,,,,,,,,,'--^^^^^++!!!!!!!!++^^^^^^>HHHHHHHHHHH@-,,,,,,,,,,**-,,,,,-***,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,H@@-,,,,,,,,,,,,,,,,$]^^^^+!!!+!!!!+!!!!+++^~HHHHH@HHHHH@;-,,,,,,,,,,;@@H-,-/;@@@@H;*-,,,,,,,,,,,,,,,,,,,,-*/@@;**,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,H/,,,,,,,,,,,,,,,,,,$^^^+!!+!+!!!++!!+!!!+!~HHHHHHH@HHHH;,,,,,,,,,,,,@HHH/*@H@@@H@@H@@*,,,,,,,,,,,,,,,,,*;@HH@@H@@@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,/,,,,,,,,,,,,,,,,,,$^^^!!!+!!!^++!!!!^^+!!>HHHHH@H@H@HH'^$,,,,,,,,,,,H@@@@@H@@HH@HH@@@@/,,,,,,,,,,,,,,,;HHH@@H@@@HHHH*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-^^^!!!!!!^!=========!^>HHHHHHHHHH@H'~'-,,,,,,,,,,,HHH@H@HH@@H@@H@H@@@*,,,,,,,,,,,,,;@@@HH@HHH@H@HH@*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,'],,,,,,^^^!!!+!!^==========={HHHHHH@H@HHH>/-,',,,,,,,,,,,,@@@H@H@@H;//;@H@H@@@,,,,,,,,,,,,/@@@H@@;**/H@H@@HH-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,$^^^~~']~^^!!+!!!+===========%HHHHHHHHHH@@>-,--&,,,,,,,,,,,,HH@H@HH;-,,,,-;@@@@H*,,,,,,,,,,*@HH@H/,,,,,,/HH@HH@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,^^^^^^^^^^^!!!!+^==========.%HHHHHH@H@H@H>^&-,$-,,,,,,,,,,,,@@H@H@/,,,,,,,,@@@@@/,,,,,,,,,,;@@@H/,,,,,,,,*@H@@@/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,]^^^^^^^^^^!!!+!^===========>HHHHHHHHHHHH~^^^,-$,,,,,,,,,,,,,H@H@@;,,,,,,,,,*@H@H@,,,,,,,,,*HHH@;,,,,,,,,,,/@@@@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,~^^^^^^^^^++!!!+^========={HHHHHHH@H@HHH+!^^^]]),,,,,,,,,,,,,@H@H@*,,,,,,,,,,H@H@@,,,,,,,,,;@@@@-,,,,,,,,,,,@H@@@*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,^^^+^^^^^^+!!+!!^=======!%HHHHH@@HHHHH>+!!^^^~$,,,,,,,,,,,,,,@H@@H-,,,,,,,,,,;HH@@,,,,,,,,-@@H@;,,,,,,,,,,,,/@@@H;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,]^^^^^^+^^^+!!+!!+====!~&/@HHHHHHHH@HH>!!!!+^^^),,,,,,,,,,,,,,H@HH@,,,,,,,,,,,;@@HH,,,,,,,,*@H@H*,,,,,,,,,,,,*@HH@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,$^^^^^^^^^^+!!!!!+===^]-;@HHHH@HHHHHH%+++!+^^^~,,,,,,,,,,,,,,,H@@H/,,,,,,,,,,,;@@@@,,,,,,,,/@H@H-,,,,,,,,,,,,-@@HHH-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,$^+^^^^^^^^+!+!+!^==~,*;@@@HHHHHH@HH.!+!!!!+^^~,,,,,,,,,,,,,,,@HHH/,,,,,,,,,,,;HHHH,,,,,,,,@H@H@;;/;/;/;/;/;/;@H@@@-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,&^^^^+^^^^^^!!!!!+!^,*@@HHH@@H@@HH;^=++!!+!^^^^'),,,,,,,,,,,,,@H@H/,,,,,,,,,,,/H@@@,,,,,,,,@H@H@@H@H@H@H@H@H@H@HHH@-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,~^^^^^^^^^^+!+!!!!+&*@@HHH@HHHHH@/,&++!+!!!^^^^^^^^~')-,,,,,,,H@HH/,,,,,,,,,,,;@HHH,,,,,,,,H@H@@@@H@H@H@H@H@H@H@@@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,)^^^^^+^^^^^!!+!+!+^>HH@HHHH@HHH*,,$!!!!!++^^^^^^^^^^^^,,,,,,,H@HH/,,,,,,,,,,,;@@@@,,,,,,,,H@HHHH@H@H@H@H@H@H@HHHH/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,$^^^^^^~-^^^+!!+!!+++'@H@HHHH@@-,,'+!!!+!!^^^^^^^^^^^^~,,,,,,,@H@H/,,,,,,,,,,,/@HHH,,,,,,,,;H@@@@H@H@H@H@H@H@H@@@;-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,]^^^~-,-,]^^^!!!+!!+++^>HH@HH/,,$^+++!!!!+^^^^^+^^^^^^',,,,,,,@HHH/,,,,,,,,,,,;@@@@,,,,,,,,/HHH@/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,-~,,-,-,-,^^^^!+!!!!!!!!^%~>>~^^+!!!!!+!!^^^+^^^^^^^^^],,,,,,,H@@H/,,,,,,,,,,,/HHHH,,,,,,,,*@@@;;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,$],-,-,-,~^^^+!+!!!+!!!!+!!!!!+!+!+!!!++^^^^^^^^^^^^^-,,,,,,,HHHH/,,,,,,,,,,,;@@@@,,,,,-,,-@HH@@-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,',-,-,-,)$^^^+!!!!!!!!+!+!!+!!!!!!+!+^^^^^^^^^^+^^^~,,,,,,,,@@@H/,,,,,,,,,,,/@HHH,,,*@@;,,H@@@@/,,,,,,,,,,,,-**-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,$],-,-,-,']^^^^+!!++!!+!!+!+!!!+!!!+^^+^^^+^^^^^^^^~,,,,,,,,HHHH/,,,,,,,,,,,;@@@@,,,H@@@*,/@H@@@*,,,,,,,,,,-@H@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,-',-,-,]$~--^^^^^+!!!!!!+!!!!+!!!++^^^^^^^^^+^^^^^^-,,,,,,,,@@@H/,,,,,,,,,,,/HHHH,,*@@@H*,,;@@@@@*,,,,,,,,/H@@HH*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,$-,]$$&H>$--~^+^+^!+!!!!!+!!!++^^^^^^^~^^^^^^+^^^',,,,,,,,,HHHH/,,,,,,,,,,,/H@@H--@HH@H,,,-@H@@@@;*,,,,*;@@H@HH*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,-~'&-/H@@'--]^^^^^^^^+^++++^^^^^^^^^&$]$^^^^^^^^^-,,,,,,,,,@@@H/,,,,,,,,,,,*HHH@@@@@@@;,,,,*@HH@@@HH@/@@@@@@H@/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,/HHHH>$*^^^^+^^^^^^^^^^^^^^^^^$-,~--]^^^^^^^',,,,,,,,,,HHHH/,,,,,,,,,,,*@@@@@@HHH@-,,,,,/@H@@H@@H@@@@HH@H*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,-;H@HHHH'~^^^^^^^^+^^^^+^^^^^~],-,&$---]^^^^^^,,,,,,,,,,-@@@H/,,,,,,,,,,,,@HHHHH@@@/,,,,,,,/@@@@H@HHHHH@@;-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,*@HHH@H@H'^^^^^^+^^^^^^^^^)],,-,-,-$]----]^^^^),,,,,,,,/;H;@@H-,,,,,,,,,,,,-@@@@H@@/,,,,,,,,,-/H@H@@@@@H;/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,*@HH@HHHH>^^^^+^^^^^^+^^^^^,,-,-,-,-~------]^^~,,,,,,,*@@@/,**-,,,,,,,,,,,,,,,/@HH/*,,,,,,,,,,,,,**///*-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,/HHHH@HHHH^^+^^^^^^^^^^^^^^^-,-,-,-]$$&------$~,,,,,,,*@HHH/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,-;HHH@HH@HH^^^^^^^^+^^^^^^^^^^,-,-,-$$,-$&----]~$,,,,,,,@@@H@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,-;HHH@HHHH@>^^^^^^^^^^+^^^+^^^^]-,&$$-,,,,$&---~~,,,,,,,-@HHH@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,*HHH@HHHH@HHH$^^^+^^^^^^^^^^^^^^'$$&,,,,,,,,&]-&~],,,,,,,*HHHHH@*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,/@@HHH@HH@HH/,$]]~^^^^^^^+^^^^^^^&,,,,,,,,,,,,$&~&,,,,,,,,*@@H@@@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,/@HH@HH@HHH@/,,-$--]~^^^^^^^^^^^^^~,,,,,,,,,,,,,$$,,,,,,,,,-@H@HHH@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,-;H@HHHHHH@HH*,,,,$-----]~^^^^^^^^^^$,,,,,,,,,,,,,,,,,,,,,,,,,@HHHHH@@/,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,*;HHHH@HH@H@;-,,,,,&&---------&$~~~~^~,,,,,,,,,,,,,,,,,,,,,,,,,*HH@H@H@@;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,*@@HH@HHH@HH/,,,,,,,,&$]-------------]&,,,,,,,,,,,,,,,,,,,,,,,,,,@H@H@H@@H;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,/HHHHHH@HHHH*,,,,,,,,,,-&$&-----------&],,,,,,,,,,,,,,,,,,,,,,,,,,*HHHHHHH@H/-,,,,,,-$$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,$&-,,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,;@HH@HHHHH@;*,,,,,,,,,,,,,,&'$]--------&-,,,,,,,,,,,,,,,,,,,,,,,,,,,@HHHH@HHH@;-,,,,-++!+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^!+!-,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,,,,,,-@@H@@HHH@HH;-,,,,,,,,,,,,,,,,,-&$$$&&]&&',,,,,,,,,,,,,,,,,,,,,,,,,,,,*@H@@HHHHHH;,,,,$++!!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!!+$,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,,,,*@@HHH@H@HHHH*,,,,,,,,,,,,,,,,,,,,,,--]]$&],,,,,,,,,,,,,,,,,,,,,,,,,,,,*@HHH@@HHHHH/,,,$!+!!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!+!!$,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,,,*@@H@HHHHHHH@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-@HHHHHH@@HH@*,,$!!+!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!!!$,,,,,,,,,,,,,,,,,,,,,-,{.", "{{,,,,;HHHHHH@HH@HHHH,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,;@@@HH@HHHH@@*,,$!!+!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!+!!$,,,,,,,,,,,,,,,,,,,,,,-..", "{{,,,;@@H@H@@HHH@HH@H;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/@@HHHHHHH@@HH;,,$!!!!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]+!+!$,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,;HHHHHHH@HHHH@H@@@;*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,**;HHHHH@@HHHHHHHH/,,$!!+!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!!!$,,,,,,,,,,,,,,,,,,,,,,-.{", "{{,,;HH@H@HHHH@HH@HHHH@@H@/;///;///;//HHHHHHHHHHHHHHHHHH@;//;///;////;@@@@@@@@HHHHHHH@@HHH@;,,,$!+!+],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!+!$,,,,,,,,,,,,,,,,,,,,,-,..", "{{,,,//@HHHH@HHHH@HHHHHHH@@HHHHHHHHHHHHHHHHHHHHHHHHHHHHHH@@@@HH@@HHH@HHHH@@HHH@@@HH@HHHH@/*,,,,$!!!!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!!!$,,,,,]$~+^~],,,,,,,,,,-..", "{{,,,,,,,,-------------------,,,,,,,,,,,,,,,,,,,---------------*/***/****/**/***/**/***-,,,,,,,$!!!+],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]+!+!$,,,,~!!!!!!!$,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],,,,,,,,$+!!!],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!!!$,,]^+!!!!!!!!^,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-'^!!++~],,,,$!+!+],-)~+!!+~$,,,,,,,,,,,,,,,,,,,,,,)~+!+~'],,,,,,,,,,,,,,,-'^~$~^^~),,,,,]+!+!$,-++!!+!+!!!!!$,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,$^!+!+!+!+!^),,$!!!!]]+++!+!!!!+$,,,,,,,,,,,,,,,,,]^!!!!!!!++!$,,,,,,,,,,,-^^^^$^''^^^^],,,]!!!!$,^!!+!+!+!+!!!^,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~!!!!!!!!!!!!+],$!+!+'!!!!!!!!!!+!',,,,,,,,,,,,,,,$!!!!!+!+!!!+!^-,,,,,,,,,^^^^^&~~$^^^~^,,,]!!!!$'!+!!+!+!+!+!!+],,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~!!+!+!!!+!+!!!$,$!!!!!!!!+!+++!!!+!~,,,,,,,,,,,,,$!+!!+!!!+!!!!+!^,,,,,,,,,^]^^^^^^^^^~-^,,,]++!!^+!!!!~],]~!!!!+),,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~!!!!!!+!+!!!!!!$,$!!!!+!+!^'$~!+!!!+!],,,,,,,,,,,)!!!!!!^'$$^!!!!!!^,,,,,,-^^$^^^^$~~^^^^~,,,]!!!+!!!++~,,,,-!+!!!$,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'!!!!+!^]],]$++++-,$!+!!!!!$,,,,]~!!!!!^,,,,,,,,,,,++!+++),,,,,)^!!!!!&,,,,)^~'^^^$,)~]]$'$],,,]!!!+!!!!^,,,,,,!+!!!$,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,$!!!+!!&,,,,,,,$$-,,$!!!!+!&,,,,,,,^+!!!!,,,,,,,,,,$!!!!^-,,,,,,,-^+!!!!,,,,^^'$^~,----]]-,],,,,]!+!!!!!!],,,,,]!!+!+],,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^!+!+!',,,,,,,,,,,,,$+!+!!',,,,,,,,]++!!!],,,,,,,,,+!!!!],,,,,,,,,-!!!+!$,,'^^^^^~,,,,,,,,,,,,,,]!!!++!+$,,,,,,~!!+!+,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)!!!!!^,,,,,,,,,,,,,,$!!!!+,,,,,,,,,,~!+!!$,,,,,,,,)!!++',,,,,,,,,,,'++!!+-,^^^^^^~,,,,,,,,,,,,,,]!!+!!!+,,,,,$!+!!!!),,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,~+!!!!],,,,,,,,,,,,,,$!!!!',,,,,,,,,,$!+!!~,,,,,,,,~!!!!),,,,,,,,,,,-!!+!+)-^^^^^^~,,,,,,,,,,,,,,]+!!!+!',,,)^!!!!!!$,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+!+!!+,,,,,,,,,,,,,,,$+!++$,,,,,,,,,,]+!!!~,,,,,,,,!!!!+,,,,,,,,,,,,,+!!+!$,^&]^^~],,,,,,,,,,,,,,]!!!+!+'$~+!+!!+!+',,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!!+!+~,,,,,,,,,,,,,,,$!!!!],,,,,,,,,,,!!!!~,,,,,,,]!!+!~,,,,,,,,,,,,,^+!!!~,^^^^^&,,,,,,,,,,,,,,,]+!!!!+!+!!!!!!+!',,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-!!!!+$,,,,,,,,,,,,,,,$!!!!],,,,,,,,,,,!+!!~,,,,,,,$!+!!+^^~^~^~^~^~^~+!!!!~,^^^^^-,,,,,,,,,,,,,,,]!!!!!!!!+!!!!!~-,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]+!+!!),,,,,,,,,,,,,,,$+!!!],,,,,,,,,,,!!!!~,,,,,,,$!!!+!+!!!!!!!!!!!!!+!+!~&^&]^^-,,,,,,,,,,,,,,,]++!+!+!!+!++'-,,,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!!!!],,,,,,,,,,,,,,,$!!+!],,,,,,,,,,,!!!!~,,,,,,,~!!!!!!!!!!!!!!!!!!!!!!!'~^^^^^$,,,,,,,,,,,,,,,]!!!!!!!!!+$-,,,,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-+!!!!],,,,,,,,,,,,,,,$!!!!],,,,,,,,,,,!!!!~,,,,,,,'+!!+!!!!!!!!!!!!!++!!!+-^^^^^^^,,,,,,,,,,,,,,,]!+!+!!+!++',,,,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,!!++!],,,,,,,,,,,,,,,$!+!+],,,,,,,,,,,+!!!~,,,,,,,)!+!!+!!!!!!!+!+!+!!!++),$^^^^^^,,,,,,,,,,,,,,,]+!!!!+!+!!+',,,,,,,,,,,,,,-,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+!!!+',,,,,,,,,,,,,,,$!!!!],,,,,,,,,,,!!!!~,,,,,,,]+!!!+,,,,,,,,,,,,,,,,,,,~^^^^^^,,,,,,,,,,,,,,,]!+!+$^+!+!++',,,,,,,,,,,,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^!!!!+,,,,,,,,,,,,,,,$!+!+],,,,,,,,,,,+!!!~,,,,,,,,!+!!!),,,,,,,,,,,,,,,,,,]^^])^!,,,,,,,,,,,,,,,]!!!!$,^+!!!!+',,,,,,,,,,,,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,&!!!!!$,,,,,,,,,,,,,,$!!!!],,,,,,,,,,,!!!!~,,,,--,,^+!!+',,,,,,,,,,,,,,,,,,,^^$&++^~,,,,,,,,,,,,,]!!!!$,,^+!!!+!',,,,,,,,,,,,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-!+!+!+,,,,,,,,,,,,,,$!+!+],,,,,,,,,,,+!!!~,,,^!!~,$!!!!+-,,,,,,,,,,,,$~$,,,]^++~^^^^),,,-]$'$-,,]++!!$,,,^++!!!+',,,,,-&),,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^+!!!!^,,,,,,,,,,,,,$!!!!],,,,,,,,,,,!!!!~,,)++!!)-+!+!!^,,,,,,,,,,-^+!!$,,,]^+]&^^^^$,~^^^^^^),]!!!!$,,,,^+!+!!+',,,]+!!',,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]!!+!!+^],,,,-]$$-,,$!+!+],,,,,,,,,,-+!!!~,,~!!!+-,$!!+!+^-,,,,,,,]++!+!+,,,,)^$~^^^^^+^^^^^^^^,]!!!!$,,,,,^+!!!!+',,^!!!!--,{.", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,)!+!!+!+^'~++!!!!],$!!!!],,,,,,,,,,,!!!!^,'!!+!^,,,~!!!+++'),,,]'!!+!!!^,,,,]^^^^^^^^+~^^^^~-$]]+!!!$,,,,,,^++!!!!~$!!+!!],-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,$!!!!+!!!!+!!+++$,$!+!+],,,,,,,,,,,+!!!!!!!!!!$,,,-^+!!!++!!~+!+!+!!!+],,,,,^^^^^^&~^-]^^^^&'$]!!!!$,,,,,,,^+!!!+!!!!!!^,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,$+!!!!!!!!!!!!!$,$!!!!],,,,,,,,,,,^+!!+!!!!!^,,,,,]+!+!+!!!!!!+!!!+^,,,,,,,)^^^^~-$+''^^^^^^]]+!!!$,,,,,,,,^++!!+!+!!!],,-.{", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,'!!!+!!!!+!!+^,,$!!+!],,,,,,,,,,,]!!!!!++!!),,,,,,)+!!!!+!!+!!!!+$,,,,,,,,,$^^^^^+^^^^^^^^^,]!!!!$,,,,,,,,,^+!+!!!++),,-,..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]$++!+!!+!!',,,-++!+,,,,,,,,,,,,,$!+!!!!!),,,,,,,,,$^!!+!!!!!+~],,,,,,,,,,,]^^^^~~^^^^^^^-,,^!+!-,,,,,,,,,,'!!+!!^],,,,-..", "{{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-$~^~$),,,,,,-$$-,,,,,,,,,,,,,,]~+!^'],,,,,,,,,,,,]$$~~$]-,,,,,,,,,,,,,,,,$'],,)~~~)-,,,,,$$-,,,,,,,,,,,,-&$$],,,,,-,{.", "{{,,----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------..", "{{,-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------..", "{{........................................................................................................................................................................................................", "{........................................................................................................................................................................................................." ] end end zonecheck-3.0.5/zc/data/msgcat.dtd000066400000000000000000000073441226210254100167730ustar00rootroot00000000000000 zonecheck-3.0.5/zc/data/xpm.rb000066400000000000000000000360501226210254100161450ustar00rootroot00000000000000# $Id: xpm.rb,v 1.9 2010/06/01 15:36:07 chabannf Exp $ # # AUTHOR : Stephane D'Alu # CREATED: 2002/08/02 13:58:17 # # COPYRIGHT: AFNIC (c) 2003 # CONTACT : zonecheck@nic.fr # LICENSE : GPL v2 (or MIT/X11-like after agreement) # # $Revision: 1.9 $ # $Date: 2010/06/01 15:36:07 $ # # CONTRIBUTORS: (see also CREDITS file) # - All graphics (except Book_* and Minipage) are from: # David Barou # - Book_open, Book_closed and Minipage are from ruby-gtk # module ZCData module XPM Book_open = [ "16 16 4 1", " c None s None", ". c black", "X c #808080", "o c white", " ", " .. ", " .Xo. ... ", " .Xoo. ..oo. ", " .Xooo.Xooo... ", " .Xooo.oooo.X. ", " .Xooo.Xooo.X. ", " .Xooo.oooo.X. ", " .Xooo.Xooo.X. ", " .Xooo.oooo.X. ", " .Xoo.Xoo..X. ", " .Xo.o..ooX. ", " .X..XXXXX. ", " ..X....... ", " .. ", " " ] Book_closed = [ "16 16 6 1", " c None s None", ". c black", "X c red", "o c yellow", "O c #808080", "# c white", " ", " .. ", " ..XX. ", " ..XXXXX. ", " ..XXXXXXXX. ", ".ooXXXXXXXXX. ", "..ooXXXXXXXXX. ", ".X.ooXXXXXXXXX. ", ".XX.ooXXXXXX.. ", " .XX.ooXXX..#O ", " .XX.oo..##OO. ", " .XX..##OO.. ", " .X.#OO.. ", " ..O.. ", " .. ", " " ] Minipage = [ "16 16 4 1", " c None s None", ". c black", "X c white", "o c #808080", " ", " ....... ", " .XXXXX.. ", " .XoooX.X. ", " .XXXXX.... ", " .XooooXoo.o ", " .XXXXXXXX.o ", " .XooooooX.o ", " .XXXXXXXX.o ", " .XooooooX.o ", " .XXXXXXXX.o ", " .XooooooX.o ", " .XXXXXXXX.o ", " ..........o ", " oooooooooo ", " " ] Info = [ "16 16 50 1", " c #7C5719", ". c #504F4C", "X c #545250", "o c #5A5956", "O c gray40", "+ c #73716E", "@ c #777571", "# c #797774", "$ c #0066B2", "% c #835C1A", "& c #8D631C", "* c #91661D", "= c #9B6D1F", "- c #A27120", "; c #B47E24", ": c #84827E", "> c #C78B27", ", c #D4952A", "< c #DF9E31", "1 c #E5A539", "2 c #EDAE44", "3 c #F5B64C", "4 c #F5BA56", "5 c #F8BD5C", "6 c #F9C46B", "7 c #FACB7B", "8 c #908E89", "9 c #96938F", "0 c #ADAAA5", "q c #B3B0AB", "w c #B8B5B0", "e c #BCB9B4", "r c #C7C3BE", "t c #FACD83", "y c #FAD18B", "u c #FBD494", "i c #CBC8C2", "p c #D3CFC9", "a c #D4D0CA", "s c #DEDAD5", "d c #E0DCD6", "f c #E7E4DE", "g c #EBE7E1", "h c #EEEAE4", "j c #F1EEE7", "k c #F4F2ED", "l c #F6F4F0", "z c #F9F8F5", "x c gray100", "c c None", "cccccccccccccccc", "cccccty7642ccccc", "ccccuzzllhd1cccc", "cccuzz$$hhdpc", "c7lhhh$$hhhhh0;c", "c6khhh$$hhhhh9-c", "c5jhhh$$hhhhd+*c", "c3gfhh$$hhhs:O=c", "cc2s$$$$$$s#o&cc", "ccc1aaghhs@.%ccc", "cccc;=%&ccccc", "cccccccccccccccc" ] Warning = [ "16 16 64 1", " c black", ". c #003156", "X c #00345B", "o c #00365E", "O c #003E6C", "+ c #004274", "@ c #00497F", "# c #664714", "$ c #795518", "% c #7F5919", "& c #004B83", "* c #00508C", "= c #0C5185", "- c #085C9B", "; c #1A659D", ": c #2E73A6", "> c #2C79B2", ", c #3883BB", "< c #468DC2", "1 c #4A94C5", "2 c #5292C2", "3 c #6699CC", "4 c #77ADD6", "5 c #7FB2D8", "6 c #835C1A", "7 c #8A601B", "8 c #91661D", "9 c #A07429", "0 c #AC7922", "q c #B57B21", "w c #B7822A", "e c #BE882D", "r c #B3883F", "t c #C18726", "y c #C68A27", "u c #E8A22E", "i c #EFA82F", "p c #F1AA32", "a c #F7AD31", "s c #F4B03F", "d c #CCA25C", "f c #D8A248", "g c #D9AD64", "h c #F8B442", "j c #E8BD74", "k c #85B5D9", "l c #84B5DA", "z c #91BDDE", "x c #A5C9E4", "c c #ABCDE6", "v c #B3D1E8", "b c #EAC485", "n c #FBD594", "m c #FBD89C", "M c #F5D6A4", "N c #F9DEB1", "B c #F8E1BA", "V c #FDE7C3", "C c #FDEACA", "Z c #FDECCF", "A c #FEF0D9", "S c #FEF2DE", "D c gray100", "F c None", "FFFFFFF1FFFFFFFF", "FFFFFFF5FFFFFF", "FFFFFzSng;FFFFFF", "FFFFFvA fe-FFFFF", "FFFFlZm pw*FFFFF", "FFFFcZh ay0*FFFF", "FFFlZma ai0&FFFF", "FFFcZha aay0*FFF", "FF5Zmaa aai0&FFF", "FFxChaaaaaayq*FF", "F4Vnaaa aaait0*F", "FlMsaaaaaaaau7+F", "3bdr9876666$##%@", ",:=+OOoooooo..X+" ] Fatal = [ "16 16 86 1", " c #002846", ". c #003054", "X c #00355C", "o c #003A65", "O c #003E6D", "+ c #004274", "@ c #004679", "# c #513910", "$ c #604313", "% c #694915", "& c #765317", "* c #7A5518", "= c #624920", "- c #004B83", "; c #00508B", ": c #005594", "> c #005899", ", c #0066B2", "< c #1169AA", "1 c #146EB2", "2 c #1271B7", "3 c #1B73B5", "4 c #287BB9", "5 c #2B7EBC", "6 c #2B80BF", "7 c #3A88C3", "8 c #3F8BC4", "9 c #4C94C9", "0 c #5196CA", "q c #5C9DCE", "w c #66A3D1", "e c #6BA6D2", "r c #73ABD5", "t c #865E1B", "y c #8A601B", "u c #96691E", "i c #A07020", "p c #A17120", "a c #AA7722", "s c #B37E24", "d c #BF8626", "f c #B98632", "g c #C98D29", "h c #CC8F29", "j c #D1932A", "k c #D4952B", "l c #DE9B2C", "z c #D79A33", "x c #D69A36", "c c #DA9E38", "v c #E8A22E", "b c #ECA630", "n c #F0AB37", "m c #F7AD31", "M c #E1A642", "N c #EAB355", "B c #EDB250", "V c #F2B95A", "C c #F8BB54", "Z c #F1BC62", "A c #F7BE60", "S c #F8C56E", "D c #F7C573", "F c #85B6DA", "G c #8DBBDD", "H c #92BEDE", "J c #9EC5E2", "K c #A1C7E3", "L c #A7CBE5", "P c #B9D5EA", "I c #BCD7EB", "U c #F9CE85", "Y c #FAD089", "T c #FBD492", "R c #FCDCA8", "E c #FCDFAD", "W c #FCE1B3", "Q c #C4DCED", "! c #D5E6F2", "~ c #FDE7C2", "^ c #E0ECF6", "/ c #EFF5FA", "( c #F1F1F0", ") c #F3F8FB", "_ c gray100","` c None", "`````qwq9753````", "````rWRTUSVN<```", "```HWWRYDABMc>``", "``J~~WCmmmncjh>`", "`wRETC,,m,,bgdd:", "`0TUmm,,m,,mlaa-", "`8DZnmmmmmmmhuu@", "`4NMxkvmmmjy$$&O", "`1>;siy&$ .o``", "q````:fit*X(```Q", ",8F!``:-++`)QHq6", "`PF76qJ!^Kr80GI/", ")```!e7226r!````", "9GF76qJ!^Kr80GLK", ",8F!```````)QH00" ] Element = [ "16 16 65 1", " c None", ". c #003B67", "+ c #FFFFFF", "@ c #CB8E28", "# c #9E6F20", "$ c #2075B4", "% c #86B6DA", "& c #F9C46A", "* c #5296CA", "= c #01518C", "- c #B17C23", "; c #E1A94D", "> c #8A6F43", ", c #FBD596", "' c #F7AD31", ") c #0C609F", "! c #65A3D0", "~ c #4C94C9", "{ c #856227", "] c #DD9D31", "^ c #FACB7B", "/ c #00477C", "( c #BC8427", "_ c #9D8254", ": c #AD7922", "< c #72AAD4", "[ c #EEB555", "} c #015797", "| c #F7D295", "1 c #136BAD", "2 c #2A7FBE", "3 c #EDA62F", "4 c #5A9CCD", "5 c #F5C77A", "6 c #004476", "7 c #004B83", "8 c #FCDCA6", "9 c #C58B28", "0 c #05538E", "a c #E9A42E", "b c #EDB85F", "c c #A47320", "d c #F7B13C", "e c #6EA8D3", "f c #3381BC", "g c #FAC772", "h c #DDA13B", "i c #054879", "j c #529CCE", "k c #6AA5D0", "l c #055693", "m c #FACE84", "n c #00426B", "o c #CE9429", "p c #9F7022", "q c #84B5DE", "r c #B88125", "s c #075FA1", "t c #BD8C29", "u c #7BB0D7", "v c #025B9E", "w c #156DAF", "x c #6699CC", "y c #004578", "z c #C88F30", " ", " 2 ", " ~f ", " k5$ ", " %|b1 ", "4un ", " 0_. ", " 0i ", " l ", " ", " " ] Zone = [ "16 16 67 1", " c #004272", ". c #00477C", "X c #004C84", "o c #00508C", "O c #005493", "+ c #00599C", "@ c #0361A6", "# c #0063AC", "$ c #0763A8", "% c #0063B5", "& c #0868B0", "* c #0A6CB4", "= c #0D6DB5", "- c #126AAC", "; c #196BB5", ": c #1973B6", "> c #2078BA", ", c #287DBD", "< c #3183C1", "1 c #3586C2", "2 c #3988C3", "3 c #418DC6", "4 c #4F95CA", "5 c #5A9CCD", "6 c #6EA8D3", "7 c #71AAD4", "8 c #79AFD7", "9 c #835C1A", "0 c #8D631C", "q c #93671D", "w c #9C6D1F", "e c #A07020", "r c #A37220", "t c #A97621", "y c #AD7922", "u c #B47E24", "i c #B88125", "p c #BA8225", "a c #C08626", "s c #C68A27", "d c #CC8F29", "f c #CE912A", "g c #D2932A", "h c #D9992E", "j c #DF9C2D", "k c #DC9C31", "l c #E6A230", "z c #E6A537", "x c #EBA530", "c c #EFAA35", "v c #F6AD32", "b c #F1AD3C", "n c #F6B03B", "m c #F1B043", "M c #F7B444", "N c #F1B349", "B c #F8B749", "V c #F8BA51", "C c #F9BD5A", "Z c #F9C164", "A c #F9C265", "S c #F9C46B", "D c #F9C671", "F c #FACB7B", "G c #FACF87", "H c gray100", "J c None", "JJJJJJJJJJJJJJJJ", "JJJJJZ31,NbJJJJJ", "JJJJDFDACNzzJJJJ", "JJJ5GFA:;zljOpe09wJJ", "JJJ;-zhfatq9wJJJ", "JJJJ$kfayw0 JJJJ", "JJJJJjgsptyJJJJJ", "JJJJJJJJJJJJJJJJ" ] Primary = [ "16 16 36 1", " c #573D11", ". c #745117", "X c #0066B2", "o c #835C1A", "O c #8C621C", "+ c #93671D", "@ c #976A1E", "# c #9A6C1F", "$ c #9E6F1F", "% c #A57321", "& c #AE7A23", "* c #BD8425", "= c #BE8526", "- c #C28826", "; c #CB8F2A", ": c #CD902A", "> c #DB9C33", ", c #EAA83A", "< c #EBA93B", "1 c #F7AD31", "2 c #E1A541", "3 c #EBAD44", "4 c #EDAF47", "5 c #EFB34D", "6 c #F4B750", "7 c #F7BC58", "8 c #F9C061", "9 c #F9C46C", "0 c #FAC978", "q c #FACF86", "w c #FAD08A", "e c #FBD698", "r c #FBD89D", "t c #FCE1B3", "y c gray100", "u c None", "uuuuuuuuuuuuuuuu", "uuuuuuuuuuuuuuuu", "uuqeeq0998864uu", "uuwrXXXX1111::uu", "uuqq11XX1111--uu", "uu0011XX1111&&uu", "uu9911XX1111%%uu", "uu9911XX1111$$uu", "uu9911XX1111$$uu", "uu8811XX1111##uu", "uu77XXXXXX11OOuu", "uu6511111111.ouu", "uu32:*&%$@O. .uu", "uu<>;*&%$@Oo.+uu", "uuuuuuuuuuuuuuuu" ] Secondary = [ "16 16 36 1", " c #573D11", ". c #745117", "X c #0066B2", "o c #835C1A", "O c #8C621C", "+ c #93671D", "@ c #976A1E", "# c #9A6C1F", "$ c #9E6F1F", "% c #A57321", "& c #AE7A23", "* c #BD8425", "= c #BE8526", "- c #C28826", "; c #CB8F2A", ": c #CD902A", "> c #DB9C33", ", c #EAA83A", "< c #EBA93B", "1 c #F7AD31", "2 c #E1A541", "3 c #EBAD44", "4 c #EDAF47", "5 c #EFB34D", "6 c #F4B750", "7 c #F7BC58", "8 c #F9C061", "9 c #F9C46C", "0 c #FAC978", "q c #FACF86", "w c #FAD08A", "e c #FBD698", "r c #FBD89D", "t c #FCE1B3", "y c gray100", "u c None", "uuuuuuuuuuuuuuuu", "uuuuuuuuuuuuuuuu", "uuqeeq0998864uu", "uuwrXX11XX11::uu", "uuqq1111XX11--uu", "uu001111XX11&&uu", "uu99111XX111%%uu", "uu9911XX1111$$uu", "uu991XX11111$$uu", "uu88XX111111##uu", "uu77XXXXXX11OOuu", "uu6511111111.ouu", "uu32:*&%$@O. .uu", "uu<>;*&%$@Oo.+uu", "uuuuuuuuuuuuuuuu" ] Reference = [ "16 16 10 1", " c #0066B2", ". c #ABBEC4", "X c #E6DECD", "o c #EBE5D7", "O c #EEE9DE", "+ c #F0ECE5", "@ c #F6F3EF", "# c #F7F4F0", "$ c gray100", "% c None", "%%% %%%%%%%%%", "%%% @@ %%%%%%%%%", "%% ++ %%%%%%%%", "% +++@ %%%%%%%%", "% #++++ %%%%%%%", " +++++@ ", " #+++++ XXXXXO ", " +++++ .XXXXX ", "% +++ XXXXXX ", "% o++ .XXXXXX ", "% + XXXXXX ", "%% .XXXXXX %", "%%% XX %", "%%%%% XXXX %", "%%%%%% OoX %%", "%%%%%%%%%% %%" ] Detail = [ "16 16 46 1", " c None", ". c #DBD7D1", "+ c #94928E", "@ c #9F6F20", "# c #E4E1DC", "$ c #F9BF5D", "% c #C2C0BB", "& c #ABA8A3", "* c #868380", "= c #999999", "- c #375395", "; c #C78B27", "> c #FCDFB0", ", c #EEEAE4", "' c #000000", ") c #FACF86", "! c #28458A", "~ c #47609D", "{ c #B37E24", "] c #F5F3EE", "^ c #F9C368", "/ c #BCBAB5", "( c #2E4C93", "_ c #DFDCD5", ": c #2C4784", "< c #AA7722", "[ c #B5B2AC", "} c #3B5799", "| c #CDC9C3", "1 c #D5D1CB", "2 c #F0EDE6", "3 c #E6E3DD", "4 c #2A488C", "5 c #000000", "6 c #4B65A4", "7 c #000000", "8 c #2F4984", "9 c #F2EFEB", "0 c #E3DFD9", "a c #F9C671", "b c #C6C3BD", "c c #D6D3CD", "d c #000000", "e c #345195", "f c #445E9D", "g c #26417F", " ", " !!!! ", " 44003_8g ", " 4_3299_8 ", " (.1_,,]9.g ", " e|[_222]#: ", " }b=|2229#: ", " fc=+b.###! ", " ~%+*&1_4> ", " 66|/b.4$>) ", " 6f-( ; c #EAB55D", ", c #B8852F", "' c #448BC0", ") c #0B62A2", "! c #D59C3D", "~ c #EED2A3", "{ c #8BB9DC", "] c #023F6D", "^ c #AA7928", "/ c #21567D", "( c #64A1CF", "_ c #1671B5", ": c #F2AE3E", "< c #DC9F38", "[ c #12619B", "} c #9B7536", "| c #FACD82", "1 c #E6BC76", "2 c #AE833B", "3 c #A8CBE5", "4 c #C5933E", "5 c #E8B560", "6 c #004F8A", "7 c #003366", "8 c #DAA956", "9 c #F9D291", "0 c #327FB9", "a c #0066B2", "b c #4A92C7", "c c #F8DCAF", "d c #EEC581", "e c #5599CB", "f c #CC9933", "g c #E9A431", "h c #074A7D", "i c #D69C42", "j c #A77726", "k c #72AAD4", "l c #F8C369", "m c #B58A42", "n c #E0B368", "o c #01355C", "p c #075894", "q c #3282BD", "r c #93BEDE", "s c #A87E38", "t c #BC872D", "u c #186298", "v c #EFB553", "w c #478FC5", "x c #FBDAA3", "y c #024475", "z c #1E70AE", "A c #E1A43E", "B c #4E95CA", "C c #599BCD", "D c #F0BD68", "E c #F0AC3C", "F c #034D85", "G c #AB8545", "H c #EEB95F", "I c #B27E26", "J c #065EA0", "K c #003A65", "L c #1065A4", "M c #EDBF71", "N c #EACD9C", "O c #5297CB", "P c #418DC5", "Q c #8DBBDD", "R c #F4B040", "S c #A07A3B", "T c #F9D08B", "U c #06538D", "V c #F8D7A0", "W c #3184B5", "X c #E8A638", "Y c #D4A049", "Z c #176199", "` c #FCDEAC", " ", " Beq ", " B $9w # ", " kx{r|Cbblq ", " C`c=1:5DDvv_ ", " r~XsS2!*!L ", " rN2.KyuAf& ", " CQ3dGK 0> zonecheck-3.0.5/zc/dbg.rb000066400000000000000000000111341226210254100151600ustar00rootroot00000000000000# $Id: dbg.rb,v 1.30 2010/06/23 12:03:59 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/09/16 13:31:29 # REVISION : $Revision: 1.30 $ # DATE : $Date: 2010/06/23 12:03:59 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'thread' ## ## Debugging ## class DBG # # Debugging types # INIT = 0x0001 # Initialisation LOCALE = 0x0002 # Localization / Internationalisation CONFIG = 0x0004 # Configuration AUTOCONF = 0x0008 # Autoconf LOADING = 0x0010 # Loading tests TESTS = 0x0020 # Tests performed TESTDBG = 0x0040 # Debugging messages from tests CACHE_INFO = 0x0400 # Information about cached object DBG = 0x0800 # Debugger itself CRAZYDEBUG = 0x1000 # Crazy Debug, don't try it... DNSRUBY = 0x2000 # Dnsruby debugging messages NOCACHE = 0x4000 # Disable caching DONT_RESCUE = 0x8000 # Don't try to rescue exceptions # # Tag associated with some types # Tag = { INIT => 'init', LOCALE => 'locale', CONFIG => 'config', AUTOCONF => 'autoconf', LOADING => 'loading', TESTS => 'tests', TESTDBG => 'testdbg', CACHE_INFO => 'cache', DBG => 'dbg' } # # Initializer # def initialize(lvl=0, output=$stderr) @output = output @lvl = lvl @mutex = Mutex::new @old_messages = [] msg(DBG) { "Debugger initialized at level %0x" % @lvl } end # # Test if debug is enabled for that type # def enabled?(type) @lvl & type != 0 end alias [] enabled? # # Enable debugging for the specified type # def []=(type, enable) self.level = enable ? @lvl | type : @lvl & ~type end # # Change debugging level # def level=(lvl) old_crazydebug = enabled?(CRAZYDEBUG) old_dnsruby = enabled?(DNSRUBY) # parsing case lvl when String then @lvl = lvl =~ /^0x/ ? lvl.hex : lvl.to_i when Fixnum then @lvl = lvl else raise ArgumentError, "unable to interprete: #{lvl}" end # message msg(DBG) { "Setting level to 0x%0x" % lvl } # enable/disable Dnsruby if enabled?(DNSRUBY) ^ old_dnsruby Dnsruby::TheLog.level = Logger::DEBUG if enabled?(DNSRUBY) end # enable/disable CrazyDebug if enabled?(CRAZYDEBUG) ^ old_crazydebug dbgfunc = if enabled?(CRAZYDEBUG) proc { |event, file, line, id, binding, classname| @output.printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname } else nil end set_trace_func(dbgfunc) end failed_messages = @old_messages @mutex.synchronize { @old_messages = [] } failed_messages.each {|type,msg| msg(type,msg) unless msg.nil? } end # # Print debugging message # WARN: It is adviced to use a block instead of the string # second argument, as this will provide a lazy evaluation # def msg(type, arg=nil) unless block_given? ^ !arg.nil? raise ArgumentError, 'either string or block should be given' end arg = yield if block_given? arg = arg.to_s unless enabled?(type) @mutex.synchronize { @old_messages << [type,arg] } return end @mutex.synchronize { case arg when Array case arg.size when 0 raise ArgumentError, 'the array argument must not be empty' when 1 @output.puts "DBG[#{Tag[type]}]: #{arg[0]}" else tag = "DBG[#{Tag[type]}]" tagfiller = " " * tag.size @output.puts "#{tag}: #{arg[0]}" arg[1..-1].each { |l| @output.puts "#{tagfiller}| #{l}" } end else @output.puts "DBG[#{Tag[type]}]: #{arg}" end } end def self.status2str(status, ok=true) case status when FalseClass, TrueClass then status == ok ? 'passed' : 'failed' when NilClass, Exception then 'exception' else 'n/a' end end end end zonecheck-3.0.5/zc/ext/000077500000000000000000000000001226210254100146775ustar00rootroot00000000000000zonecheck-3.0.5/zc/ext/array.rb000066400000000000000000000025051226210254100163440ustar00rootroot00000000000000# $Id: array.rb,v 1.8 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.8 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # class Array def unsorted_eql?(other) unless (self.class == other.class) && (self.size == other.size) return false end oc = other.clone self.each { |e| return false unless i = oc.index(e) oc.delete_at(i) } return oc.empty? end end zonecheck-3.0.5/zc/ext/file.rb000066400000000000000000000024361226210254100161500ustar00rootroot00000000000000# $Id: file.rb,v 1.4 2010/06/07 08:51:26 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/12/22 15:40:37 # REVISION : $Revision: 1.4 $ # DATE : $Date: 2010/06/07 08:51:26 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # class File def self.shrink_path(path, sep=nil) spath = sep.nil? ? [ path ] : path.split(/#{sep}/, -1) if ENV['HOME'] spath.collect! { |p| p.gsub(/^#{ENV['HOME']}/, '~') } end spath.join(sep) end end zonecheck-3.0.5/zc/ext/myxml.rb000066400000000000000000000120521226210254100163720ustar00rootroot00000000000000# $Id: myxml.rb,v 1.8 2010/06/07 08:51:26 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/12/15 10:58:17 # REVISION : $Revision: 1.8 $ # DATE : $Date: 2010/06/07 08:51:26 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # XML_CATALOG_FILES=~/Repository/zonecheck/zc/data/catalog.xml # type # - string => xpath (but only yield elements) # - false => elements # - true => nodes module MyXML Implementation = (Proc::new { if $zc_xml_parser $zc_xml_parser.intern else begin require 'xml/libxml' :libxml rescue LoadError :rexml end end }).call class Node class Element < Node ; end class Text < Node ; end class Comment < Node ; end def child(type=:element, idx=1) each(type) { |node| return node if (idx -= 1) <= 0 } return nil end def to_a(type=:element) res = [] each(type) { |node| res << node } res end end end case MyXML::Implementation when :libxml #-- BEGIN: libxml specific -------------------------------------------- require 'xml/libxml' module MyXML class Document def initialize(doc) @parser = XML::Parser::new case doc when String then @parser.string = doc when IO then @parser.io = doc else raise ArgumentError, "String or IO expected" end @doc = @parser.parse end def root ; Node::create(@doc.root) ; end end class Node class Element < Node def name ; @node.name ; end def [](attr) ; @node[attr] ; end end def self.create(node) klass = case node.node_type when XML::Tree::ELEMENT_NODE then Element when XML::Tree::TEXT_NODE then Text when XML::Tree::COMMENT_NODE then Comment else Node end klass::new(node) end def initialize(node) ; @node = node ; end def value ; @node.content ; end def text ; @node.to_s ; end def parent ; Node::create(@node.parent) ; end def empty?(type=:element) case type when String @node.find(type).each { return false } ; return true when :element node = @node.child while ! node.nil? return true if node.node_type == XML::Tree::ELEMENT_NODE node = node.next end false when :child @node.child? end end def each(type=:element) case type when String @node.find(type).each { |node| if node.node_type == XML::Tree::ELEMENT_NODE yield Node::create(node) end } when :element node = @node.child while ! node.nil? if node.node_type == XML::Tree::ELEMENT_NODE yield Node::create(node) end node = node.next end when :child node = @node.child while ! node.nil? yield Node::create(node) node = node.next end end end end end #-- END: libxml specific ---------------------------------------------- when :rexml #-- BEGIN: REXML specific --------------------------------------------- require 'rexml/document' module MyXML class Document def initialize(doc) ; @doc=REXML::Document::new(doc); end def root ; Node::create(@doc.root) ; end end class Node class Element < Node def name ; @node.name ; end def [](attr) ; @node.attributes[attr] ; end end def self.create(node) klass = case node when REXML::Element then Element when REXML::Text then Text when REXML::Comment then Comment else Node end klass::new(node) end def initialize(node) ; @node = node ; end def value ; @node.value ; end def text ; @node.text ; end def parent ; Node::create(@node.parent) ; end def empty?(type=:element) case type when String @node.elements.each(type) { return false } ; return true when :element ! @node.elements.empty? when :child ! @node.empty? end end def each(type=:element) case type when String @node.elements.each(type) { |node| yield Node::create(node) } when :element @node.elements.each { |node| yield Node::create(node) } when :child @node.each_child { |node| yield Node::create(node) } end end end end #-- END: REXML specific ----------------------------------------------- else raise "Unsupported XML parser (#{MyXML::Implementation})" end zonecheck-3.0.5/zc/framework.rb000066400000000000000000000213411226210254100164220ustar00rootroot00000000000000# $Id: framework.rb,v 1.56 2010/09/30 12:39:15 bortzmeyer Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.56 $ # DATE : $Date: 2010/09/30 12:39:15 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'cache' require 'cachemanager' require 'msgcat' ## ## Class that should be inherited by every test set ## class Test ## ## Abstract class for: Succeed, Failed, Error ## class Result # --> ABSTRACT <-- class Desc attr_writer :error, :details attr_reader :error, :details attr_reader :check def initialize(check=true) @check = check @error = nil # Error message (ie: Exception) @details = nil end def hash @check ^ @error.hash ^ @msg.details end def eql?(other) (@check == other.instance_eval('@check') && @error == other.instance_eval('@error') && @details == other.instance_eval('@details')) end alias == eql? end attr_reader :testname, :desc, :ns, :ip def initialize(testname, desc, ns=nil, ip=nil) @testname = testname @desc = desc @ns = ns @ip = ip end def eql?(other) self.instance_of?(Result) && other.instance_of?(Result) && self.testname == other.testname && self.ns == other.ns && self.ip == other.ip end alias == eql? def hash testname.hash ^ ns.hash ^ ip.hash end def source if ! @ns.nil? # NS then @ip.nil? ? "#{@ns}" : "#{@ns}/#{ip}" # NS/IP else $mc.get('word:generic') # generic end end end ## ## Test that has Succeed ## class Succeed < Result def ok? ; true ; end end ## ## Test that has Failed ## class Failed < Result def ok? ; false ; end end ## ## Test that was unable to complete due to Error ## class Error < Result def ok? ; false ; end end def initialize(network, config, cm, domain) @network = network @config = config @cm = cm @domain = domain @cache = Cache::new end def dbgmsg(ns=nil, ip=nil) $dbg.msg(DBG::TESTDBG) { func = 'caller_unknown' caller.each { |l| if l =~ /`((?:chk|tst)_.*)'/ #` <-- emacs func = $1 break end } header = if ns.nil? && ip.nil? then func else func + ' [' + [ ns, ip ].collect{|e| e.to_s}.compact.join('/') + ']' end case arg = yield when Array then [ header ] + arg else [ header, arg ] end } end # Test if 'name' is a cname # If 'name' is inside the current domain, the specified 'ip' # will be used (if 'ip' is nil the first nameserver address # is used) # WARN: this is necessary because the query could be in the # domain being delegated # IDEA: a better way would be to use the cachemanager to fake # the nameserver NS, A and AAAA records retrieved by autoconf # unfortunately we have a NOCACHE option in the debug mode def is_cname?(name, ip=nil) if name.subdomain_of?(@domain.name) || name.eql?(@domain.name) ip = @domain.addresses[0] if ip.nil? else ip = nil end res = @cm[ip].cname(name) res.nil? ? nil : res.cname end def is_resolvable?(name, ip=nil, domain=@domain.name) (( (name.subdomain_of?(domain) || name.eql?(domain)) && !@cm[ip].addresses(name).empty?) || ( @cm[ip].rec(@domain.name) && !@cm[ip].addresses(name).empty?) || (!@cm[ip].rec(@domain.name) && !@cm[nil].addresses(name).empty?)) end def bestresolverip(name=@domain.name) if (ips = @domain.get_resolver_ips(name)).nil? then nil else ips[0] end end def prefix_of(arg,size=nil) case arg when Dnsruby::IPv4 if size.nil? raise RuntimeError, 'Not Implemented Yet' else if size > arg.address.size * 8 raise ArgumentError, 'prefix size too big' end bytes, bits_shift = size / 8, 8 - (size % 8) address = arg.address.slice(0, bytes) + ("\0" * (arg.address.size - bytes)) if arg.address.respond_to?("bytes") a = arg.address.bytes.to_a a[bytes] = (a[bytes] >> bits_shift) << bits_shift address = a.map { |e| e.chr }.join else address[bytes] = (arg.address[bytes] >> bits_shift) << bits_shift end Dnsruby::IPv4::new(address.freeze) end when Dnsruby::IPv6 if size.nil? size = 64 end if size > arg.address.size * 8 raise ArgumentError, 'prefix size too big' end bytes, bits_shift = size / 8, 8 - (size % 8) address = arg.address.slice(0, bytes) + ("\0" * (arg.address.size - bytes)) if arg.address.respond_to?("bytes") a = arg.address.bytes.to_a a[bytes] = (a[bytes] >> bits_shift) << bits_shift address = a.map { |e| e.chr }.join else address[bytes] = (arg.address[bytes] >> bits_shift) << bits_shift end Dnsruby::IPv6::new(address.freeze) else raise ArgumentError, "Could not fing the prefix of : #{address}" end end def is_valid_hostname?(name) name.labels.each { |lbl| return false if (lbl.downcase =~ /^-|-$/) # to_s would have put a '\' before '.' # have at least one character and is just composed of letters and '.' and '-' return false unless (lbl.downcase =~ /^[A-Za-z0-9\-]*$/) return false if (lbl.downcase =~ /^\./) # begin with a dot } true end def is_valid_mbox_address?(name) return false unless name.labels.size > 1 mbox = name[0].string # to_s would have put a '\' before '.' is_valid_hostname?(Dnsruby::Name::new(name.labels[1..-1])) && (mbox !~ /[^A-Za-z0-9\._\-~\#]/) && (mbox !~ /^\.|\.$/) end #-- Shortcuts ----------------------------------------------- def const(name) @config.constants.fetch(name) end def rec(ip=nil, dom=@domain.name, force=false) @cm[ip].rec(dom, force) end def soa(ip=nil, dom=@domain.name, force=false) @cm[ip].soa(dom, force) end def ns(ip=nil, dom=@domain.name, force=false) @cm[ip].ns(dom, force) end def mx(ip=nil, dom=@domain.name, force=false) @cm[ip].mx(dom, force) end def any(ip=nil, resource=nil) @cm[ip].any(@domain.name, resource) end def addresses(name, ip=nil) @cm[ip].addresses(name) end def a(ip, name, force=false) @cm[ip].a(name, force) end def aaaa(ip, name, force=false) @cm[ip].aaaa(name, force) end def cname(ip, name, force=false) @cm[ip].cname(name, force) end def ptr(ip, name) @cm[ip].ptr(name) end def dnskey(ip, name=@domain.name, force=false) @cm[ip].dnskey(name, force) end def rrsig(ip, resource, name=@domain.name, force=false) @cm[ip].rrsig(name, resource, force) end def is_dnssec_mandatory?() return @domain.is_dnssec_mandatory end def given_ds() return @domain.ds end def given_dnskey() return @domain.dnskey end def edns() return @cm.edns end end ## ## Hold tests that are generic ## module CheckGeneric def self.family ; 'generic' ; end end ## ## Hold tests that are directed to an NS entry ## => take an NS name as argument ## module CheckNameServer def self.family ; 'nameserver' ; end end ## ## Hold tests that are directed to a DNS running on an IP address ## => take an NS name and an IP address as argument ## module CheckNetworkAddress def self.family ; 'address' ; end end ## ## Hold tests that are related to DNSSEC ## module CheckDNSSEC def self.family ; 'dnssec' ; end end ## ## Hold tests that are not directed DNS related ## module CheckExtra def self.family ; 'extra' ; end end end zonecheck-3.0.5/zc/input/000077500000000000000000000000001226210254100152365ustar00rootroot00000000000000zonecheck-3.0.5/zc/input/cgi.rb000066400000000000000000000222711226210254100163310ustar00rootroot00000000000000# $Id: cgi.rb,v 1.65 2011/03/14 13:38:25 kmkaplan Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.65 $ # DATE : $Date: 2011/03/14 13:38:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'cgi' require 'param' ## ## Processing parameters from CGI (Common Gateway Interface) ## ## WARN: don't forget to update locale/cgi.* ## ## ---------------------------------------------------------------------- ## ## For obvious security reasons the following parameters shouldn't ## be set through the CGI: ## - configfile ## - testdir ## - debug ## - resolver ## ## parameters: ## - lang = [ fr | en | ... ] ## - quiet ## - one ## - option ## - verbose = [ i|intro, n|testname, x|explain, d|details, ## t|testdesc, c|counter, o|reportok ] ## - intro ## - testname ## - explain ## - details ## - progress = [ t|testdesc | c|counter ] ## - reportok ## - fatalonly ## - output = [ bs|byseverity, bh|byhost, text, html ] ## - report = bs|byseverity | bh|byhost ## - format = h|html | t|text ## - error = [ af|allfatal, aw|allwarning, ds|dfltseverity, ## s|stop, ns|nostop ] ## - errorlvl = [ af|allfatal | aw|allwarning | ds|dfltseverity ] ## - dontstop ## - transp = [ ipv4, ipv6, udp, tcp, std ] ## - transp3 = [ ipv4, ipv6 ] ## - transp4 = [ udp | tcp | std ] ## - profile = profilename ## - category = cat1,!cat2:subcat1,cat2,!cat3,+ ## - chkmail (!mail) ## - chkrir (!rir) ## - chkzone (!dns:axfr) ## - ds-rdata = DS rdata ( ) ## - ns = ns1=ip1,ip2;ns2=ip3;ns3 ## - ns0 .. nsX = nameserver name ## - ips0 .. ipsX = coma separated ip addresses ## - zone = zone to test ## ## exemple: ## zone=afnic.fr&intro&progress=testdesc&transp=ipv4,ipv6,std ## zone=afnic.fr&verbose=i,t&ns=ns1.nic.fr%3bns2.nic.fr%3bns3.nic.fr ## zone=afnic.fr&verbose=i,t&ns=ns1.nic.fr=192.93.0.1&ns=ns2.nic.fr&ns=bns3.nic.fr ## module Input class CGI with_msgcat "cgi.%s" MaxNS = 20 # Maximum number of NS taken into account def allow_preset ; false ; end def initialize @cgi = ::CGI::new end def restart @cgi = ::CGI::new end def parse(p) # Direct script invocation is not authorized return false if @cgi.params.empty? # Parse zone data and options parse_zonedata(p) && parse_options(p) end def redirect(url, errcode, data=nil, io=$console.stdout) io.puts @cgi.header({ 'status' => 'REDIRECT', 'location' => url, 'type' => 'text/plain', 'charset' => $console.encoding }) io.puts data if data exit errcode unless errcode.nil? end def interact(p, c, tm, io=$console.stdout) # XXX: not good place p.rflag.autoconf p.publisher.autoconf(p.rflag, p.option) puts @cgi.header({ 'type' => p.publisher.engine.class::Mime, 'charset' => $console.encoding }) true end def usage(errcode, io=$console.stdout) io.puts @cgi.header({ 'type' => 'text/plain', 'charset' => $console.encoding }) io.puts $mc.get('input:cgi:usage') exit errcode unless errcode.nil? end def error(str, errcode=nil, io=$console.stdout) l10n_error = $mc.get('word:error').upcase io.puts @cgi.header({ 'type' => 'text/plain', 'charset' => $console.encoding }) io.puts "#{l10n_error}: #{str}" exit errcode unless errcode.nil? end #-- PRIVATE ------------------------------------------------- private def parse_options(p) # Lang # => The message catalogue need to be replaced if @cgi.has_key?('lang') $locale.lang = @cgi['lang'] end # Quiet, One p.rflag.quiet = true if @cgi.has_key?('quiet') p.rflag.one = true if @cgi.has_key?('one') # Verbose if @cgi.has_key?('verbose') p.verbose = @cgi.params['verbose'].join(',') else p.verbose = 'testname' if @cgi.has_key?('testname') p.verbose = 'intro' if @cgi.has_key?('intro') p.verbose = 'explain' if @cgi.has_key?('explain') p.verbose = 'details' if @cgi.has_key?('details') p.verbose = 'reportok' if @cgi.has_key?('reportok') p.verbose = 'fatalonly' if @cgi.has_key?('fatalonly') p.verbose = @cgi['progress'] if @cgi.has_key?('progress') end # Output if @cgi.has_key?('output') p.output = @cgi.params['output'].join(',') else p.output = if @cgi.has_key?('format') then @cgi['format'] else 'html' end p.output = if @cgi.has_key?('report') then @cgi['report'] else 'byseverity' end end # Error if @cgi.has_key?('error') p.error = @cgi.params['error'].join(',') else errorlvl = if @cgi.has_key?('errorlvl') then @cgi.params['errorlvl'].delete_if { |e| e =~ /^\s*$/ } else [] end errorstop = @cgi.has_key?('dontstop') ? 'nostop' : 'stop' p.error = (errorlvl + [ errorstop ]).join(',') end # Transp if @cgi.has_key?('transp') p.transp = @cgi.params['transp'].join(',') else p.transp = ((@cgi.params['transp3'] || []) + (@cgi.params['transp4'] || [])).join(',') end # Profile if @cgi.has_key?('profile') p.preconf.profile = @cgi['profile'] end # Category if @cgi.has_key?('category') p.test.categories = @cgi.params['category'].join(',') else cat = [ ] cat << '!mail' unless @cgi.has_key?('chkmail') cat << '!rir' unless @cgi.has_key?('chkrir') cat << '!dns:axfr' unless @cgi.has_key?('chkzone') if ! cat.empty? cat << '+' p.test.categories = cat.join(',') end end # Option if @cgi.has_key?('option') p.option << @cgi.params['option'].join(',') end # DNSSEC sd = [""] if @cgi.has_key?('ds-rdata') @cgi.params['ds-rdata'].each {|ds| if ds.include?(',') raise ParamError, "Invalid DS-RDATA" end sd << "DS-RDATA:" + ds unless ds.empty? unless ds.empty? } end if @cgi.has_key?('ds') && !@cgi.params['ds'].join("").empty? if @cgi.has_key?('ha') @cgi.params['ds'] = @cgi.params['ds'].join("").upcase unless @cgi.params['ds'].gsub(/[^A-F0-9]/,"").nil? @cgi.params['ds'] = @cgi.params['ds'].gsub(/[^A-F0-9]/,"") end sd << "DS:" + @cgi.params['ds'] + ":" + @cgi.params['ha'].join("") end end if @cgi.has_key?('dnskey') && !@cgi.params['dnskey'].join("").empty? @cgi.params['dnskey'] = @cgi.params['dnskey'].join("") unless @cgi.params['dnskey'].gsub(/[^A-Za-z0-9\/+=]/,"").nil? @cgi.params['dnskey'] = @cgi.params['dnskey'].gsub(/[^A-Za-z0-9\/+=]/,"") end sd << "DNSKEY:" + @cgi.params['dnskey'] end if sd != [""] sd = sd.delete_if {|e| e == ""} p.securedelegation= sd.join(",") elsif @cgi.has_key?('sd') p.securedelegation= "" end # Ok true end def parse_zonedata(p) # NS and IPs if @cgi.has_key?('ns') p.domain.ns = @cgi.params['ns'].join(';') else ns_list = [ ] (0..MaxNS-1).each { |i| next unless cgi_ns = @cgi.params["ns#{i}"] next unless !cgi_ns.empty? next unless ns = cgi_ns[0] next unless !ns.empty? cgi_ips = [] @cgi.params["ips#{i}"].each {|e| cgi_ips << e if e != nil && !e.empty? } cgi_ips = (cgi_ips.empty? ? nil : cgi_ips) || '' if cgi_ips.nil? || cgi_ips.length == 0 || cgi_ips == '' || cgi_ips.empty? ns_list << [ ns ] else ips = cgi_ips.collect { |a| a.split(/\s*,\s*|\s+/) }.flatten.compact ns_list << [ ns, ips ] end } if ! ns_list.empty? p.domain.ns = ns_list.collect { |ns, ips| ips ? "#{ns}=#{ips.join(',')}" : ns }.join(';') end end # Zone/Domain zone = @cgi['zone'] zone.strip! if zone if zone.nil? || zone.empty? # If we got a referer send him back to this page, # otherwise assume it was an attempt of a direct # script invocation (and send a usage page) if ENV.has_key?('HTTP_REFERER') then redirect(ENV['HTTP_REFERER'], EXIT_USAGE) else return false end end p.domain.name = zone # Ok true end end end zonecheck-3.0.5/zc/input/cli.rb000066400000000000000000000225341226210254100163400ustar00rootroot00000000000000# $Id: cli.rb,v 1.43 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.43 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'getoptlong' require 'param' ## ## Processing parameters from CLI (Command Line Interface) ## ## WARN: don't forget to update locale/cli.* ## ## ---------------------------------------------------------------------- ## ## usage: PROGNAME: [-hqV] [-voet opt] [-46] [-n ns...] [-c conf] domainname ## --lang Select another language (en, fr, ...) ## -d, --debug Select debugging messages to print ## -h, --help Show this message ## -V, --version Display version and exit ## -B, --batch Depreciated option ## -c, --config Specify location of the configuration file ## --testdir Location of the directory holding tests ## -P, --profile Force uses of a particular profile ## -C, --category Only perform test for the specified category ## -T, --test Name of the test to perform ## --testlist List all the available tests ## --testdesc Give a description of the test ## (values: name, failure, success, explanation) ## -r, --resolver Resolver to use for guessing 'ns' information ## -n, --ns List of nameservers for the domain ## (ex: ns1;ns2=ip1,ip2;ns3=ip3) ## -q, --quiet Don't display extra titles ## -1, --one Only display the most relevant message ## -g, --tagonly Display only tag (suitable for scripting) ## -v, --verbose Display extra information (see verbose) ## -o, --output Output (see output) ## -e, --error Behaviour in case of error (see error) ## -t, --transp Transport/routing layer (see transp) ## -4, --ipv4 Only check the zone with IPv4 connectivity ## -6, --ipv6 Only check the zone with IPv6 connectivity ## --preset Use a preset configuration ## --option Set extra options (-,-opt,opt,opt=foo) ## ## verbose: [intro/testname/explain/details] ## [reportok|fatalonly] [testdesc|counter] ## can be prefix by '-' or '!' to remove the effect ## intro [i] Print summary for domain and associated nameservers ## testname [n] Print the test name ## explain [x] Print an explanation for failed tests ## details [d] Print a detailed description of the failure ## reportok [o] Still report passed test ## fatalonly [f] Print fatal errors only ## testdesc [t] Print the test description before running it ## counter [c] Print a test counter ## ## output: [byseverity|byhost] [text|html] ## byseverity *[bs] Output is sorted/merged by severity ## byhost [bh] Output is sorted/merged by host ## text *[t] Output plain text ## html [h] Output HTML ## ## error: [allfatal|allwarning|dfltseverity] [stop|nostop] ## allfatal [af] All error are considered fatal ## allwarning [aw] All error are considered warning ## dfltseverity *[ds] Use the severity associated with the test ## stop *[s] Stop on the first fatal error ## nostop [ns] Never stop (even on fatal error) ## ## transp: [ipv4/ipv6] [udp|tcp|std] ## ipv4 *[4] Use IPv4 routing protocol ## ipv6 *[6] Use IPv6 routing protocol ## udp [u] Use UDP transport layer ## tcp [t] Use TCP transport layer ## std *[s] Use UDP with fallback to TCP for truncated messages ## module Input class CLI with_msgcat "cli.%s" def allow_preset ; true ; end def initialize init end def restart init end def parse(p) begin opts_analyse(p) args_analyse(p) unless p.test.list || p.test.desctype rescue GetoptLong::Error return false end true end def interact(p, c, tm, io=$console.stdout) true end def usage(errcode, io=$console.stderr) io.print $mc.get('input:cli:usage').gsub('PROGNAME', PROGNAME) exit errcode unless errcode.nil? end def error(str, errcode=nil, io=$console.stderr) l10n_error = $mc.get('word:error').upcase io.puts "#{l10n_error}: #{str}" exit errcode unless errcode.nil? end #-- PRIVATE ------------------------------------------------- private def init @opts = GetoptLong.new(* opts_definition) @opts.quiet = true end def opts_definition [ [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--version', '-V', GetoptLong::NO_ARGUMENT ], [ '--quiet', '-q', GetoptLong::NO_ARGUMENT ], [ '--lang', GetoptLong::REQUIRED_ARGUMENT ], [ '--debug', '-d', GetoptLong::REQUIRED_ARGUMENT ], [ '--batch', '-B', GetoptLong::OPTIONAL_ARGUMENT ], [ '--config', '-c', GetoptLong::REQUIRED_ARGUMENT ], [ '--testdir', GetoptLong::REQUIRED_ARGUMENT ], [ '--category', '-C', GetoptLong::REQUIRED_ARGUMENT ], [ '--profile', '-P', GetoptLong::REQUIRED_ARGUMENT ], [ '--test', '-T', GetoptLong::REQUIRED_ARGUMENT ], [ '--testlist', GetoptLong::NO_ARGUMENT ], [ '--testdesc', GetoptLong::REQUIRED_ARGUMENT ], [ '--resolver', '-r', GetoptLong::REQUIRED_ARGUMENT ], [ '--ns', '-n', GetoptLong::REQUIRED_ARGUMENT ], [ '--ipv4', '-4', GetoptLong::NO_ARGUMENT ], [ '--ipv6', '-6', GetoptLong::NO_ARGUMENT ], [ '--one', '-1', GetoptLong::NO_ARGUMENT ], [ '--tagonly', '-g', GetoptLong::NO_ARGUMENT ], [ '--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT ], [ '--output', '-o', GetoptLong::REQUIRED_ARGUMENT ], [ '--error', '-e', GetoptLong::REQUIRED_ARGUMENT ], [ '--transp', '-t', GetoptLong::REQUIRED_ARGUMENT ], [ '--preset', GetoptLong::REQUIRED_ARGUMENT ], [ '--option', GetoptLong::REQUIRED_ARGUMENT ], [ '--edns', GetoptLong::REQUIRED_ARGUMENT ], [ '--securedelegation', '-s', GetoptLong::OPTIONAL_ARGUMENT ], # # Let's have some fun [ '--makecoffee', GetoptLong::NO_ARGUMENT ], [ '--coffee', GetoptLong::NO_ARGUMENT ] ] end def opts_analyse(p) @opts.each do |opt, arg| case opt when '--help' then usage(EXIT_USAGE, $console.stdout) when '--version' l10n_version = $mc.get('input:version') % $zc_version l10n_version.gsub!(/PROGNAME/, PROGNAME) $console.stdout.puts l10n_version exit EXIT_OK when '--quiet' then p.rflag.quiet = true when '--debug' then $dbg.level = arg when '--lang' then $locale.lang = arg when '--config' then p.preconf.cfgfile = arg.dup.untaint when '--testdir' then p.preconf.testdir = arg.dup.untaint when '--profile' then p.preconf.profile = arg when '--category' then p.test.categories = arg when '--test' then p.test.tests = arg when '--testlist' then p.test.list = true when '--testdesc' then p.test.desctype = arg when '--resolver' then p.resolver.local = arg when '--ns' then p.domain.ns = arg when '--ipv6' then p.network.ipv6 = true when '--ipv4' then p.network.ipv4 = true when '--one' then p.rflag.one = true when '--tagonly' then p.rflag.tagonly = true when '--error' then p.error = arg when '--transp' then p.transp = arg when '--verbose' then p.verbose = arg when '--output' then p.output = arg when '--preset' then p.preconf.preset = arg when '--option' then p.option << arg when '--edns' then p.edns = arg when '--securedelegation' then p.securedelegation = arg when '--batch' $console.stdout.puts $mc.get('input:cli:deprecated_option') % "batch" exit EXIT_OK # # Let's have some fun when '--makecoffee' $console.stdout.print < # # CREATED : 2003/08/27 12:02:17 # REVISION : $Revision: 1.15 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'getoptlong' require 'param' ## ## Processing parameters from INETD ## ## WARN: don't forget to update locale/inetd.* ## ## ---------------------------------------------------------------------- ## ## ## usage: PROGNAME: [-hV] [-46] [-c conf] ## --lang Select another language (en, fr, ...) ## -h, --help Show this message ## -V, --version Display version and exit ## -c, --config Specify location of the configuration file ## --testdir Location of the directory holding tests ## -r, --resolver Resolver to use for guessing 'ns' information ## -4, --ipv4 Only allow to check the zone with IPv4 connectivity ## -6, --ipv6 Only allow to check the zone with IPv6 connectivity ## ## ## Command Args ## ?|help 0 This message ## q|quit|exit 0 Leave ZoneCheck ## check 0 Launch the zone checking process ## zone|domain 1 Zone to test ## nslist 0+ Set the list of the zone nameservers ## set 1-2 Option to set (see options) ## unset 1 Option to unset (see options) ## preset 1 Preset configuration (supported: classic, fatal) ## show 1 Show possibles values (supported: profiles) ## ## Options Args ## lang 1 Select another language (en, fr, ...) ## one 0 Only display the most relevant message ## quiet 0 Don't display extra titles ## tagonly 0 Display only tag (suitable for scripting) ## category 1+ Only perform test for the specified category ## profile 1 Force a profile to use ## verbose 1+ Display extra information (see verbose) ## output 1+ Output (see output) ## error 1+ Behaviour in case of error (see error) ## transp 1+ Transport/routing layer (see transp) ## option 1+ Set extra options (-,-opt,opt,opt=foo) ## ## Arguments for Options ## verbose: [intro/testname/explain/details] ## [reportok|fatalonly] [testdesc|counter] ## intro [i] Print summary for domain and associated nameservers ## testname [n] Print the test name ## explain [x] Print an explanation for failed tests ## details [d] Print a detailed description of the failure ## reportok [o] Still report passed test ## fatalonly [f] Print fatal errors only ## testdesc [t] Print the test description before running it ## counter [c] Print a test counter ## ## output: [byseverity|byhost] [text|html] ## byseverity *[bs] Output is sorted/merged by severity ## byhost [bh] Output is sorted/merged by host ## text *[t] Output plain text ## html [h] Output HTML ## ## error: [allfatal|allwarning|dfltseverity] [stop|nostop] ## allfatal [af] All error are considered fatal ## allwarning [aw] All error are considered warning ## dfltseverity *[ds] Use the severity associated with the test ## stop *[s] Stop on the first fatal error ## nostop [ns] Never stop (even on fatal error) ## ## transp: [ipv4/ipv6] [udp|tcp|std] ## ipv4 *[4] Use IPv4 routing protocol ## ipv6 *[6] Use IPv6 routing protocol ## udp [u] Use UDP transport layer ## tcp [t] Use TCP transport layer ## std *[s] Use UDP with fallback to TCP for truncated messages ## ## Example ## preset classic ## zone foorbar.com ## check ## module Input class INETD with_msgcat "inetd.%s" def allow_preset ; false ; end def initialize @prompt = "zonecheck> " end def restart end def parse(p) begin ipv6, ipv4 = false, false opts = GetoptLong::new( [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--version', '-V', GetoptLong::NO_ARGUMENT ], [ '--lang', GetoptLong::REQUIRED_ARGUMENT ], [ '--debug', '-d', GetoptLong::REQUIRED_ARGUMENT ], [ '--config', '-c', GetoptLong::REQUIRED_ARGUMENT ], [ '--testdir', GetoptLong::REQUIRED_ARGUMENT ], [ '--resolver', '-r', GetoptLong::REQUIRED_ARGUMENT ], [ '--ipv4', '-4', GetoptLong::NO_ARGUMENT ], [ '--ipv6', '-6', GetoptLong::NO_ARGUMENT ] ) opts.each { |opt, arg| case opt when '--help' then usage(EXIT_USAGE, $console.stdout) when '--version' l10n_version = $mc.get('input:version') % $zc_version l10n_version.gsub!(/PROGNAME/, PROGNAME) $console.stdout.puts l10n_version exit EXIT_OK when '--quiet' then p.rflag.quiet = true when '--debug' then $dbg.level = arg when '--lang' then $locale.lang = arg when '--config' then p.preconf.cfgfile = arg.untaint when '--testdir' then p.preconf.testdir = arg.untaint when '--resolver' then p.resolver.local = arg when '--ipv6' then ipv6 = true when '--ipv4' then ipv4 = true end } rescue GetoptLong::Error return false end ipv6 = ipv4 = true if !ipv6 && !ipv4 $ipv4_stack &&= ipv4 $ipv6_stack &&= ipv6 true end def interact(p, c, tm, io=$console.stdout) io.puts $mc.get('input:inetd:welcome').gsub('VERSION', ZC_VERSION) io.print @prompt io.flush while true do # Check if ^D otherwise read a full line char = $stdin.getc break if char.nil? || char == 4 $stdin.ungetc(char) line = $stdin.gets break if line.nil? line.strip! begin case line when '' # Set when /^preset\s+(\w+)$/ case $1 when 'classic' p.verbose = 'i,x,d,c' io.puts '+ set verbose i,x,d,c' when 'fatal' p.verbose = 'x,d,f' p.rflag.quiet = true io.puts '+ set verbose x,d,f' io.puts '+ set quiet' else error($mc.get('input:inetd:unknown_preset') % $1) end when /^set\s+(\w+)\s+(.*?)\s*$/ case $1 when 'verbose' then p.verbose = $2 when 'output' then p.output = $2 when 'error' then p.error = $2 when 'transp' then p.transp = $2 when 'option' then p.option = $2 when 'category' then p.category = $2 when 'quiet' then p.rflag.quiet = true when 'one' then p.rflag.one = true when 'tagonly' then p.rflag.tagonly = true when 'lang' then $locale.lang = $2 when 'profile' then p.preconf.profile = c.profilename = $2 end when /^nslist\s+(.*)/ then p.domain.ns = $1 when /^(?:zone|domain)\s+(.*)/ then p.domain.name = $1 # Unset when /^unset\s+(\w+)$/ case $1 when 'quiet' then p.rflag.quiet = false when 'one' then p.rflag.one = false when 'profile' then p.preconf.profile = c.profilename = nil end # Show when /show\s+(\w+)$/ case $1 when 'profiles' c.profiles.each { |profile| io.puts profile.name } end # when '?', 'help' io.puts $mc.get('input:inetd:help') # Leave interaction loop when 'check' then return true when 'quit', 'q', 'exit' then return false # What did he said?! else error($mc.get('input:inetd:what')) end rescue Param::ParamError, Config::ConfigError => e error(e.to_s) end io.print @prompt io.flush end io.puts # Skip a line return false end def usage(errcode, io=$console.stdout) io.puts $mc.get('input:inetd:usage').gsub('PROGNAME', PROGNAME) io.flush exit errcode unless errcode.nil? end def error(str, errcode=nil, io=$console.stdout) l10n_error = $mc.get('word:error').upcase io.puts "#{l10n_error}: #{str}" io.flush exit errcode unless errcode.nil? end end end zonecheck-3.0.5/zc/instructions.rb000066400000000000000000000076211226210254100171760ustar00rootroot00000000000000# $Id: instructions.rb,v 1.15 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/07/19 07:28:13 # REVISION : $Revision: 1.15 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'dbg' ## ## ## module Instruction class InstructionError < StandardError end class PreevalError < InstructionError end ## ## Abstract Node class ## class Node end ## ## Instruction block ## class Block < Node def initialize(instr=[]) @instr = instr end attr_reader :instr def [](idx) ; @instr[idx] ; end def size ; @instr.size ; end def <<(instr) ; @instr << instr ; end def validate(testmanager) @instr.each { |i| i.validate(testmanager) } end def preeval(testmanager, args) count = 0 @instr.each { |i| count += i.preeval(testmanager, args) } count end def eval(testmanager, args) @instr.each { |i| i.eval(testmanager, args) } end end ## ## Check ## class Check < Node def initialize(checkname, severity, category, block=nil) @checkname = checkname @severity = severity @category = category @block = block end attr_reader :checkname, :severity, :category, :block def validate(testmanager) unless testmanager.has_check?(@checkname) raise StandardError, $mc.get('config:check_unknown') % [ @checkname ] end end def preeval(testmanager, args) testmanager.wanted_check?(@checkname, category) ? @block.preeval(testmanager, args) + 1 : 0; end def eval(testmanager, args) if testmanager.wanted_check?(@checkname, category) result = testmanager.check1(@checkname, severity, *args) if result == Test::Succeed unless @block.nil? @block.eval(testmanager,args) end end end end end ## ## Case switch ## class Switch < Node def initialize(testname, when_stmt, else_stmt) @testname = testname @when = when_stmt @else = else_stmt end attr_reader :testname, :when, :else def validate(testmanager) unless testmanager.has_test?(@testname) raise StandardError, $mc.get('config:check_unknown') % [ @testname ] end @when.each_value { |b| b.validate(testmanager) } @else.validate(testmanager) if @else end def preeval(testmanager, args) choice = testmanager.test1(@testname, false, *args) raise PreevalError if choice.kind_of?(Exception) $dbg.msg(DBG::TESTS) { "preeval: #{@testname} = #{choice}" } block = @when[choice] || @else block.nil? ? 0 : block.preeval(testmanager, args) end def eval(testmanager, args) choice = testmanager.test1(@testname, true, *args) $dbg.msg(DBG::TESTS) {"switching to: #{@testname} = #{choice}"} block = @when[choice] || @else if block $dbg.msg(DBG::TESTS) { "leaving switch: #{@testname}" } block.eval(testmanager, args) else $dbg.msg(DBG::TESTS) { "switch no choice: #{@testname} = #{choice}" } end end end end zonecheck-3.0.5/zc/locale.rb000066400000000000000000000064211226210254100156660ustar00rootroot00000000000000# $Id: locale.rb,v 1.5 2010/06/29 12:08:35 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2003/08/29 14:10:22 # REVISION : $Revision: 1.5 $ # DATE : $Date: 2010/06/29 12:08:35 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck class Locale LANGRegex = /^(\w+?)(?:_(\w+))?(?:\.([\w\-]+))?$/ # # Normalize lang # (and raise exception is the parameter is suspicious) # The settings are based on: LanguageCode_CountryCode.Encoding # def self.normlang(lng) unless md = LANGRegex.match(lng) raise ArgumentError, "Suspicious language selection: #{lng}" end lang = md[1].downcase lang += '_' + md[2].upcase if md[2] lang += '.' + md[3].downcase if md[3] lang.untaint end # # Split lang between Language, Country, Encoding # def self.splitlang(lng) unless md = LANGRegex.match(lng) raise ArgumentError, "Suspicious language selection: #{lng}" end [ md[1], md[2], md[3] ] end # # Initializer # def initialize @actions = {} @lang = nil @language = nil @country = nil @encoding = nil if ENV['LANG'] lng = ENV['LANG'] ln, ct, en = ZoneCheck::Locale::splitlang(ZoneCheck::Locale::normlang(lng)) evlist = [] evlist << 'lang' if (@language != ln) || (@country != ct) evlist << 'encoding' if (@encoding != en) @lang, @language, @country, @encoding = lng, ln, ct, en $dbg.msg(DBG::LOCALE) { "locale set to #{lng}" } notify(*evlist) end end attr_reader :lang, :language, :country, :encoding def lang=(lng) ln, ct, en = ZoneCheck::Locale::splitlang(ZoneCheck::Locale::normlang(lng)) if($supported_languages.include?(ln.downcase)) evlist = [] evlist << 'lang' if (@language != ln) || (@country != ct) evlist << 'encoding' if (@encoding != en) @lang, @language, @country, @encoding = lng, ln, ct, en $dbg.msg(DBG::LOCALE) { "locale set to #{lng}" } notify(*evlist) else $dbg.msg(DBG::LOCALE) { "The given language (#{lng}) is not supported by ZoneCheck. " + "Here is a list of supported languages: " + $supported_languages.join(", ") } end end def watch(event, action) (@actions[event] ||= []) << action end def notify(*event) event.each { |ev| @actions[ev].each { |a| a.call } if @actions.has_key?(ev) } end end endzonecheck-3.0.5/zc/mail.rb000066400000000000000000000145611226210254100153550ustar00rootroot00000000000000# $Id: mail.rb,v 1.29 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/09/25 08:58:17 # REVISION : $Revision: 1.29 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'socket' require 'timeout' ## ## ## class Mail ## ## ## class MailError < StandardError end def initialize(mhost, mip, dbgio=nil) @myhostname = Socket::gethostname @mhost = mhost @mip = mip @mrelay = nil @dbgio = dbgio end def open(tout=nil) Timeout::timeout(tout) { @mrelay = TCPSocket::new(@mip, 25) } end def fake_info(user, mdest, mfrom) @user = user @mdest = mdest @mfrom = mfrom @openrelay_testlist = [ [ "Test 0", "spamtest@#{@mhost}", "\"nobody@#{@mdest}\"" ], [ "Test 1", "spamtest@#{@mdest}", "nobody@#{@mdest}" ], [ "Test 2", "spamtest@#{@mfrom}", "nobody@#{@mdest}" ], [ "Test 3", "spamtest@localhost", "nobody@#{@mdest}" ], [ "Test 4", "spamtest", "nobody@#{@mdest}" ], [ "Test 5", "", "nobody@#{@mdest}" ], [ "Test 6", "spamtest@#{@mhost}", "nobody@#{@mdest}" ], [ "Test 7", "spamtest@[#{@mip}]", "nobody@#{@mdest}" ], [ "Test 8", "spamtest@#{@mhost}", "nobody%#{@mdest}@#{@mhost}" ], [ "Test 9", "spamtest@#{@mhost}", "nobody%#{@mdest}@[#{@mip}]" ], [ "Test 10", "spamtest@#{@mhost}", "\"nobody@#{@mdest}\"" ], [ "Test 11", "spamtest@#{@mhost}", "\"nobody%#{@mdest}\"" ], [ "Test 12", "spamtest@[#{@mip}]", "\"nobody@#{@mdest}@#{@mhost}\""], [ "Test 13", "spamtest@#{@mhost}", "\"nobody@#{@mdest}\"@[#{@mip}]"], [ "Test 14", "spamtest@#{@mhost}", "nobody@#{@mdest}@[#{@mip}]" ], [ "Test 15", "spamtest@[#{@mip}]", "@#{@mhost}:nobody@#{@mdest}" ], [ "Test 16", "spamtest@#{@mhost}", "@[#{@mip}]:nobody@#{@mdest}" ], [ "Test 17", "spamtest@[#{@mip}]", "#{@mdest}!nobody" ], [ "Test 18", "spamtest@#{@mhost}", "#{@mdest}!nobody@[#{@mip}]" ], [ "test 19", "postmaster@#{@mhost}", "nobody@#{@mdest}" ] ] end def close @mrelay.close end def cmd(str) if str @dbgio << ">> #{str}\n" if @dbgio @mrelay.write("#{str}\r\n") ; @mrelay.flush end begin desc = "" while true # Bug Fix by Romuald # Timeout added to SMTP requests if server is not responding line = nil Timeout.timeout(10, Timeout::Error) { line = @mrelay.readline } @dbgio << "<< #{line}" if @dbgio case line when NilClass then raise ZoneCheck::Mail::MailError, "parsing error" when /^(\d{3}) (.*)$/ then return [ $1.to_i, desc << $2 ] when /^(\d{3})-(.*)$/ then desc << $2 else raise ZoneCheck::Mail::MailError, "parsing error" end end rescue EOFError raise ZoneCheck::Mail::MailError, "Unexpected closing of connection" rescue Timeout::Error raise ZoneCheck::Mail::MailError, "Timeout from SMTP server" end # NOT REACHED end def banner ; cmd(nil) ; end def helo(host) ; cmd("HELO #{host.gsub(/\.$/, "")}") ; end def vrfy(user) ; cmd("VRFY #{user.gsub(/\.$/, "")}") ; end def mail_from(from) ; cmd("MAIL FROM:<#{from.gsub(/\.$/, "")}>") ; end def rcpt_to(to) ; cmd("RCPT TO:<#{to.gsub(/\.$/, "")}>") ; end def rset ; cmd("RSET") ; end def quit ; cmd("QUIT") ; end def test_userexists(user, use_vrfy=false) if use_vrfy case vrfy(user)[0] when 250, 251, 252 then rset ; return true end end mail_from("#{@user}@#{@mdest}") res = rcpt_to(user)[0] == 250 rset res end def test_openrelay(count=1) tests = [ @openrelay_testlist[1] ] tests.each { |name, from, to| if (r = mail_from(from)[0]) == 250 case rcpt_to(to)[0] when 250..259 then return true end else raise ZoneCheck::Mail::MailError, "Unexpected return code #{r}" end rset } false end end # 500 Syntax error, command unrecognized # [This may include errors such as command line too long] # 501 Syntax error in parameters or arguments # 502 Command not implemented # 503 Bad sequence of commands # 504 Command parameter not implemented # # 211 System status, or system help reply # 214 Help message # [Information on how to use the receiver or the meaning of a # particular non-standard command; this reply is useful only # to the human user] # # 220 Service ready # 221 Service closing transmission channel # 421 Service not available, # closing transmission channel # [This may be a reply to any command if the service knows it # must shut down] # # 250 Requested mail action okay, completed # 251 User not local; will forward to # 450 Requested mail action not taken: mailbox unavailable # [E.g., mailbox busy] # 550 Requested action not taken: mailbox unavailable # [E.g., mailbox not found, no access] # 451 Requested action aborted: error in processing # 551 User not local; please try # 452 Requested action not taken: insufficient system storage # 552 Requested mail action aborted: exceeded storage allocation # 553 Requested action not taken: mailbox name not allowed # [E.g., mailbox syntax incorrect] # 354 Start mail input; end with . # 554 Transaction failed endzonecheck-3.0.5/zc/msgcat.rb000066400000000000000000000157151226210254100157130ustar00rootroot00000000000000# $Id: msgcat.rb,v 1.46 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.46 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'ext/myxml' require 'dbg' ## ## Message catalog for I18N/L10N ## ## ## WARN: this file is not localized ## ## BUGFIX: ## - method readfile: inode is always 0 on Windows ## we replace the inode number by the filename if the inode is 0 ## # BUG: @lang / @language / @country? class MsgCat TAG = 'tag' CHECK = 'check' TEST = 'test' NAME = 'name' FAILURE = 'failure' SUCCESS = 'success' EXPLANATION = 'explanation' DETAILS = 'details' ## ## Exception: the corresponding message catalog is not installed ## class NoCatalogFound < StandardError end ## ## Exception: Syntax error, while parsing the file ## class SyntaxError < StandardError end ## ## Exception: no message for the 'tag' ## class EntryNotFound < StandardError end # # Initializer # def initialize(directory, dfltlang) $dbg.msg(DBG::LOCALE) { 'creating message catalogue' } $dbg.msg(DBG::LOCALE) {"fallback for language is set to '#{dfltlang}'"} @dfltlang = dfltlang @directory = directory @loaded = {} @catfiles = [] @language = nil @country = nil clear end attr_writer :language, :country def clear @tag = {} @check = {} @test = {} @shortcut = { EXPLANATION => {}, DETAILS => {} } end # # Test if a file catalog is available # def available?(where) filepath(where).each { |fp| return true if File::readable?(fp) } false end # # Read catalog (from the template filename) # (the occurence of %s is replaced by the language name) # def read(where) filepath(where).each { |fp| if File::readable?(fp) res = readfile(fp) @catfiles << where unless res.nil? return res end } raise NoCatalogFound, "No valid catalog found for #{@lang}" end # # Get message associated with the 'tag' # def get(tag, type=TAG, subtype=nil) $dbg.msg(DBG::LOCALE) { category = type != TAG ? " (#{type}/#{subtype})" : '' "requesting locale for: #{tag}#{category}" } sameas = nil begin case type when TAG @tag.fetch(tag) when CHECK res = @check.fetch(tag)[subtype] if res && (sameas = res['sameas']) res = case sameas when /^shortcut:(.*)$/ @shortcut.fetch(subtype).fetch($1) else @check.fetch(sameas).fetch(subtype) end end res when TEST @test.fetch(tag)[subtype] end rescue IndexError category = type != TAG ? " (#{type}/#{subtype})" : '' xcp = if sameas.nil? "Entity '#{tag}'#{category} has not been defined/localized" else "Entity '#{tag}'#{category} doesn't have a link to '#{sameas}'" end raise EntryNotFound, xcp end end # # Reload the message catalogs # (allowing to take into account a new locale) # def reload $dbg.msg(DBG::LOCALE, 'reloading message catalogue') clear @loaded = {} @catfiles.each { |where| catch(:loaded) { filepath(where).each { |fp| if File::readable?(fp) readfile(fp) ; throw :loaded end } raise NoCatalogFound, "No valid catalog found for #{@lang}" } } end ## PRIVATE ## private # # Establish the possible filepaths from the template file # - %s is replace by lang # - if not fullpath the default directory is prepend # # WARN: An array is returned has for exemple we could need to # test for fr_CA and next fr # def filepath(where) where = "#{@directory}/#{where}" unless where[0] == ?/ fp = [] if @language fp << "#{@language}_#{@country}" if @country fp << @language end fp << @dfltlang fp.collect { |x| where % x } end # # Read catalog file # (return false if the file was already loaded, true otherwise) # def readfile(msgfile) # Check for already loaded catalog file_stat = File::stat(msgfile) file_id = [ file_stat.dev, file_stat.ino != 0 ? file_stat.ino \ : msgfile ] if @loaded.has_key?(file_id) $dbg.msg(DBG::LOCALE) { "file already loaded: #{msgfile}" } return false end # Read message catalogue $dbg.msg(DBG::LOCALE, "reading file: #{msgfile}") prefix = nil lineno = 0 File::open(msgfile) { |io| doc = MyXML::Document::new(io) root = doc.root # Tag root.each('//tag') { |element| # create prefix from parent sections prefix = '' xmlsection = element.parent while xmlsection.name == 'section' prefix = xmlsection['name'] + ':' + prefix xmlsection = xmlsection.parent end name = prefix + element['name'] $dbg.msg(DBG::LOCALE) { "locale tag: #{name}" } @tag[name] = element.text } # Shortcut root.each('shortcut') { |shortcut| shortcut.each { |element| name = element['name'] @shortcut[element.name][name] = element } } # Check root.each("check") { |element| checkname = element['name'] name = element.child(NAME) success = element.child(SUCCESS) failure = element.child(FAILURE) explanation = element.child(EXPLANATION) details = element.child(DETAILS) if explanation['sameas'].nil? explanation = nil unless explanation.empty? end if details['sameas'].nil? details = nil unless details.empty? end @check[checkname] = { NAME => name, SUCCESS => success, FAILURE => failure, EXPLANATION => explanation, DETAILS => details } } # Test root.each('test') { |element| testname = element['name'] name = element.child(NAME) @test[testname] = { NAME => name } } } # Consider the file loaded @loaded[file_id] = true return true end end # # Include the 'with_msgcat' facility in every objects # def with_msgcat(*msgcat_list) return unless $mc && $mc.kind_of?(MsgCat) msgcat_list.each { |msgcat| $mc.read(msgcat) } end endzonecheck-3.0.5/zc/param.rb000066400000000000000000000701531226210254100155320ustar00rootroot00000000000000# $Id: param.rb,v 1.115 2011/03/11 16:09:18 kmkaplan Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.115 $ # DATE : $Date: 2011/03/11 16:09:18 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'dbg' require 'report' require 'publisher' require 'msgcat' ## ## Parameters of the ZoneCheck application ## ## All the subclasses have an 'autoconf' method, which must be ## used to finish configuring the class. ## class Param ## ## Hold the flags used to describe report output behaviour ## ## tagonly : only print tag or information suitable for parsing ## one : only print 1 message ## quiet : don't print extra titles ## intro : display summary about checked domain ## testname : print the name of the test in the report ## explain : explain the reason behind the test (if test failed) ## details : give details about the test failure ## testdesc : print a short description of the test being performed ## counter : display a progress bar ## stop_on_fatal: stop on the first fatal error ## reportok : also report test that have passed ## fatalonly : only print fatal errors ## ## Corrections are silently made to respect the following constraints: ## - 'tagonly' doesn't support 'explain', 'details' (as displaying ## a tag for an explanation is meaningless) ## - 'testdesc' and 'counter' are exclusive ## - 'counter' can be ignored if the display doesn't suppport ## progress bar animation ## - 'one' ignore 'testname', 'explain', 'details' ## - 'fatalonly' ignore 'reportok' ## class ReportFlag attr_reader :tagonly, :one, :quiet attr_reader :testname, :intro, :explain, :details attr_reader :testdesc, :counter attr_reader :stop_on_fatal, :reportok, :fatalonly attr_reader :dig attr_writer :one, :quiet, :intro attr_writer :stop_on_fatal, :reportok, :fatalonly attr_writer :testname attr_writer :dig def initialize @tagonly = @one = false @intro = @testname = @details = @explain = false @testdesc = @counter = false @stop_on_fatal = true @reportok = @fatalonly = false @dig = false end def tagonly=(val) @details = @explain = false if @tagonly = val end def explain=(val) @explain = val if !@tagonly end def details=(val) @details = val if !@tagonly end def testdesc=(val) @counter = false if @testdesc = val end def counter=(val) @testdesc = false if @counter = val end def autoconf $dbg.msg(DBG::AUTOCONF) { flags = [] flags << 'tagonly' if @tagonly flags << 'one' if @one flags << 'quiet' if @quiet flags << 'intro' if @intro flags << 'testname' if @testname flags << 'explain' if @explain flags << 'details' if @details flags << 'testdesc' if @testdesc flags << 'counter' if @counter flags << 'stop' if @stop_on_fatal flags << 'reportok' if @reportok flags << 'fatalonly' if @fatalonly flags << 'NONE' if flags.empty? "Report flags: #{flags.join('/')}" } end end ## ## Hold information about the domain to check ## ## name : a fully qualified domain name ## ns : list of nameservers attached to the domain (name) ## output format : [ [ ns1, [ ip1, ip2 ] ], ## [ ns2, [ ip3 ] ], ## [ ns3 ] ] ## input format : ns1=ip1,ip2;ns2=ip3;ns3 ## if element aren't specified they will be 'guessed' ## when calling 'autoconf' ## addresses : list of ns addresses ## cache : should result be stored in external database (for hooks) ## class Domain def initialize(name=nil, ns=nil) clear self.name = name unless name.nil? self.ns = ns unless ns.nil? end attr_reader :cache, :name, :ns, :addresses, :ds, :dnskey, :is_dnssec_mandatory attr_writer :cache, :ds, :dnskey, :is_dnssec_mandatory def clear @name = nil @ns = nil @ns_input = [ ] @addresses = nil @cache = true @ds = nil @dnskey = nil @is_dnssec_mandatory = false end # # The policy for caching is (stop on first match): # - the NS have been guessed => false # - a necessary glue is missing => false # - an unecessary glue has been given => false # - everything else => true # def can_cache? # purely guessed information return false if @ns_input.empty? # glue misused @ns_input.each { |ns, ips| return false unless (ns == @name || ns.subdomain_of?(@name)) ^ ips.empty? } # ok true end def name=(domain) domain = domain + '.' unless domain =~ /.\.$/ domain = Dnsruby::Name::create(domain) unless domain.absolute? raise ArgumentError, $mc.get('xcp_param_fqdn_required') end @name = domain end def ns=(ns) if ns.nil? @ns_input = [ ] @ns = nil return nil end # Parse inputed NS (and IPs) @ns_input = [ ] ns.split(/\s*;\s*/).each { |entry| ips = [] if entry =~ /^(.*?)\s*=\s*(.*)$/ host_str, ips_str = $1, $2 if host_str =~ Dnsruby::IPv4::Regex || host_str =~ Dnsruby::IPv6::Regex || !(host_str =~ /^[A-Za-z0-9.-]+$/) raise ParamError, $mc.get("param:ns_name") % host_str end # Canonicalize host names (final dot mandatory) host_str = host_str + '.' unless host_str =~ /.\.$/ host = Dnsruby::Name::create(host_str) ips_str.split(/\s*,\s*|\s+/).each { |str| if str =~ Dnsruby::IPv4::Regex ips << Dnsruby::IPv4::create(str) else if str =~ Dnsruby::IPv6::Regex ips << Dnsruby::IPv6::create(str) else raise ArgumentError, "Argument #{str} should be an IP address" end end } else if entry =~ Dnsruby::IPv4::Regex || entry =~ Dnsruby::IPv6::Regex || !(entry =~ /^[A-Za-z0-9.-]+$/) raise ParamError, $mc.get("param:ns_name") % entry end # Canonicalize host names (final dot mandatory) entry = entry + '.' unless entry =~ /.\.$/ host = Dnsruby::Name::create(entry) end @ns_input << [ host, ips ] } # Do a deep copy @ns = [ ] @ns_input.each { |host, ips| @ns << [ host, ips.dup ] } # @ns end def autoconf(resolver) # Guess Nameservers and ensure primary is at first position if @ns.nil? $dbg.msg(DBG::AUTOCONF) { "Retrieving NS for #{@name}" } begin soa = nil resolver.query(@name,"SOA").answer.each { |record| soa = record if record.class == Dnsruby::RR::IN::SOA } if soa.nil? raise ParamError, $mc.get('xcp_param_soa') end primary = soa.mname $dbg.msg(DBG::AUTOCONF) { "Identified NS primary as #{primary}" } rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout raise ParamError, $mc.get('xcp_param_domain_nxdomain') % @name rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout raise ParamError, $mc.get('xcp_param_soa') end begin @ns = [ ] nameservers = [] resolver.query(@name,"NS").answer.each { |record| nameservers << record.rdata if record.class == Dnsruby::RR::IN::NS } nameservers.each { |n| if n =~ Dnsruby::IPv4::Regex || n =~ Dnsruby::IPv6::Regex raise ParamError, $mc.get('xcp_param_nameserver_is_ip') end if n == primary then @ns.unshift([ n, [] ]) else @ns << [ n, [] ] end } rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout raise ParamError, $mc.get('xcp_param_nameservers_ns') end if @ns[0].nil? raise ParamError, $mc.get('xcp_param_prim_ns_soa') end end # Set cache status if @cache @cache &&= can_cache? $dbg.msg(DBG::AUTOCONF) { "Cache status set to #{@cache}" } end # Guess Nameservers IP addresses @ns.each { |ns, ips| if ips.empty? then $dbg.msg(DBG::AUTOCONF) { "Retrieving IP for NS: #{ns}" } begin resolver.query(ns.to_s,"A").answer.each { |rr| if rr.class == Dnsruby::RR::IN::A ips << rr.address end } resolver.query(ns.to_s,"AAAA").answer.each { |rr| if rr.class == Dnsruby::RR::IN::AAAA ips << rr.address end } rescue Dnsruby::ResolvError, Dnsruby::ResolvTimeout end end if ips.empty? then raise ParamError, $mc.get('xcp_param_nameserver_ips') % [ ns ] end } # XXX: doesn't allow to force an IP addresse. # # Sanity check on given IP addresses # # => this is not done for nameservers which are in the # # delegated zone, as we need to perform additional # # checks before, there will be an explicit test for it # # in the configuration file # @ns_input.each { |ns, ips| # if !ns.subdomain_of?(@name) && !ips.nil? # resolved_ips = nil # begin # $dbg.msg(DBG::AUTOCONF) {"Comparing IP for NS: #{ns}"} # resolved_ips = dns.getaddresses(ns, # Address::OrderStrict) # # unless ips.unsorted_eql?(resolved_ips) # # raise ParamError, # # $mc.get('xcp_param_ns_bad_ips') % ns # end # rescue Dnsruby::ResolvError # end # if resolved_ips.nil? || resolved_ips.empty? # raise ParamError, # $mc.get('xcp_param_nameserver_ips') % [ ns ] # end # end # } # Build addresses set @addresses = [] @ns.each { |ns, ips| @addresses.concat(ips) } end def get_resolver_ips(name, prim=false) if name.nil? || !((name == @name) || (name.subdomain_of?(@name))) nil # elsif (name.labels.size - @name.labels.size) > 1 # raise RuntimeError, "XXX: correct behaviour not decided (#{name})" else if prim then ns[0][1] else @addresses end end end end ## ## As the Report class, but allow severity override ## class ProxyReport attr_reader :info, :warning, :fatal def initialize @report_class = nil @info_attrname = :info @warning_attrname = :warning @fatal_attrname = :fatal @report = nil @info = nil @warning = nil @fatal = nil end def allfatal @warning_attrname = @fatal_attrname = :fatal end def allwarning @warning_attrname = @fatal_attrname = :warning end def standard @warning_attrname = :warning @fatal_attrname = :fatal end def reporter=(report_class) @report_class = report_class end def reporter @report_class end def finish @report.finish end def autoconf(domain, rflag, publisher) # Set publisher class (if not already done) if @report_class.nil? require 'report/byseverity' @report_class = ::Report::BySeverity end # Instanciate report engine @report = @report_class::new(domain, rflag, publisher) # Define dealing of info/warning/fatal severity @info = @report.method(@info_attrname).call @warning = @report.method(@warning_attrname).call @fatal = @report.method(@fatal_attrname).call # Check for 'tagonly' support if rflag.tagonly && !@report.tagonly_supported? raise ParamError, $mc.get('xcp_param_output_support') % [ 'tagonly' ] end # Check for 'one' support if rflag.one && !@report.one_supported? raise ParamError, $mc.get('xcp_param_output_support') % [ 'one' ] end # Debug $dbg.msg(DBG::AUTOCONF) { "Report using #{reporter}" } end end ## ## Hold information necessary for initializing configuration ## process. ## ## cfgfile: configuration file to use (zc.conf) ## testdir: directory where tests are located ## profile: allow override of automatic profile selection ## preset: allow selection of a preset configuration ## class Preconf attr_reader :cfgfile, :testdir, :profile, :preset attr_writer :cfgfile, :testdir, :profile, :preset def initialize @cfgfile = $zc_config_file @testdir = ZC_TEST_DIR @profile = nil @preset = nil end def autoconf # Debug $dbg.msg(DBG::AUTOCONF) { "Configuration file: #{@cfgfile}" } $dbg.msg(DBG::AUTOCONF) { "Tests directory: #{@testdir}" } $dbg.msg(DBG::AUTOCONF) { "Asking for profile: #{profile}" } $dbg.msg(DBG::AUTOCONF) { "Asking for preset: #{preset}" } end end ## ## Hold information about the resolver behaviour ## ## ipv4 : use IPv4 routing protocol ## ipv6 : use IPv6 routing protocol ## mode : use the following mode for new resolvers: STD / UDP / TCP ## class Network attr_reader :ipv4, :ipv6, :query_mode attr_writer :query_mode def initialize @ipv6 = nil @ipv4 = nil @query_mode = nil end def ipv6=(bool) if bool && ! $ipv6_stack raise ParamError, $mc.get('xcp_param_ip_no_stack') % 'IPv6' end @ipv6 = bool end def ipv4=(bool) if bool && ! $ipv4_stack raise ParamError, $mc.get('xcp_param_ip_no_stack') % 'IPv4' end @ipv4 = bool end def address_wanted?(address) case address when String case address when Dnsruby::IPv4::Regex then address if ipv4 when Dnsruby::IPv6::Regex then address if ipv6 else nil end when Dnsruby::IPv4 then address if ipv4 when Dnsruby::IPv6 then address if ipv6 when Array address.collect { |addr| address_wanted?(addr) }.compact else nil end end def autoconf # Select routing protocol (IPv4/IPv6) @ipv4 = @ipv6 = true if @ipv4.nil? && @ipv6.nil? @ipv4 = false if @ipv4.nil? || !$ipv4_stack @ipv6 = false if @ipv6.nil? || !$ipv6_stack if !@ipv4 && !@ipv6 raise 'Why are you using this program! (No IP stack selected)' end # Debug $dbg.msg(DBG::AUTOCONF) { routing = [ ] routing << 'IPv4' if @ipv4 routing << 'IPv6' if @ipv6 routing << 'NONE' if routing.empty? # => YARGL "Routing protocol set to: #{routing.join('/')}" } # Select mode (UDP/TCP/STD) @query_mode = "std" if @query_mode.nil? # Debug $dbg.msg(DBG::AUTOCONF) { "Query mode set to: #{@query_mode}" } end end ## ## Hold information about local resolver ## ## local: local resolver to use ## class Resolver attr_reader :local def initialize @local = nil @local_name = nil end def local=(resolv) resolv = resolv.dup.untaint if resolv.tainted? @local_name = if resolv.nil? || resolv =~ /^\s*$/ then nil else resolv end @local = nil end def autoconf # Select local resolver if @local.nil? @local = if @local_name.nil? # Use default resolver Dnsruby::Resolver::new else # Only accept addresses unless @local_name =~ Dnsruby::IPv4::Regex || @local_name =~ Dnsruby::IPv6::Regex raise ParamError, $mc.get('xcp_param_local_resolver') end # Build new resolver Dnsruby::Resolver::new(@local_name) end end @local.do_caching = false @local.dnssec = false # Debug $dbg.msg(DBG::AUTOCONF) { resolver = @local_name || '' "Resolver #{resolver}" } end end ## ## Hold information about the test ## ## list : has listing of test name been requested ## test : limiting tests to this list ## catagories: limiting tests to these categories ## desctype : description type (name, xpl, error, ...) ## class Test attr_reader :list, :tests, :categories, :desctype attr_writer :list def initialize @list = false @tests = nil @categories = nil @desctype = nil end def desctype=(string) case string when MsgCat::NAME, MsgCat::EXPLANATION, MsgCat::SUCCESS, MsgCat::FAILURE @desctype = string else raise ParamError, $mc.get('xcp_param_unknown_modopt') % [string, 'testdesc'] end end def tests=(string) @tests = if string.nil? || string =~ /^\s*$/ then nil else string.split(/\s*,\s*/) end end def categories=(string) return if string =~ /^\s*$/ @categories = string.split(/\s*,\s*/) end def autoconf # Debug $dbg.msg(DBG::AUTOCONF) { tests = (@tests || [ 'ALL' ]).join(',') "Selected tests: #{tests}" } $dbg.msg(DBG::AUTOCONF) { categories = (@categories || [ '+' ]).join(',') "Selected categories: #{categories}" } if @desctype $dbg.msg(DBG::AUTOCONF) { "Test description requested for type: #{@desctype}" } end if @list $dbg.msg(DBG::AUTOCONF) { 'Test listing requested' } end end end ## ## Hold information about the publisher ## ## engine : the publisher to use (write class, read object) ## class Publisher def initialize @publisher_class = nil @publisher = nil end def engine=(klass) @publisher_class = klass end def engine @publisher end def autoconf(rflag, option) # Set publisher class (if not already done) if @publisher_class.nil? require 'publisher/text' @publisher_class = ::Publisher::Text end # Set output publisher @publisher = @publisher_class::new(rflag, option, $console.stdout) $dbg.msg(DBG::AUTOCONF) { "Publish using #{@publisher_class}" } end end ## ## Hold optional input information ## class Option def initialize @opt = { } end def [](key) ; @opt[key] ; end def []=(key,value) ; @opt[key] = value ; end def delete(key) ; @opt.delete(key) ; end def clear ; @opt = { } ; end def each ; @opt.each { |*a| yield a } ; end def <<(args) args.strip.split(/\s*,\s*/).each { |arg| case arg when /^-$/ then self.clear when /^-(\w+)$/ then self.delete($1) when /^\+?(\w+)$/ then self[$1] = true when /^\+?(\w+)=(\w+)$/ then self[$1] = $2 else raise ArgumentError, 'bad option specification' end } self end def autoconf @opt.each { |key, value| $dbg.msg(DBG::AUTOCONF) { if value == true # this is NOT a pleonasm! then "Option set: #{key}" else "Option set: #{key} = #{value}" end } } end end ## ## Hold information (statistics, ...) ## class Info attr_reader :testingtime, :testcount, :nscount, :profile attr_writer :testingtime, :testcount, :nscount, :profile def initialize end def clear @testingtime = 0.0 @testcount = 0 @nscount = 0 @profile = nil end def autoconf end end ## ## Exception: Parameter errors (ie: usage) ## class ParamError < StandardError end # # ATTRIBUTS # attr_reader :publisher, :preconf, :network, :resolver, :rflag, :test, :report, :option, :info attr_reader :domain, :edns attr_writer :domain, :edns # # Create parameters # def initialize @publisher = Publisher::new @preconf = Preconf::new @network = Network::new @resolver = Resolver::new @test = Test::new @report = ProxyReport::new @domain = Domain::new @rflag = ReportFlag::new @option = Option::new @info = Info::new @edns = "auto" end # # WRITER: error # def error=(string) return if (string = string.strip).empty? string.split(/\s*,\s*/).each { |token| case token when 'af', 'allfatal' then @report.allfatal when 'aw', 'allwarning' then @report.allwarning when 'ds', 'dfltseverity' then @report.standard when 's', 'stop' then @rflag.stop_on_fatal = true when 'ns', 'nostop' then @rflag.stop_on_fatal = false else raise ParamError, $mc.get('xcp_param_unknown_modopt') % [ token, 'error' ] end } end # # WRITER: verbose # def verbose=(string) return if (string = string.strip).empty? string.split(/\s*,\s*/).each { |token| action = case token[0] when ?!, ?- then token = token[1..-1] ; false when ?+ then token = token[1..-1] ; true else true end case token when 'i', 'intro' then @rflag.intro = action when 'n', 'testname' then @rflag.testname = action when 'x', 'explain' then @rflag.explain = action when 'd', 'details' then @rflag.details = action when 'o', 'reportok' then @rflag.reportok = action when 'f', 'fatalonly' then @rflag.fatalonly = action when 't', 'testdesc' then @rflag.testdesc = action when 'c', 'counter' then @rflag.counter = action when 'g', 'dig' then @rflag.dig = action else raise ParamError, $mc.get('xcp_param_unknown_modopt') % [ token, 'verbose' ] end } end # # WRITER: output # def output=(string) return if (string = string.strip).empty? string.split(/\s*,\s*/).each { |token| case token when 'bs', 'byseverity' require 'report/byseverity' @report.reporter = Report::BySeverity when 'bh', 'byhost' require 'report/byhost' @report.reporter = Report::ByHost when 't', 'text' require 'publisher/text' @publisher.engine = ::Publisher::Text when 'h', 'html' require 'publisher/html' @publisher.engine = ::Publisher::HTML when 'x', 'xml' require 'publisher/xml' @publisher.engine = ::Publisher::XML else raise ParamError, $mc.get('xcp_param_unknown_modopt') % [ token, 'output' ] end } end # # WRITER: transp # def transp=(string) return if (string = string.strip).empty? string.split(/\s*,\s*/).each { |token| case token when '4', 'ipv4' then @network.ipv4 = true when '6', 'ipv6' then @network.ipv6 = true when 'u', 'udp' @network.query_mode = "udp" when 't', 'tcp' @network.query_mode = "tcp" when 's', 'std' @network.query_mode = "std" else raise ParamError, $mc.get('xcp_param_unknown_modopt') % [token, 'transp'] end } end def securedelegation=(string) if (string = string.strip).empty? @domain.is_dnssec_mandatory = true else array = string.split(/\s*,\s*/) if array.size == 1 || array.size == 2 array.each { |token| if token =~ /^DNSKEY:/ token = token.gsub(/DNSKEY:/, '') rr = Dnsruby::RR::DNSKEY.new() rr.init_defaults rr.key = token unless @domain.dnskey @domain.dnskey = [] end @domain.dnskey << rr elsif token =~ /^DS:/ token = token.gsub(/DS:/,'') ds = token.split(/\s*:\s*/) unless ds.size == 2 raise ParamError, "Syntax of DS argument should be DS:your_ds:the_hash_algorithm\n" end rr = Dnsruby::RR::DS.new() rr.init_defaults rr.digest= ds[0] rr.digest_type= ds[1] rr.digestbin = [rr.digest].pack("H*") unless @domain.ds @domain.ds = [] end @domain.ds << rr elsif token =~ /^DS-RDATA:/ token = token.gsub(/DS-RDATA:/,'') rr = Dnsruby::RR::DS.new() rr.from_string(token) unless @domain.ds @domain.ds = [] end @domain.ds << rr else raise ParamError, "See man page for syntax of --securedelegation option" end } else raise ParamError, $mc.get('param_too_many_arguments') % [arra.size.to_s, 'sd'] end @domain.is_dnssec_mandatory = true end end end end zonecheck-3.0.5/zc/publisher.rb000066400000000000000000000063611226210254100164270ustar00rootroot00000000000000# $Id: publisher.rb,v 1.41 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.41 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'thread' module Publisher def self.to_bind_duration(src) sec = src % 60 ; src /= 60 min = src % 60 ; src /= 60 hour = src % 24 ; src /= 24 day = src % 7 ; src /= 7 week = src str = '' str += "#{week}W" if week > 0 str += "#{day}D" if day > 0 str += "#{hour}H" if hour > 0 str += "#{min}M" if min > 0 str += "#{sec}S" if sec > 0 str end ## ## ## class Template # --> ABSTRACT <-- attr_reader :progress, :xmltrans attr_reader :info, :rflag, :option attr_writer :info def initialize(rflag, option, ostream=$stdout) @rflag = rflag @option = option @o = ostream @mutex = Mutex::new @info = nil end def constants=(const) @xmltrans.const = const end def output ; @o ; end def synchronize(&block) @mutex.synchronize(&block) end def setup(domain_name) end def status(domainname, i_count, w_count, f_count) if f_count == 0 tag = (w_count > 0) ? "res_success_but" : "res_success" else tag = (w_count > 0) ? "res_failure_and" : "res_failure" end $mc.get(tag) % [ w_count ] end def begin ; end def end ; end #-- [protected] --------------------------------------------- protected def severity_description(i_unexp, w_unexp, f_unexp) if @rflag.tagonly i_tag = ZoneCheck::Config::Info w_tag = ZoneCheck::Config::Warning f_tag = ZoneCheck::Config::Fatal else i_tag = $mc.get('word:info_id') w_tag = $mc.get('word:warning_id') f_tag = $mc.get('word:fatal_id') end i_tag = i_tag.upcase if i_unexp w_tag = w_tag.upcase if w_unexp f_tag = f_tag.upcase if f_unexp [ i_tag, w_tag, f_tag ] end def status_message(checkname, desc, severity) # WARN: MsgCat::TEST only defines MsgCat::NAME but # it is only generated on error type = desc.check ? MsgCat::CHECK : MsgCat::TEST if severity.nil? @xmltrans.apply($mc.get(checkname, type, MsgCat::SUCCESS)) elsif desc.error l10n_name = @xmltrans.apply($mc.get(checkname, type, MsgCat::NAME)) "[TEST #{l10n_name}]: #{desc.error}" else @xmltrans.apply($mc.get(checkname, type, MsgCat::FAILURE)) end end end end zonecheck-3.0.5/zc/publisher/000077500000000000000000000000001226210254100160745ustar00rootroot00000000000000zonecheck-3.0.5/zc/publisher/html.rb000066400000000000000000000374011226210254100173720ustar00rootroot00000000000000# $Id: html.rb,v 1.82 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.82 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ##### # # TODO: # - escape html text # - clean up html # - only load javascript when needed # require 'cgi' require 'config' module Publisher ## ## ## class HTML < Template Mime = "text/html" # Shortcut for enclosing javascript def self.jscript '' end # Shortcut for enclosing noscript def self.nscript '' end ## ## Rendering of XML chunks ## class XMLTransform attr_writer :const def initialize @const = {} end def apply(xmlnode, var={}) case xmlnode when MyXML::Node::Element case xmlnode.name when MsgCat::NAME, MsgCat::FAILURE, MsgCat::SUCCESS do_text(xmlnode, var) when MsgCat::EXPLANATION # not displayed in tagonly "
    " + xmlnode.to_a('src').collect { |xmlsrc| type = $mc.get("tag_#{xmlsrc['type']}") title = do_text(xmlsrc.child('title')) from = xmlsrc['from'] fid = xmlsrc['fid'] link = case from when 'rfc' case fid when NilClass 'http://www.ietf.org/' when /^(rfc\d+)/ "ftp://ftp.ietf.org/rfc/#{$1}.txt" end end title = "#{title}" if link "
  • " + "#{type}: #{title}" + "
    " + xmlsrc.to_a('para').collect { |xmlpara| fmt_para(do_text(xmlpara, var)) }.join + "
  • " }.join("\n") + "
" when MsgCat::DETAILS # not displayed in tagonly "
  • " + xmlnode.to_a('para').collect { |xmlpara| fmt_para(do_text(xmlpara, var)) }.join + '
' else do_text(xmlnode, var) end when MyXML::Node::Text CGI::escapeHTML(xmlnode.value.to_s) else '' end end #-- [private] ----------------------------------------------- private def fmt_para(text) '

' + text + '

' end def do_text(xmlnode, var={}) case xmlnode when MyXML::Node::Element case xmlnode.name when 'zcvar', 'zcconst' display = xmlnode['display'] data = case xmlnode.name when 'zcvar' then var when 'zcconst' then @const end name = xmlnode['name'] value = data.fetch(name) case display when 'duration' unit = $mc.get('word:second_abbr') "" + Publisher.to_bind_duration(value.to_i) + '' else value end when 'uri' link = xmlnode['link'] "" + xmlnode.text + "" else xmlnode.to_a(:child).collect { |xmlchild| do_text(xmlchild, var) }.join end when MyXML::Node::Text CGI::escapeHTML(xmlnode.value.to_s) else '' end end end ## ## Class for displaying progression information about ## the tests being performed. ## class Progress # Initialization def initialize(publisher) @publisher = publisher @jscript_off = publisher.option['nojavascript'] @o = publisher.output @l10n_testing = $mc.get('word:testing').capitalize end # Start progression def start(count) title = if @publisher.rflag.quiet then "" else "

" + $mc.get('title_progress') + "

" end # Counter if @publisher.rflag.counter && !@jscript_off @o.puts HTML.jscript { pgr_quiet_param = @publisher.rflag.quiet ? "true" \ : "false" pgr_locale_param = [ $mc.get('title_progress'), $mc.get('pgr_progress'), $mc.get('pgr_test'), $mc.get('pgr_speed'), $mc.get('pgr_time'), $mc.get('pgr_na') ] pgr_start_param = count str = 'zc_pgr_setlocale("%s", "%s", "%s", "%s", "%s", "%s");' % pgr_locale_param str += 'zc_pgr_setquiet(%s);' % pgr_quiet_param str += 'zc_pgr_start(%d);' % pgr_start_param str } @o.puts HTML.nscript { title } @o.puts HTML.nscript { "
    " } end # Test description if @publisher.rflag.testdesc @o.puts title @o.puts "
      " end end # Finished on success def done(desc) end # Finished on failure def failed(desc) end # Finish (finalize) output def finish # Counter if @publisher.rflag.counter && !@jscript_off @o.puts HTML.jscript { "zc_pgr_finish();" } @o.puts HTML.nscript { "
    " } end # Test description if @publisher.rflag.testdesc @o.puts "
" end end # Process an item def process(checkname, ns, ip) # Don't bother, if there is no output asked return unless (@publisher.rflag.counter || @publisher.rflag.testdesc) xtra = if ip then " (IP=#{ip})" elsif ns then " (NS=#{ns})" else '' end desc = if @publisher.rflag.tagonly checkname else @publisher.xmltrans.apply($mc.get(checkname, MsgCat::CHECK, MsgCat::NAME)) end msg = "#{desc}#{xtra}" # Counter if @publisher.rflag.counter && !@jscript_off jmsg = msg.gsub(/\"/, '\\"') @o.puts HTML.jscript { "zc_pgr_process(\"#{jmsg}\")" } @o.puts HTML.nscript { "
  • #{@l10n_testing}: #{msg}
  • "} end # Test description if @publisher.rflag.testdesc @o.puts "
  • #{@l10n_testing}: #{msg}
  • " end # Flush @o.flush end end #------------------------------------------------------------ def initialize(rflag, option, ostream=$stdout) super(rflag, option, ostream) @progress = Progress::new(self) @publish_path = ZC_HTML_PATH.gsub(/\/+$/, '') @xmltrans = XMLTransform::new end def error(text) @o.puts "
    " @o.puts "" @o.puts CGI::escapeHTML(text) @o.puts "
    " end #------------------------------------------------------------ def begin return if @option['ihtml'] l10n_form = $mc.get('word:form').capitalize l10n_single_form = l10n_form+': '+$mc.get('t_single').capitalize # XXX: javascript only if counter langpath = $locale.language langpath << "_" + $locale.country if $locale.country @o.print <<"EOT" ZoneCheck results EOT unless @option['nojavascript'] @o.print <<"EOT" EOT end @o.print <<"EOT" EOT @o.flush end def end return if @option['ihtml'] profileinfo = if info.profile then "#{info.profile[0]} (#{info.profile[1]})" else 'N/A' end # @o.puts @HTML.jscript { # "zc_contextmenu_setlocale(\"#{$mc.get('word:name')}\", \"#{$mc.get('word:details')}\", \"#{$mc.get('word:references')}\", \"#{$mc.get('word:elements')}\");\n" + # "zc_contextmenu_start();" } @o.print <<"EOT"
    Valid CSS! Valid HTML 4.01! Profile: #{profileinfo}
    Statistics: #{"%d tests in %.2f sec accross %d nameservers" % [info.testcount, info.testingtime, info.nscount]}
    Release: #{$zc_name}-#{CGI::escapeHTML($zc_version.to_s)}
    Last generated: #{Time::now.gmtime.strftime("%Y/%m/%d %H:%M UTC")} EOT end def setup(domain_name) if !@rflag.quiet && !@option['ihtml'] @o.puts "

    ZoneCheck: #{CGI::escapeHTML(domain_name.to_s)}

    " end end #------------------------------------------------------------ def intro(domain) return unless @rflag.intro tbl_beg = '' tbl_zone = '' tbl_ns = '' tbl_end = '
    %s%s
    %s%s%s
    ' unless @rflag.quiet title = $mc.get('title_zoneinfo') @o.puts "

    #{title}

    " end l10n_zone = $mc.get('ns_zone').capitalize @o.puts "
    " # Easy parseable comment ([ "ZONE: #{domain.name}" ] + domain.ns.collect { |ns, ips| "NS : #{ns} [#{ips.join(', ')}]" }).each { |e| @o.puts "" } # Result @o.puts tbl_beg @o.puts tbl_zone % [ "\"#{l10n_zone}\"", CGI::escapeHTML(domain.name.to_s) ] domain.ns.each_index { |i| ns_ip = domain.ns[i] if i == 0 css = 'zc-ns-prim' desc = $mc.get('ns_primary').capitalize logo = 'primary' else css = 'zc-ns-sec' desc = $mc.get('ns_secondary').capitalize logo = 'secondary' end desc = "\"#{desc}\"" @o.puts tbl_ns % [ css, desc, CGI::escapeHTML(ns_ip[0].to_s), CGI::escapeHTML(ns_ip[1].join(", ")) ] } @o.puts tbl_end @o.puts "
    " @o.flush end def diag_start() @o.puts "

    #{$mc.get('title_testres')}

    " end def diag_section(title) @o.puts "

    ---- #{title} ----

    " end def diagnostic1(domainname, i_count, i_unexp, w_count, w_unexp, f_count, f_unexp, res, severity) i_tag, w_tag, f_tag = severity_description(i_unexp, w_unexp, f_unexp) summary = "%1s%03d %1s%03d %1s%03d" % [ i_tag, i_count, w_tag, w_count, f_tag, f_count ] @o.puts "
    " @o.puts "" @o.puts "" if !res.nil? if @rflag.tagonly status = severity source = res.source || 'generic' msg = res.testname else status = ZoneCheck::Config.severity2tag(severity) status = $mc.get("word:#{status}").capitalize source = res.source || $mc.get('word:generic') msg = status_message(res.testname, res.desc, severity) end @o.puts "" @o.puts "" else @o.puts "" @o.puts "" end @o.puts "
    #{CGI::escapeHTML(domainname.to_s)}#{summary}
    #{status}: #{source}
    #{msg}
     --
     --
    " @o.puts "
    " end def diagnostic(severity, testname, desc, lst) @o.puts "" @o.puts "
    " # Testname if desc.check && @rflag.testname && !@rflag.tagonly l10n_name = @xmltrans.apply($mc.get(testname, MsgCat::CHECK, MsgCat::NAME)) @o.puts "
    \"\" #{l10n_name}
    " end # Status messsage status_tag = ZoneCheck::Config.severity2tag(severity) logo = status_tag + ".png" if @rflag.tagonly status_shorttag = severity || ZoneCheck::Config::Ok status = desc.error ? "[Unexpected] #{testname}" : testname else status_shorttag = $mc.get("word:#{status_tag}_id") status = status_message(testname, desc, severity) end @o.puts "
    \"#{status_shorttag}:\" #{status}
    " # Explanation & Details # => only in case of failure (ie: not for Ok or Error) # not when in 'tag only' mode if desc.check && !severity.nil? && desc.error.nil? && !@rflag.tagonly # Explanation if @rflag.explain explanation = $mc.get(testname, MsgCat::CHECK, MsgCat::EXPLANATION) @o.print @xmltrans.apply(explanation) if explanation end # Details if @rflag.details && desc.details details = $mc.get(testname, MsgCat::CHECK, MsgCat::DETAILS) @o.print @xmltrans.apply(details, desc.details) if details end end # Elements if ! lst.empty? @o.puts "
      " lst.each { |elt| elt ||= (@rflag.tagonly ? 'generic' : $mc.get('word:generic')) @o.puts "
    • #{elt}
    • " } @o.puts "
    " end @o.puts "
    " @o.puts "
    " end def status(domainname, i_count, w_count, f_count) unless @rflag.quiet l10n_title = $mc.get('title_status') @o.puts "

    #{l10n_title}

    " end @o.puts "
    " # Easy parseable comment [ "STATUS : #{f_count > 0 ? "FAILED" : "PASSED"}", " error : #{f_count}", " warning: #{w_count}" ].each { |e| @o.puts "" } # Result @o.puts super(domainname, i_count, w_count, f_count) @o.puts "
    " @o.puts "
    " if @rflag.quiet @o.puts "
    " @o.puts "
    " end end end end zonecheck-3.0.5/zc/publisher/text.rb000066400000000000000000000247771226210254100174260ustar00rootroot00000000000000# $Id: text.rb,v 1.42 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.42 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'textfmt' require 'config' module Publisher ## ## ## class Text < Template Mime = "text/plain" MaxLineLength = 79 ## ## Rendering of XML chunks ## class XMLTransform attr_writer :const def initialize @const = {} end def apply(xmlnode, var={}) case xmlnode when MyXML::Node::Element case xmlnode.name when MsgCat::NAME, MsgCat::FAILURE, MsgCat::SUCCESS do_text(xmlnode, var) when MsgCat::EXPLANATION # not displayed in tagonly text = xmlnode.to_a('src').collect { |xmlsrc| type = $mc.get("tag_#{xmlsrc['type']}") title = do_text(xmlsrc.child('title')) type + ': ' + title + "\n" + xmlsrc.to_a('para').collect { |xmlpara| fmt_para(do_text(xmlpara, var)) }.join }.join("\n") ::Text::Formater.lbox(text, [ ' |', ' `', '-', ' ' ]) when MsgCat::DETAILS # not displayed in tagonly text = xmlnode.to_a('para').collect { |xmlpara| fmt_para(do_text(xmlpara, var)) }.join("\n") ::Text::Formater.lbox(text, [ ' :', ' `', '.', ' ' ]) else do_text(xmlnode, var) end when MyXML::Node::Text xmlnode.value else '' end end #-- [private] ----------------------------------------------- private def fmt_para(text, width=MaxLineLength-7, tag=' ') ::Text::Formater.paragraph(text, width, tag) end def do_text(xmlnode, var={}) case xmlnode when MyXML::Node::Element case xmlnode.name when 'zcvar', 'zcconst' display = xmlnode['display'] data = case xmlnode.name when 'zcvar' then var when 'zcconst' then @const end name = xmlnode['name'] value = data.fetch(name) case display when 'duration' Publisher.to_bind_duration(value.to_i) else value end else xmlnode.to_a(:child).collect { |xmlchild| do_text(xmlchild, var) }.join end when MyXML::Node::Text xmlnode.value else '' end end end ## ## Display progression information about the tests being performed. ## class Progress ## ## Progession bar implementation ## class PBar BarSize = 37 def initialize(output, precision) @output = output @precision = precision @mutex = Mutex::new @updater = nil @l10n_unit = $mc.get('pgr_speed_unit') end def start(length) @length = length @starttime = @lasttime = Time.now @totaltime = 0 @processed = 0 @tick = 0 @output.write $console.ctl['vi'] @output.print barstr @updater = Thread::new { last_processed = nil while true sleep(@precision) nowtime = Time.now @mutex.synchronize { @totaltime = if @lasttime == @starttime then 0.0 else nowtime - @starttime end @lasttime = nowtime if @processed != last_processed @tick += 1 last_processed = @processed end @output.write "\r" @output.print barstr @output.write $console.ctl['ce'] @output.flush } end } end def processed(size) @mutex.synchronize { @processed += size } end def done @mutex.synchronize { @updater.kill } @output.write "\r" + $console.ctl['ce'] @output.flush end def finish @output.write $console.ctl['ve'] end protected def barstr speed = if @totaltime == 0.0 then -1.0 else @processed / @totaltime end speed_s = if speed < 0.0 then "--.--%s" % [ @l10n_unit ] else "%7.2f%s" % [ speed, @l10n_unit ] end if @length > 0 then pct = 100 * @processed / @length eta = if speed < 0.0 then -1 else ((@length-@processed) / speed).to_i end pct_s = "%2d%%" % pct eta_s = "ETA " + sec_to_timestr(eta) bar_s = '=' * (BarSize * pct / 100) + '>' "%-4s[%-#{BarSize}.#{BarSize}s] %-11s %10s %12s" % [ pct_s, bar_s, @processed, speed_s, eta_s ] else ind = @tick % (BarSize * 2 - 6) pos = if ind < BarSize - 2 then ind + 1; else BarSize - (ind - BarSize + 5) end bar_s = " " * BarSize bar_s[pos-1,3] = '<=>' " [%s] %-11s %10s" % [ bar_s, @processed, speed_s ] end end private def sec_to_timestr(sec) return "--:--" if sec < 0 hrs = sec / 3600; sec %= 3600; min = sec / 60; sec %= 60; if (hrs > 0) then sprintf "%2d:%02d:%02d", hrs, min, sec else sprintf "%2d:%02d", min, sec end end end # Initialization def initialize(publisher) @publisher = publisher @o = publisher.output @counter = if @publisher.rflag.counter && @o.tty? then PBar::new(@o, 1) else nil end @l10n_testing = $mc.get('word:testing').capitalize end # Start progression def start(count) @counter.start(count) if @counter end # Finished on success def done(desc) @counter.done if @counter end # Finished on failure def failed(desc) @counter.done if @counter end # Finish (finalize) output def finish @counter.finish if @counter end # Process an item def process(checkname, ns, ip) # Counter if @counter @counter.processed(1) end # Test description if @publisher.rflag.testdesc xtra = if ip then " (IP=#{ip})" elsif ns then " (NS=#{ns})" else '' end if @publisher.rflag.tagonly @o.puts "Testing: #{checkname}#{xtra}" else desc = @publisher.xmltrans.apply($mc.get(checkname, MsgCat::CHECK, MsgCat::NAME)) @o.puts "#{@l10n_testing}: #{desc}#{xtra}" end end end end #------------------------------------------------------------ def initialize(rflag, option, ostream=$stdout) super(rflag, option, ostream) @progress = Progress::new(self) @xmltrans = XMLTransform::new end #------------------------------------------------------------ def testdesc(testname, subtype) l10n = @xmltrans.apply($mc.get(testname, MsgCat::CHECK, subtype)) case subtype when MsgCat::NAME, MsgCat::FAILURE, MsgCat::SUCCESS l10n += "\n" end @o.puts testname + ':' @o.print l10n @o.puts end def error(text) @o.print ::Text::Formater.paragraph(text, MaxLineLength, $mc.get('word:error').upcase+': ') end def intro(domain) return unless @rflag.intro l10n_zone = $mc.get('ns_zone').upcase l10n_ns = $mc.get('ns_ns' ).upcase sz = [ l10n_zone.length, l10n_ns.length+3 ].max @o.printf "%-*s : %s\n", sz, l10n_zone, domain.name domain.ns.each_index { |i| n = domain.ns[i] @o.printf "%-*s : %s [%s]\n", sz, i == 0 ? "#{l10n_ns} <=" : "#{l10n_ns} ", n[0].to_s, n[1].join(', ') } @o.puts end def diag_start() end def diag_section(title) @o.print ::Text::Formater.title(title, MaxLineLength) end def diagnostic1(domainname, i_count, i_unexp, w_count, w_unexp, f_count, f_unexp, res, severity) i_tag, w_tag, f_tag = severity_description(i_unexp, w_unexp, f_unexp) summary = "%1s%03d %1s%03d %1s%03d" % [ i_tag, i_count, w_tag, w_count, f_tag, f_count ] @o.printf "%-*s %s\n", MaxLineLength - 4 - summary.length, domainname, summary if !res.nil? if @rflag.tagonly @o.puts " #{res.testname}" @o.puts " #{severity}: #{res.source || 'generic'}" else status = ZoneCheck::Config.severity2tag(severity) l10n_status = $mc.get("word:#{status}").capitalize source = res.source || $mc.get('word:generic') msg = status_message(res.testname, res.desc, severity) @o.puts " #{msg}" @o.puts " #{l10n_status}: #{source}" end else @o.puts " --", " --" end end def diagnostic(severity, testname, desc, lst) # Testname if desc.check && @rflag.testname && !@rflag.tagonly l10n_name = @xmltrans.apply($mc.get(testname, MsgCat::CHECK, MsgCat::NAME)) @o.puts "[> #{l10n_name}" end # Status messsage status_tag = ZoneCheck::Config.severity2tag(severity) if @rflag.tagonly status_shorttag = severity || ZoneCheck::Config::Ok status = desc.error ? "[Unexpected] #{testname}" : testname else status_shorttag = $mc.get("word:#{status_tag}_id") status = status_message(testname, desc, severity) end @o.puts "#{status_shorttag}> #{status}" # Explanation & Details # => only in case of failure (ie: not for Ok or Error) # not when in 'tag only' mode if desc.check && !severity.nil? && desc.error.nil? && !@rflag.tagonly # Explanation if @rflag.explain explanation = $mc.get(testname, MsgCat::CHECK, MsgCat::EXPLANATION) @o.print @xmltrans.apply(explanation) if explanation end # Details if @rflag.details && desc.details details = $mc.get(testname, MsgCat::CHECK, MsgCat::DETAILS) @o.print @xmltrans.apply(details, desc.details) if details end end # Elements lst.each { |elt| elt ||= (@rflag.tagonly ? 'generic' : $mc.get('word:generic')) @o.print ::Text::Formater.item(elt) } if @rflag.dig && !(desc.details.nil?) && !(desc.details["dig"].nil?) @o.puts $mc.get("dig_print") @o.puts desc.details["dig"] end # Blank @o.puts '' end def status(domainname, i_count, w_count, f_count) @o.puts "==> " + super(domainname, i_count, w_count, f_count) end end end zonecheck-3.0.5/zc/publisher/xml.rb000066400000000000000000000142011226210254100172170ustar00rootroot00000000000000# $Id: xml.rb,v 1.8 2010/06/07 08:51:25 chabannf Exp $ # # CONTACT : # AUTHOR : Stephane D'Alu # # CREATED : 2003/06/26 22:32:43 # REVISION : $Revision: 1.8 $ # DATE : $Date: 2010/06/07 08:51:25 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : Stephane D'Alu (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'config' module Publisher ## ## ## class XML < Template Mime = "text/xml" ## ## Class for displaying progression information about ## the tests being performed. ## class Progress # Initialization def initialize(publisher) @publisher = publisher @o = publisher.output @l10n_testing = $mc.get("word:testing").capitalize end # Start progression def start(count) # Counter if @publisher.rflag.counter || @publisher.rflag.testdesc @o.puts "" end end # Finished on success def done(desc) end # Finished on failure def failed(desc) end # Finish (finalize) output def finish # Counter if @publisher.rflag.counter || @publisher.rflag.testdesc @o.puts "" end end # Process an item def process(desc, ns, ip) # Don't bother, if there is no output asked return unless (@publisher.rflag.counter || @publisher.rflag.testdesc) @o.puts " " xtra = if ip then " (IP=#{ip})" elsif ns then " (NS=#{ns})" else "" end msg = "#{desc}#{xtra}" end end #------------------------------------------------------------ def initialize(rflag, option, ostream=$stdout) super(rflag, option, ostream) @progress = Progress::new(self) @publish_path = ZC_HTML_PATH.gsub(/\/+$/, "") end def error(text) @o.puts "
    #{text}
    " end #------------------------------------------------------------ def begin # XXX: javascript only if counter @o.print <<"EOT" EOT end def end @o.print <<"EOT" release=\"#{$zc_name}-#{$zc_version.gsub(//,'>')}\" date=\"#{Time::now}\"> EOT end def setup(domain_name) end #------------------------------------------------------------ def intro(domain) return unless @rflag.intro @o.puts " " @o.puts " #{domain.name}" domain.ns.each_index { |i| ns_ip = domain.ns[i] if i == 0 then @o.puts " " else @o.puts " " end @o.puts " #{ns_ip[0]}" ns_ip[1].each { |ip| type = case ip when Dnsruby::IPv4 then "ipv4" when Dnsruby::IPv6 then "ipv6" else raise "Unknown address type" end @o.puts "
    #{ip}
    " } @o.puts "
    " } @o.puts "
    " end def diag_start() end def diag_section(title) end def diagnostic1(domainname, i_count, i_unexp, w_count, w_unexp, f_count, f_unexp, res, severity) i_tag, w_tag, f_tag = severity_description(i_unexp, w_unexp, f_unexp) summary = "%1s%03d %1s%03d %1s%03d" % [ i_tag, i_count, w_tag, w_count, f_tag, f_count ] @o.puts "
    " @o.puts "" @o.puts "" if res.nil? l10n_perfect = $mc.get("word:perfect").capitalize @o.puts "" @o.puts "" else msg = if @rflag.tagonly then res.testname else res.desc.msg end @o.puts "" @o.puts "" end @o.puts "
    #{domainname}#{summary}
    #{l10n_perfect}
     
    #{severity}: #{res.tag}
    #{msg}
    " @o.puts "
    " end def diagnostic(severity, testname, desc, lst) msg, xpl_lst = nil, nil @o.puts "" @o.puts " #{testname}" # Severity @o.puts " " # Testname if @rflag.testname @o.puts " #{$mc.get("#{testname}_testname")}" end # Message if severity.nil? msg = $mc.get("#{testname}_ok") msgtype = "passed" else msg = desc.msg msgtype = desc.is_error? ? "exception" : "failed" end @o.puts " #{msg}" if !severity.nil? # Details if @rflag.details && desc.dtl @o.puts "
    #{desc.dtl}
    " end # Explanation if @rflag.explain && !@rflag.tagonly xpl_lst = xpl_split(desc.xpl) end if xpl_lst xpl_lst.each { |t, h, b| @o.puts " " @o.puts " " + h.gsub(/]+)>/, '\1') + "" @o.puts " " b.each { |l| @o.puts l.gsub(/]+)>/, '\1') } @o.puts " " @o.puts " " } end end # Elements lst.each { |elt| @o.puts " #{elt}" } @o.puts "
    " end def status(domainname, i_count, w_count, f_count) @o.puts "" @o.puts "" end end end zonecheck-3.0.5/zc/report.rb000066400000000000000000000067031226210254100157450ustar00rootroot00000000000000# $Id: report.rb,v 1.42 2010/06/21 09:34:44 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.42 $ # DATE : $Date: 2010/06/21 09:34:44 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'config' module Report ## ## Exception raised to abort zonecheck ## class FatalError < StandardError end ## ## Template for creating report ## class Template attr_reader :full_list, :ok attr_reader :fatal, :warning, :info def tagonly_supported? ; true ; end def one_supported? ; true ; end ## ## ## class Processor # --> ABSTRACT <-- def initialize(master) @master = master @list = [] end def empty? ; @list.empty? ; end def count ; @list.length ; end def one ; @list.first ; end def list ; @list ; end def <<(result) if result.ok? then @master.ok << result else @list << result @master.full_list << [ result, severity ] end end def has_error? @list.each { |res| return true if res.desc.error } false end end ## ## Fatal/Warning/Info results ## class Fatal < Processor def <<(result) super(result) raise FatalError unless result.ok? end def severity ; ZoneCheck::Config::Fatal ; end end class Warning < Processor def severity ; ZoneCheck::Config::Warning ; end end class Info < Processor def severity ; ZoneCheck::Config::Info ; end end class Ok < Processor def <<(result) @list << result @master.full_list << [ result, severity ] end def severity ; nil ; end def has_error? ; false ; end end def initialize(domain, rflag, publish) @domain = domain @rflag = rflag @publish = publish @full_list = [] @ok = Ok::new(self) @fatal = Fatal::new(self) @warning = Warning::new(self) @info = Info::new(self) @ns_list = [] @domain.ns.each {|name,ips| ips.each {|ip| @ns_list << name.to_s+"/"+ip.to_s } } end def finish if @rflag.one then display_one else display_std end end protected def display_one rtest, severity = nil, nil rtest, severity = @fatal.one, @fatal.severity unless rtest rtest, severity = @warning.one, @warning.severity unless rtest @publish.diagnostic1(@domain.name, @info.count, @info.has_error?, @warning.count, @warning.has_error?, @fatal.count, @fatal.has_error?, rtest, severity) end def display_std raise 'abstract method' end end end zonecheck-3.0.5/zc/report/000077500000000000000000000000001226210254100154125ustar00rootroot00000000000000zonecheck-3.0.5/zc/report/byhost.rb000066400000000000000000000042171226210254100172530ustar00rootroot00000000000000# $Id: byhost.rb,v 1.16 2010/06/07 08:51:26 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.16 $ # DATE : $Date: 2010/06/07 08:51:26 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'report' require 'config' module Report ## ## Sorting by 'host' ## class ByHost < Template def display_std # Sorting by 'host' byhost = {} full_list.each { |elt| res, severity = elt next if @rflag.fatalonly && severity != Config::Fatal next if severity.nil? && !@rflag.reportok tag = res.source byhost[tag] = [] unless byhost.has_key?(tag) byhost[tag] << elt } if !byhost.empty? @publish.diag_start() unless @rflag.quiet # Print 'generic' first gentag = $mc.get('word:generic') display(byhost[gentag], gentag) byhost.delete(gentag) # Print remaining 'host' byhost.keys.sort.each { |tag| display(byhost[tag], tag) } end @publish.status(@domain.name, @info.count, @warning.count, @fatal.count) end private def display(list, title) return if list.nil? || list.empty? if !@rflag.tagonly && !@rflag.quiet @publish.diag_section(title) end list.each { |res, severity| @publish.diagnostic(severity, res.testname, res.desc, [ res.source ]) } end end end zonecheck-3.0.5/zc/report/byseverity.rb000066400000000000000000000047101226210254100201460ustar00rootroot00000000000000# $Id: byseverity.rb,v 1.15 2010/06/21 09:34:44 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/08/02 13:58:17 # REVISION : $Revision: 1.15 $ # DATE : $Date: 2010/06/21 09:34:44 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require 'report' require 'config' module Report ## ## Sorting by severity ## class BySeverity < Template def display_std catlist = [] if !@rflag.fatalonly catlist << @ok if @rflag.reportok catlist << @info << @warning end catlist << @fatal allempty = true catlist.each { |e| allempty &&= e.empty? } if !allempty @publish.diag_start() unless @rflag.quiet catlist.each { |cat| display(cat.list, cat.severity) } end @publish.status(@domain.name, @info.count, @warning.count, @fatal.count) end private def display(list, severity) return if list.nil? || list.empty? if !@rflag.tagonly && !@rflag.quiet severity_tag = ZoneCheck::Config.severity2tag(severity) l10n_severity = $mc.get("word:#{severity_tag}") @publish.diag_section(l10n_severity) end nlist = list.dup while ! nlist.empty? # Get test result res = nlist.shift # Initialize whos = [ res.source ] desc = res.desc.clone testname = res.testname # Look for similare test results nlist.delete_if { |a| whos << a.source if ((a.testname == res.testname) && (a.desc == res.desc)) } # if whos.unsorted_eql?(@ns_list) # whos = [$mc.get('report:all_servers')] # end # Publish diagnostic @publish.diagnostic(severity, testname, desc, whos) end end end end zonecheck-3.0.5/zc/testmanager.rb000066400000000000000000000351061226210254100167430ustar00rootroot00000000000000# $Id: testmanager.rb,v 1.68 2010/06/14 11:47:54 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 02/08/02 13:58:17 # REVISION : $Revision: 1.68 $ # DATE : $Date: 2010/06/14 11:47:54 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'thread' require 'timeout' require 'time' require 'framework' require 'report' require 'cache' ## ## TODO: decide how to replace the Errno::EADDRNOTAVAIL which is not ## available on windows ## TODO: improved detection of dependencies issues ## ## attributs: param, classes, cm, config, tests class TestManager TestSuperclass = Test # Superclass TestPrefix = 'tst_' # Prefix for test methods CheckPrefix = 'chk_' # Prefix for check methods ## ## Exception: error in the test definition ## class DefinitionError < StandardError end # # List of loaded test files # (avoid loading the same file twice) # @@test_files = {} # # Load ruby files implementing tests # WARN: we are required to untaint for loading # WARN: file are only loaded once to avoid redefinition of constants # # To minimize risk of choosing a random directory, only files # that have the ruby extension (.rb) and the 'ZCTEST 1.0' # magic header are loaded. # def self.load(*filenames) count = 0 filenames.each { |filename| # Recursively load file in the directory if File.directory?(filename) $dbg.msg(DBG::LOADING) { "test directory: #{filename}" } Dir::open(filename) { |dir| dir.each { |entry| testfile = "#{filename}/#{entry}".untaint count += self.load(testfile) if File.file?(testfile) } } # Load test file elsif File.file?(filename) # Only load file if it meet some criteria (see above) if ((filename =~ /\.rb$/) && begin File.open(filename) { |io| io.gets =~ /^\#\s*ZCTEST\s+1\.0:?\W/ } rescue # XXX: Careful with rescue all false end) # Really load the file if it wasn't already done if ! @@test_files.has_key?(filename) $dbg.msg(DBG::LOADING) { "test file: #{filename}" } ::Kernel.load filename @@test_files[filename] = true count += 1 else $dbg.msg(DBG::LOADING) { "test file: #{filename} (already loaded)" } end end end } # Return the number of loaded file return count end # # Initialize a new object. # def initialize @tests = {} # Hash of test method name (tst_*) @checks = {} # Hash of check method name (chk_*) @classes = [] # List of classes used by the methods above @cache = Cache::new @cache.create(:test) end # # Add all the available classes that containts test/check methods # def add_allclasses # Add the test classes (they should have Test as superclass) [ CheckGeneric, CheckNameServer, CheckNetworkAddress, CheckExtra, CheckDNSSEC].each { |mod| mod.constants.each { |t| testclass = eval "#{mod}::#{t}" if testclass.superclass == TestSuperclass $dbg.msg(DBG::TESTS) { "adding class: #{testclass}" } self << testclass else $dbg.msg(DBG::TESTS) { "skipping class: #{testclass}" } end } } end # # Register all the tests/checks that are provided by the class 'klass'. # def <<(klass) # Sanity check (all test class should derive from Test) if ! (klass.superclass == TestSuperclass) raise ArgumentError, $mc.get('xcp_testmanager_badclass') % [ klass, TestSuperclass ] end # Inspect instance methods for finding methods (ie: chk_*, tst_*) klass.public_instance_methods(true).each { |method| case method # methods that represent a test when /^#{TestPrefix}(.*)/ testname = $1 if has_test?(testname) l10n_tag = $mc.get('xcp_testmanager_test_exists') raise DefinitionError, l10n_tag % [ testname, klass, @tests[testname] ] end @tests[testname] = klass # methods that represent a check when /^#{CheckPrefix}(.*)/ checkname = $1 if has_check?(checkname) l10n_tag = $mc.get('xcp_testmanager_check_exists') raise DefinitionError, l10n_tag % [ checkname, klass, @tests[checkname] ] end @checks[checkname] = klass end } # Add it to the list of classes # The class will be unique in the list otherwise the checking # above will fail with method defined twice. @classes << klass end # # Check if 'test' has already been registered. # def has_test?(testname) @tests.has_key?(testname) end # # Check if 'check' has already been registered. # def has_check?(checkname) @checks.has_key?(checkname) end # # # def wanted_check?(checkname, category) return true unless @param.test.categories @param.test.categories.each { |rule| if (rule[0] == ?! || rule[0] == ?-) negation, name = true, rule[1..-1] elsif (rule[0] == ?+) negation, name = false, rule[1..-1] else negation, name = false, rule end return !negation if name.empty? if ((name == category) || !(category =~ /^#{Regexp.escape(name)}:/).nil?) return !negation end } return false end # # Return check family (ie: generic, nameserver, address, extra, dnssec) # def family(checkname) klass = @checks[checkname] klass.name =~ /^((ZoneCheck::[^:]+)|([^:]+))/ eval("#{$1}.family") end # # Return list of available checks # def list @checks.keys end # # Use the configuration object ('config') to instanciate each # class (but only once) that will be used to perform the tests. # def init(config, cm, param, do_preeval=true) @config = config @param = param @publisher = @param.publisher.engine @objects = {} @cm = cm @do_preeval = do_preeval @cache.clear(:test) @iterer = { CheckExtra.family => proc { |bl| bl.call }, CheckGeneric.family => proc { |bl| bl.call }, CheckNameServer.family => proc { |bl| @param.domain.ns.each { |ns_name, | bl.call(ns_name) } }, CheckNetworkAddress.family => proc { |bl| @param.domain.ns.each { |ns_name, ns_addr_list| @param.network.address_wanted?(ns_addr_list).each { |addr| bl.call(ns_name, addr) } } }, CheckDNSSEC.family => proc { |bl| @param.domain.ns.each { |ns_name, ns_addr_list| @param.network.address_wanted?(ns_addr_list).each { |addr| bl.call(ns_name, addr) } } } } # Create new instance of the class @classes.each { |klass| @objects[klass] = klass.method('new').call(@param.network, @config, @cm, @param.domain) } end # # Perform unitary check # def check1(checkname, severity, ns=nil, ip=nil) # Build argument list # puts "checkname: #{checkname}" args = [] args << ns if !ns.nil? args << ip if !ip.nil? # Debugging $dbg.msg(DBG::TESTS) { where = args.empty? ? "generic" : args.collect{|e| e.to_s}.join('/') "checking: #{checkname} [#{where}]" } # Stat @param.info.testcount += 1 # Retrieve the method representing the check klass = @checks[checkname] object = @objects[klass] method = object.method(CheckPrefix + checkname) # Retrieve information relative to the test output sev_report = case severity when Config::Fatal then @param.report.fatal when Config::Warning then @param.report.warning when Config::Info then @param.report.info end # Publish information about the test being executed @publisher.progress.process(checkname, ns, ip) # Perform the test desc = Test::Result::Desc::new result_class = Test::Error begin starttime = Time::now exectime = nil begin data = method.call(*args) ensure exectime = Time::now - starttime end desc.details = data if data result_class = case data when NilClass, FalseClass, Hash then Test::Failed else Test::Succeed end rescue Dnsruby::NXDomain => e # TODO # info = "(#{e.resource.rdesc}: #{e.name})" name = $mc.get('resolv:rcode:nxdomain') desc.error = "#{name}: #{e.message}"# #{info}" rescue Dnsruby::ServFail => e # TODO # info = "(#{e.resource.rdesc}: #{e.name})" name = $mc.get('resolv:rcode:servfail') desc.error = "#{name}: #{e.message}" # #{info}" rescue Dnsruby::Refused => e # TODO # info = "(#{e.resource.rdesc}: #{e.name})" name = $mc.get('resolv:rcode:refused') desc.error = "#{name}: #{e.message}" # #{info}" rescue Dnsruby::NotImp => e # TODO # info = "(#{e.resource.rdesc}: #{e.name})" name = $mc.get('resolv:rcode:notimp') desc.error = "#{name}: #{e.message}" # #{info}" rescue Errno::EADDRNOTAVAIL desc.error = "Network transport unavailable try option -4 or -6" rescue Dnsruby::ResolvTimeout => e desc.error = "DNS Timeout" rescue Timeout::Error => e desc.error = "Timeout" rescue Dnsruby::ResolvError => e desc.error = "Resolver error (#{e.message})" rescue ZoneCheck::Mail::MailError => e desc.error = "Mail error (#{e})" rescue Exception => e # XXX: this is a hack # unless @param.rflag.stop_on_fatal # desc.error = 'Dependency issue? (allwarning/dontstop flag?)' # else desc.error = e.message # end raise if $dbg.enabled?(DBG::DONT_RESCUE) ensure $dbg.msg(DBG::TESTS) { resstr = result_class.to_s.gsub(/^.*::/, '') where = args.empty? ? 'generic' : args.collect{|e| e.to_s}.join('/') timestr = "%.2f" % exectime "result: #{resstr} for #{checkname} [#{where}] (in #{timestr} sec)" } end # Build result begin result = result_class::new(checkname, desc, ns, ip) sev_report << result rescue Report::FatalError raise if @param.rflag.stop_on_fatal end return result_class end # # Perform unitary test # def test1(testname, report=true, ns=nil, ip=nil) $dbg.msg(DBG::TESTS) { "test: #{testname}" } @cache.use(:test, [ testname, ns, ip ]) { # Retrieve the method representing the test klass = @tests[testname] object = @objects[klass] method = object.method(TestPrefix + testname) # Call the method args = [] args << ns unless ns.nil? args << ip unless ip.nil? begin method.call(*args) rescue Dnsruby::ResolvError => e return e unless report desc = Test::Result::Desc::new(false) desc.error = "Resolver error (#{e})" @param.report.fatal << Test::Error::new(testname, desc, ns, ip) end } end # # Perform all the tests as asked in the configuration file and # according to the program parameters # def check threadlist = [] testcount = 0 domainname_s = @param.domain.name.to_s starttime = Time::now exception = false # Stats @param.info.nscount = @param.domain.ns.size # Do a pre-evaluation of the code if @do_preeval # Sanity check for debugging if $dbg.enabled?(DBG::NOCACHE) raise 'Debugging with preeval and NOCACHE is not adviced' end # Do the pre-evaluation # => compute the number of checking to perform begin Config::TestSeqOrder.each { |family| next unless rules = @config.rules[family] @iterer[family].call(proc { |*args| testcount += rules.preeval(self, args) }) } rescue Instruction::InstructionError => e $dbg.msg(DBG::TESTS) { "disabling preeval: #{e}" } @do_preeval = false testcount = 0 end end # Perform the tests begin # Counter start @publisher.progress.start(testcount) # Perform the checking Config::TestSeqOrder.each { |family| next unless rules = @config.rules[family] threadlist = [] @iterer[family].call(proc { |*args| threadlist << Thread::new(Thread.current) { |parent| begin rules.eval(self, args) rescue Report::FatalError => e unless exception exception = true parent.raise Report::FatalError end rescue Exception => e # XXX: debuging parent.raise e end } }) threadlist.each { |thr| thr.join } } # Counter final status if @param.report.fatal.empty? then @publisher.progress.done(domainname_s) else @publisher.progress.failed(domainname_s) end rescue Report::FatalError threadlist.each {|thread| Thread.kill(thread) } if @param.report.fatal.empty? raise "BUG: FatalError with no fatal error stored in report" end @publisher.progress.failed(domainname_s) rescue => e threadlist.each {|thread| Thread.kill(thread) } raise e ensure # Counter cleanup @publisher.progress.finish # Total testing time @param.info.testingtime = Time::now - starttime end # Status @param.report.fatal.empty? end end endzonecheck-3.0.5/zc/zc.rb000077500000000000000000000211731226210254100150470ustar00rootroot00000000000000#!/usr/local/bin/ruby # $Id: zc.rb,v 1.127 2010/06/29 12:08:35 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/07/18 10:29:53 # REVISION : $Revision: 1.127 $ # DATE : $Date: 2010/06/29 12:08:35 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ## !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ## ## WARN: when editing this file on installed ZoneCheck, you should ## keep in mind that some ZoneCheck variant (cgi, ...) are ## more or less strongly connected with this file by: ## - a copy : only THIS file will be modified ## - a hardlink : depending of your editor behaviour when ## saving the file, all the files will hold ## the modification OR only this file will. ## - a symlink : no problem should occured (except if on Windows) ## ## !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ## --> CUSTOMIZATION <-- ############################################# # # You shouldn't really need to change these values: # - This is normally automatically done when performing a: make install # - Setting the environment variable ZC_INSTALL_PATH should be enough # for testing the code # ## Installation path ZC_INSTALL_PATH = (ENV['ZC_INSTALL_PATH'] || (ENV['HOME'] || '/homes/sdalu') + '/Repository/zonecheck').dup.untaint ## Directories ZC_DIR = "#{ZC_INSTALL_PATH}/zc" ZC_LIB = "#{ZC_INSTALL_PATH}/lib" ZC_CONFIG_DIR = ENV['ZC_CONFIG_DIR'] || "#{ZC_INSTALL_PATH}/etc/zonecheck" ZC_LOCALIZATION_DIR = ENV['ZC_LOCALIZATION_DIR'] || "#{ZC_INSTALL_PATH}/locale" ZC_TEST_DIR = ENV['ZC_TEST_DIR'] || "#{ZC_INSTALL_PATH}/test" ## Configuration ZC_CONFIG_FILE = ENV['ZC_CONFIG_FILE'] || 'zc.conf' ## Lang ZC_LANG_FILE = 'zc.%s' ZC_LANG_DEFAULT = 'en' # can have an enconding: en.ascii ## Message catalog fallback ZC_MSGCAT_FALLBACK = 'en' # don't specifie an encoding here ## Input methods ZC_DEFAULT_INPUT = 'cli' ZC_CGI_ENV_KEYS = [ 'GATEWAY_INTERFACE', 'SERVER_ADDR' ] ZC_CGI_EXT = 'cgi' ## Publisher ZC_HTML_PATH = ENV['ZC_HTML_PATH'] || "#{ZC_INSTALL_PATH}/www" ## Contact / Details ZC_COPYRIGHT = 'AFNIC (c) 2003' ZC_CONTACT = 'ZoneCheck ' ZC_MAINTAINER = 'Stephane D\'Alu ' ## Internal ZC_XML_PARSER = ENV['ZC_XML_PARSER'] ZC_IP_STACK = ENV['ZC_IP_STACK'] || '46' ## --> END OF CUSTOMIZATION <-- ###################################### # # Identification # ZC_CVS_NAME = %q$Name: ZC-3_0_5 $ ZC_NAME = 'ZoneCheck' ZC_VERSION = (Proc::new { n = ZC_CVS_NAME.split[1] n = /^ZC-(.*)/.match(n) unless n.nil? n = n[1] unless n.nil? n = n.gsub(/_/, '.') unless n.nil? n || '' }).call PROGNAME = File.basename($0) # # Constants # EXIT_OK = 0 # Everything went fine, no fatal error, domain ok EXIT_FAILED = 1 # The program completed but the result is negative EXIT_TIMEOUT = 2 # The program completed but the result is negative # due to timeout. EXIT_ABORTED = 3 # The user aborted the program before completion EXIT_ERROR = 4 # An error unrelated to the result occured EXIT_USAGE = 9 # The user didn't bother reading the man page # # Sanity check # m = /^(\d+)\.(\d+)\./.match(RUBY_VERSION) if (m[1].to_i <= 1) && (m[2].to_i < 8) $stderr.puts "#{PROGNAME}: ruby version 1.8.0 at least is required." exit EXIT_ERROR end # # Run at safe level 1 # A greater safe level is unfortunately not possible due to some # low level operations in the Dnsruby library # $SAFE = 0 # REXML BUG # # Ensure '.' is not one of the possible path (too much trouble) # Add zonecheck directories to ruby path # $LOAD_PATH.delete_if { |path| path == '.' } $LOAD_PATH << ZC_DIR << ZC_LIB # # Version / Name / Contact # $zc_version ||= ZC_VERSION $zc_name ||= ZC_NAME $zc_contact ||= ZC_CONTACT # # Config directory # $zc_config_dir ||= ZC_CONFIG_DIR $zc_config_file ||= ZC_CONFIG_FILE # # Custom # $zc_custom ||= 'zc-custom' # # Internal # $zc_xml_parser ||= ZC_XML_PARSER # Resolver configuration $rootserver_hintfile = "#{$zc_config_dir}/rootservers" # # Requierement # # Standard Ruby libraries require 'socket' # Modification to standard/core ruby classes require 'ext/array' require 'ext/file' require 'ext/myxml' # ZoneCheck component require 'locale' require 'msgcat' require 'console' require 'zonecheck' require 'dbg' # # Debugger object # (earlier initialization, can also be set via input interface) # $dbg = ZoneCheck::DBG::new $dbg.level = ENV['ZC_DEBUG'] if ENV['ZC_DEBUG'] # External libraries begin require 'dnsruby' rescue LoadError => e begin require 'rubygems' rescue LoadError => e $dbg.msg(ZoneCheck::DBG::INIT, "Unable to require rubygems (#{e})") $stderr.puts "ERROR: You have to install Dnsruby in order to execute ZoneCheck" exit EXIT_ERROR end begin require 'dnsruby' rescue LoadError => e $dbg.msg(ZoneCheck::DBG::INIT, "Unable to require dnsruby (#{e})") $stderr.puts "ERROR: You have to install Dnsruby in order to execute ZoneCheck" exit EXIT_ERROR end end if Dnsruby.version < 1.47 $dbg.msg(ZoneCheck::DBG::INIT, "Unable to require dnsruby (#{e})") $stderr.puts "ERROR: You have to install at least Dnsruby 1.47 in order to execute ZoneCheck" exit EXIT_ERROR end include ZoneCheck # # XML parser # ENV['XML_CATALOG_FILES'] = "#{ZC_DIR}/data/catalog.xml" $dbg.msg(DBG::INIT) { shrinked_path = File.shrink_path(ENV['XML_CATALOG_FILES'], ':') "Using XML_CATALOG_FILES=#{shrinked_path}" } $dbg.msg(DBG::INIT) { "Using XML parser: #{MyXML::Implementation}" } # # IPv4/IPv6 stack detection # WARN: doesn't implies that we have also the connectivity # $ipv4_stack = !(ZC_IP_STACK =~ /4/).nil? $ipv6_stack = !(ZC_IP_STACK =~ /6/).nil? $ipv4_stack = $ipv6_stack = true if !$ipv4_stack && !$ipv6_stack $ipv4_stack &&= begin UDPSocket::new(Socket::AF_INET).close true rescue NameError, # if Socket::AF_INET doesn't exist SystemCallError # for the Errno::EAFNOSUPPORT error false end $ipv6_stack &&= begin UDPSocket::new(Socket::AF_INET6).close true rescue NameError, # if Socket::AF_INET6 doesn't exist SystemCallError # for the Errno::EAFNOSUPPORT error false end # # Internationalisation # WARN: default locale is mandatory as no human messages are # present in the code (except for debugging purpose) # begin $supported_languages = ["en","fr"] # Initialize locale $locale = ZoneCheck::Locale::new $locale.lang = ZC_LANG_DEFAULT if $locale.lang.nil? # Initialize the console $console = Console::new # Initialize the message catalog $mc = MsgCat::new(ZC_LOCALIZATION_DIR, ZC_MSGCAT_FALLBACK) # Add watcher for notification of locale changes # ... and force update $locale.watch('lang', proc { $mc.language = $locale.language $mc.country = $locale.country $mc.reload } ) $locale.watch('encoding', proc { $console.encoding = $locale.encoding } ) $locale.notify('lang', 'encoding') # Read msgcat $mc.read(ZC_LANG_FILE) rescue => e raise if $dbg.enabled?(DBG::DONT_RESCUE) $stderr.puts "ERROR: #{e.to_s}" exit EXIT_ERROR end # # Load eventual custom version # begin require $zc_custom rescue LoadError => e $dbg.msg(DBG::INIT, "Unable to require '#{$zc_custom}' (#{e})") end # XXX ## Adjustement due to zc-custom ## #begin # hintfile = "#{$zc_config_dir}/rootservers" # if $rootserver_hintfile != hintfile # NResolv::DNS::RootServer.current = NResolv::DNS::RootServer.from_hintfile(hintfile) # end #rescue YAML::ParseError, SystemCallError => e # $dbg.msg(DBG::INIT, # "Unable to read/parse rootserver hint file (#{e})") #end # # Check it now! # exit ZoneCheck::ZoneCheck::new::start ? EXIT_OK : EXIT_FAILED zonecheck-3.0.5/zc/zonecheck.rb000066400000000000000000000236661226210254100164120ustar00rootroot00000000000000# $Id: zonecheck.rb,v 1.25 2010/06/25 08:37:43 chabannf Exp $ # # CONTACT : zonecheck@nic.fr # AUTHOR : Stephane D'Alu # # CREATED : 2002/07/18 10:29:53 # REVISION : $Revision: 1.25 $ # DATE : $Date: 2010/06/25 08:37:43 $ # # CONTRIBUTORS: (see also CREDITS file) # # # LICENSE : GPL v3 # COPYRIGHT : AFNIC (c) 2003 # # This file is part of ZoneCheck. # # ZoneCheck is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # ZoneCheck 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 ZoneCheck; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # module ZoneCheck require 'config' require 'param' require 'cachemanager' require 'testmanager' ## ## ## class ZoneCheck # # Input method # (pseudo parameter: --INPUT=xxx) # def self.input_method im = nil # Input Method # Check meta argument ARGV.delete_if { |a| im = $1 if remove = a =~ /^--INPUT=(.*)/ remove } # Check environment variable ZC_INPUT im ||= ENV['ZC_INPUT'] # Try autoconfiguration is_cgi = false ZC_CGI_ENV_KEYS.each {|k| is_cgi = true unless ENV[k].nil?} im ||= if is_cgi || (PROGNAME =~ /\.#{ZC_CGI_EXT}$/) then "cgi" else ZC_DEFAULT_INPUT end # Sanity check on Input Method if ! (im =~ /^\w+$/) l10n_error = $mc.get('word:error').upcase l10n_input = $mc.get('input:suspicious_method') % [ im ] $console.stderr.puts "#{l10n_error}: #{l10n_input}" exit EXIT_ERROR end im = im.dup.untaint # object can be frozen, so we need to dup it # Instanciate input method begin require "input/#{im}" rescue LoadError => e $dbg.msg(DBG::INIT, "Unable to require \"input/#{im}\": #{e}") l10n_error = $mc.get('word:error').upcase l10n_input = $mc.get('input:unsupported_method') % [ im ] $console.stderr.puts "#{l10n_error}: #{l10n_input}" exit EXIT_ERROR end input = eval "Input::#{im.upcase}::new" $dbg.msg(DBG::INIT, "Input method: '#{im}', new input object created: <#{input.class}>") return input end def initialize @input = nil @param = nil @test_manager = nil @testlist = nil end def start begin # Input method selection @input = ZoneCheck.input_method # Initialize parameters (from command line parsing) argv_backup = ARGV.clone @param = Param::new @input.usage(EXIT_USAGE) unless @input.parse(@param) @param.preconf.autoconf # Load the test implementation TestManager.load(@param.preconf.testdir) # Create test manager @test_manager = TestManager::new @test_manager.add_allclasses # Load configuration @config = Config::new(@test_manager) @config.load(@param.preconf.cfgfile) @config.validate(@test_manager) @config.profilename = @param.preconf.profile # Preset if @input.allow_preset presetname = @param.preconf.preset if !presetname.nil? && @config.presets[presetname].nil? raise Config::ConfigError, $mc.get('config:unknown_preset') % presetname end presetname ||= Config::Preset_Default if preset = @config.presets[presetname] $dbg.msg(DBG::INIT) { "Using preset '#{preset.name}' (reloading parameters)"} # Create new argument @param = Param::new # Load preset begin # Can be reverted [ 'verbose', 'transp', 'output', 'error' ].each { |opt| @param.send("#{opt}=",preset[opt]) if preset[opt] } # Cannot be reverted @param.rflag.quiet = true if preset['quiet'] @param.rflag.one = true if preset['one' ] rescue Param::ParamError => e raise Config::ConfigError, ($mc.get('config:error_in_preset') % presetname) + " (#{e.message})" end # Restart argument parsing ARGV.replace(argv_backup) @input.restart @input.usage(EXIT_USAGE) unless @input.parse(@param) end end # Interaction unless @input.interact(@param, @config, @test_manager) exit EXIT_ABORTED end # Test selection @config.overrideconf(@param.test.tests) if @param.test.tests # Do the job success = if @param.test.list then print_testlist elsif @param.test.desctype then print_testdesc else do_check end # Everything fine? return success rescue Param::ParamError => e @input.error(e.to_s, EXIT_ERROR) rescue Config::SyntaxError => e @input.error("%s %d: %s\n\t(%s)" % [ $mc.get('word:line').capitalize, e.line, e.to_s, e.path ], EXIT_ERROR) rescue Config::ConfigError => e @input.error(e.to_s, EXIT_ERROR) rescue => e raise if $dbg.enabled?(DBG::DONT_RESCUE) @input.error(e.to_s, EXIT_ERROR) ensure # exit() raise an exception ensuring that the following code # is executed destroy end # NOT REACHED end def destroy end #-- zonecheck --------------------------------------------------------- def do_check param_config_preamble # Begin formatter @param.publisher.engine.begin # success = true begin cm = CacheManager::create(@param.resolver.local) cm.domain_name = @param.domain.name.to_s retry_times = @config.constants.fetch('dnsruby:retrytimes').to_i retry_delay = @config.constants.fetch('dnsruby:retrydelay').to_i query_timeout = @config.constants.fetch('dnsruby:querytimeout').to_i cm.init(@param.edns, @param.network.query_mode, retry_times, retry_delay, query_timeout) param_config_data @param.domain.ns.each { |ns_name, ns_addr_list| @param.network.address_wanted?(ns_addr_list).each { |addr| cm[addr] } } success = zc(cm) rescue Param::ParamError => e @param.publisher.engine.error(e.message) success = false end # End formatter @param.publisher.engine.end # return success end def param_config_preamble @param.rflag.autoconf @param.option.autoconf @param.publisher.autoconf(@param.rflag, @param.option) @param.network.autoconf @param.resolver.autoconf @param.test.autoconf end def param_config_data @param.info.clear @param.info.autoconf @param.publisher.engine.info = @param.info @param.domain.autoconf(@param.resolver.local) @param.report.autoconf(@param.domain, @param.rflag, @param.publisher.engine) end def zc(cm) starttime = Time::now # Setup publisher (for the domain) @param.publisher.engine.setup(@param.domain.name) # Retrieve specific configuration if (cfg = @config.profile(@param.domain.name)).nil? l10n_error = $mc.get('input:unsupported_domain') @param.publisher.engine.error(l10n_error % @param.domain.name) return false end @param.info.profile = [ cfg.name, cfg.longdesc ] @param.publisher.engine.constants = cfg.constants # Display intro (ie: domain and nameserver summary) @param.publisher.engine.intro(@param.domain) # Initialise and check @test_manager.init(cfg, cm, @param) status = @test_manager.check # Finish diagnostic (in case of pending output) @param.report.finish # Lastaction hook lastaction(status) # Return status return status end def lastaction(status) end #-- testlist ---------------------------------------------------------- # # Print the list of available tests # XXX: should use publisher # def print_testlist @param.test.autoconf @test_manager.list.sort.each { |testname| $console.stdout.puts testname } true end #-- testdesc ---------------------------------------------------------- # # Print the description of the tests # If no selection is done (option -T), the description is # printed for all the available tests # XXX: should use other publisher than text # def print_testdesc require 'publisher/text' @param.publisher.engine = ::Publisher::Text param_config_preamble list = @param.test.tests || @test_manager.list.sort publisher = @param.publisher.engine profilename = @config.profilename publisher.constants = (@config.profiles[profilename] || @config).constants publisher.begin list.each { |test| publisher.testdesc(test, @param.test.desctype) } publisher.end true end end end