From e8b6bae449360cacc68c78c270af3fa9d25a1045 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Sun, 9 Aug 2015 16:51:58 +0800 Subject: [PATCH 01/33] Initial Commit --- .cproject | 49 + .project | 27 + AUTHORS | 6 + COPYING | 280 ++++ ChangeLog | 898 ++++++++++++ FAQ | 488 +++++++ Makefile.am | 53 + NEWS | 116 ++ README | 16 + README.openwrt | 96 ++ autogen.sh | 65 + configure.in | 105 ++ contrib/airos/wifidog/Makefile | 70 + contrib/airos/wifidog/files.patch | 87 ++ contrib/airos/wifidog/files/wifidog.conf | 253 ++++ contrib/airos/wifidog/files/wifidog.init | 27 + .../wifidog/patches/100-counter_outoing.patch | 24 + contrib/airos/wifidog/readme.txt | 43 + contrib/build-deb/changelog | 14 + contrib/build-deb/control | 15 + contrib/build-deb/rules | 74 + .../wifidog/Makefile | 62 + .../wifidog/files/wifidog.conf | 246 ++++ .../wifidog/files/wifidog.init | 18 + .../wifidog/Makefile | 60 + .../wifidog/files/wifidog.conf | 246 ++++ .../wifidog/files/wifidog.init | 17 + .../wifidog/Config.in | 16 + .../wifidog/Makefile | 65 + .../wifidog/files/wifidog.conf | 246 ++++ .../wifidog/files/wifidog.init | 15 + .../wifidog/ipkg/wifidog.conffiles | 1 + .../wifidog/ipkg/wifidog.control | 8 + contrib/dump_fw.sh | 5 + doc/Makefile.am | 52 + doc/README.developers.txt | 37 + doc/doxygen.cfg.in | 1294 +++++++++++++++++ doc/wifidog_firewall_diagram.dia | Bin 0 -> 8702 bytes libhttpd/Makefile.am | 19 + libhttpd/README | 23 + libhttpd/api.c | 1067 ++++++++++++++ libhttpd/httpd.h | 250 ++++ libhttpd/httpd_priv.h | 83 ++ libhttpd/ip_acl.c | 224 +++ libhttpd/protocol.c | 791 ++++++++++ libhttpd/version.c | 23 + scripts/Copy of white_black_flush.sh | 95 ++ scripts/Copy of white_black_flush.sh~ | 95 ++ scripts/GET_settings | 48 + scripts/GET_settings~ | 48 + scripts/conf/dog_post_conf | 9 + scripts/conf/wifidog_conf | 73 + scripts/dog_conf_generator.sh | 167 +++ scripts/init.d/wifidog | 201 +++ scripts/white_black_flush.sh | 95 ++ scripts/white_black_flush.sh~ | 95 ++ scripts/wifidog | 21 + scripts/wifidog.init | 104 ++ src/Makefile.am | 61 + src/auth.c | 224 +++ src/auth.h | 61 + src/centralserver.c | 446 ++++++ src/centralserver.h | 63 + src/client_list.c | 258 ++++ src/client_list.h | 100 ++ src/commandline.c | 180 +++ src/commandline.h | 33 + src/common.h | 33 + src/conf.c | 1044 +++++++++++++ src/conf.h | 244 ++++ src/debug.c | 76 + src/debug.h | 38 + src/firewall.c | 424 ++++++ src/firewall.h | 70 + src/fw_iptables.c | 720 +++++++++ src/fw_iptables.h | 82 ++ src/gateway.c | 573 ++++++++ src/gateway.h | 33 + src/get_clientinfo.c | 443 ++++++ src/get_clientinfo.h | 89 ++ src/get_devinfo.c | 459 ++++++ src/get_devinfo.h | 119 ++ src/get_remote_shell.c | 212 +++ src/get_remote_shell.h | 35 + src/http.c | 331 +++++ src/http.h | 50 + src/httpd_thread.c | 75 + src/httpd_thread.h | 33 + src/ping_thread.c | 284 ++++ src/ping_thread.h | 35 + src/safe.c | 110 ++ src/safe.h | 56 + src/shell_command.h | 53 + src/util.c | 544 +++++++ src/util.h | 79 + src/wdctl.c | 327 +++++ src/wdctl.h | 43 + src/wdctl_thread.c | 401 +++++ src/wdctl_thread.h | 37 + wifidog-msg.html.in | 107 ++ wifidog.conf | 281 ++++ wifidog.spec.in | 69 + 102 files changed, 17760 insertions(+) create mode 100644 .cproject create mode 100644 .project create mode 100755 AUTHORS create mode 100755 COPYING create mode 100755 ChangeLog create mode 100755 FAQ create mode 100755 Makefile.am create mode 100755 NEWS create mode 100755 README create mode 100755 README.openwrt create mode 100755 autogen.sh create mode 100755 configure.in create mode 100755 contrib/airos/wifidog/Makefile create mode 100755 contrib/airos/wifidog/files.patch create mode 100755 contrib/airos/wifidog/files/wifidog.conf create mode 100755 contrib/airos/wifidog/files/wifidog.init create mode 100755 contrib/airos/wifidog/patches/100-counter_outoing.patch create mode 100755 contrib/airos/wifidog/readme.txt create mode 100755 contrib/build-deb/changelog create mode 100755 contrib/build-deb/control create mode 100755 contrib/build-deb/rules create mode 100755 contrib/build-openwrt-kamikazeipk/wifidog/Makefile create mode 100755 contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf create mode 100755 contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init create mode 100755 contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile create mode 100755 contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf create mode 100755 contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init create mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/Config.in create mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/Makefile create mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf create mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init create mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles create mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control create mode 100755 contrib/dump_fw.sh create mode 100755 doc/Makefile.am create mode 100755 doc/README.developers.txt create mode 100755 doc/doxygen.cfg.in create mode 100755 doc/wifidog_firewall_diagram.dia create mode 100755 libhttpd/Makefile.am create mode 100755 libhttpd/README create mode 100755 libhttpd/api.c create mode 100755 libhttpd/httpd.h create mode 100755 libhttpd/httpd_priv.h create mode 100755 libhttpd/ip_acl.c create mode 100755 libhttpd/protocol.c create mode 100755 libhttpd/version.c create mode 100644 scripts/Copy of white_black_flush.sh create mode 100644 scripts/Copy of white_black_flush.sh~ create mode 100755 scripts/GET_settings create mode 100755 scripts/GET_settings~ create mode 100644 scripts/conf/dog_post_conf create mode 100644 scripts/conf/wifidog_conf create mode 100644 scripts/dog_conf_generator.sh create mode 100755 scripts/init.d/wifidog create mode 100644 scripts/white_black_flush.sh create mode 100644 scripts/white_black_flush.sh~ create mode 100644 scripts/wifidog create mode 100644 scripts/wifidog.init create mode 100755 src/Makefile.am create mode 100755 src/auth.c create mode 100755 src/auth.h create mode 100755 src/centralserver.c create mode 100755 src/centralserver.h create mode 100755 src/client_list.c create mode 100755 src/client_list.h create mode 100755 src/commandline.c create mode 100755 src/commandline.h create mode 100755 src/common.h create mode 100755 src/conf.c create mode 100755 src/conf.h create mode 100755 src/debug.c create mode 100755 src/debug.h create mode 100755 src/firewall.c create mode 100755 src/firewall.h create mode 100755 src/fw_iptables.c create mode 100755 src/fw_iptables.h create mode 100755 src/gateway.c create mode 100755 src/gateway.h create mode 100644 src/get_clientinfo.c create mode 100644 src/get_clientinfo.h create mode 100644 src/get_devinfo.c create mode 100644 src/get_devinfo.h create mode 100644 src/get_remote_shell.c create mode 100644 src/get_remote_shell.h create mode 100755 src/http.c create mode 100755 src/http.h create mode 100755 src/httpd_thread.c create mode 100755 src/httpd_thread.h create mode 100755 src/ping_thread.c create mode 100755 src/ping_thread.h create mode 100755 src/safe.c create mode 100755 src/safe.h create mode 100644 src/shell_command.h create mode 100755 src/util.c create mode 100755 src/util.h create mode 100755 src/wdctl.c create mode 100755 src/wdctl.h create mode 100755 src/wdctl_thread.c create mode 100755 src/wdctl_thread.h create mode 100755 wifidog-msg.html.in create mode 100755 wifidog.conf create mode 100755 wifidog.spec.in diff --git a/.cproject b/.cproject new file mode 100644 index 00000000..e2b2aaa0 --- /dev/null +++ b/.cproject @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 00000000..7785dd6f --- /dev/null +++ b/.project @@ -0,0 +1,27 @@ + + + wifidog-20140822 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 00000000..52177b0c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,6 @@ +$Id$ + +Philippe April +Mina Naguib +Benoit Grégoire +Alexandre Carmel-Veilleux diff --git a/COPYING b/COPYING new file mode 100755 index 00000000..c7aea189 --- /dev/null +++ b/COPYING @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/ChangeLog b/ChangeLog new file mode 100755 index 00000000..31f0cc7f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,898 @@ +# $Id$ +2015-07-13 + * add get_clientinfo.h get_clientinfo.c +2015-07-09 + * add shell_command.h + * add get_devinfo.h get_devinfo.c +2014-05-13 + * libhttpd crash on invalid HTTP headers (second part of the patch) by Benoit GrĂ©goire +2013-08-21 + * add support for DROP target for firewall rules by Champtar +2013-06-14 + * add support for log, ulog target for firewall rules by jean-philippe menil and florida +2013-05-31 + Add transparent proxy support (via iptables REDIRECT) by Champtar (inspired by FFW team) +2012-05-30 + * Add many const by champtar + * Send http 302 instead of 307 by champtar + * Suppress all compilation warnings by champtar + * Add transparent proxy support (via iptables REDIRECT) +2012-08-28 + * Fix #836, buffer overflow on long urls reported by Etienne CHAMPETIER + * Fix #835, segfaults reported by Etienne CHAMPETIER +2009-11-03 + * Fix #625, does not display failure notice when quiet is set to true + * Fix #587, change index and rindex to strchr and strrchr + * Fix #548, trim leading spaces of the config file's options + +2009-09-28 Benoit GrĂ©goire + * Fix #471, patch by wichert + +2009-09-25 Geneviève Bastien + * Release 20090925 + * Update contrib Makefiles + +2009-09-17 Geneviève Bastien + * Documented #537 + * Fixed #472, patch by Jean-Philippe Menil + * Fixed #515, using the gateway interface instead of the gateway id in the iptables chain + +2009-07-02 Benoit GrĂ©goire + * Re-fix #505, #525 and fix #584, sorry about that. + +2009-06-26 Benoit GrĂ©goire + * Fix #518 + +2009-02-27 Benoit GrĂ©goire + * Fix #488 and #493 (arp_get() in firewall.c couldn't parse lowercase mac's from /proc/net/arp) with patch from jch@pps.jussieu.fr. Otherwise wifidog wouldn't work with recent openwrt and Ubuntu. + * Fix #525 + +2008-09-30 Wichert Akkerman + * Add exitcode to iptables failure errors. + * Include the gw_id in auth server updates so the client does not have + to keep track of it in a session. + * Include the gateway id in the firewall table names. Fixes ticket #466 + * URL encode the token before transmitting (it was already decoded). + Fixes ticket #473 + * Clean up compiler warnings. + * Security: strncpy may not NUL-terminate strings, so enforce this + ourselves. Fixes ticket #464 + * Make it possible to protect the status page. Fixes ticket #463. + +2008-07-20 Alexandre Carmel-Veilleux + * src/util.c: Fixed #include bug that caused segfaults on newer Linux + +2008-04-21 Alexandre Carmel-Veilleux + * Integrated patch #452 from Wichert Akkerman : Add const to function arguments in libhttpd to enforce more type checking and prevent certain class of problems. + * Compatiblity fix: Libhttpd assumes that type u_int is defined. Added an #ifndef/#include pair to httpd.h to make sure that assertion is true. + * Integrated patch #453 from Wichert Akkerman : Add configurable html to wifidog error messages. This has been a long-requested feature. + +2008-04-13 Benoit GrĂ©goire + * contrib/build-openwrt-kamikazeipk/wifidog/Makefile: Add iptables userspace dependencies + * Release 1.1.5 + +2008-03-24 Benoit GrĂ©goire + * Integrate with OpenWRT kamikaze build system + +2007-11-01 Benoit GrĂ©goire + * Apply portability patches by David Young . These have been reviewed, but not tested. + +2007-10-18 Benoit GrĂ©goire + * fw_iptables.c: From Philippe April: reverted change made in 1241 so we properly remove the entry from mangle.WiFiDog_Incoming when kicking out users, it was affecting statistics + * Update doxygen.cfg.in for latest version and to fix path ambiguity during make dist. + * Release 1.1.4 + +2007-07-06 Benoit GrĂ©goire + * Makefile.am: Slight change in make ipk tagrget. It seems that sometimes builddir isn't defined. srcdir works just as well in this case. + +2007-06-27 Benoit GrĂ©goire + * util.c: Fix while loop initialisation bug + * conf.h: Forgot to change the value of NUM_EXT_INTERFACE_DETECT_RETRY to actually make it wait forever. + * Remove hardcoded authserver paths. Can now be defined in the config file (auth server section). + * Centralise browser redirect code to simplify code + * Add manual logout URL, based in part on work by David Bird + * Release 1.1.3 final + +2007-06-24 Benoit GrĂ©goire + * Close #321: Make the Gateway retry forever if it cannot find it's interface. You never know when someone may finally replug the network cable or something... + * Close #332: Apply patch from Laurent Marchal. biguphpcgmailcom + * fw_iptables.c: Fix error in iptables_fw_access(). Rules were created as ACCEPT instead of DROP + * firewall.c: Fix bug in fw_sync_with_authserver(). The traffic for the validation period of a user who validated his account while connected wouldn't get counted. + * doc/wifidog_firewall_map.dia: At long last, full documentation of the firewall. We would have avoided a lot of stupid mistakes if we produced that sooner. + * Release 1.1.3_rc1 + +2007-05-24 Benoit GrĂ©goire + * wdctl_thread.c: Fix #324, again. Credit goes to Medea, I misunderstood his instructons. + * From David Bird libhttpd/: Fix #266 - don't process query string parameters and keep them in that request.path. + +2007-05-18 Benoit GrĂ©goire + * wdctl_thread.c: Fix #324 + +2007-04-26 Benoit GrĂ©goire + * wifidog.conf: Improve comments and add examples of blocking access to the upstream LAN. + +2007-04-26 Benoit GrĂ©goire + * conf.h: The DEFAULT_CHECKINTERVAL was 5 instead of 60 (as stated in the config file) which caused huge needless load on the auth servers, and needless ping traffic towards the clients if it wasn't manually set. + +2007-04-09 Benoit GrĂ©goire + * Makefile.am: Slight path fix when using building make ipk. Tell me if you have trouble with this + +2007-01-06 Benoit GrĂ©goire + * contrib/ Add contrib dir to collect the scripts and other code distributed with, but not really part of wifidog. + * Include the scripts used to build a ipkg on Openwrt RC6 and 0.9 + * Modify the build system to finally be able to build wifidog directly from the wifidog directory using the same files + used to make the official .ipk, without having to copy ANYTHNG to the openwrt SDK. + At last, there is now a new target: make ipk make ipk OPENWRTSDK=path_to_openwrt_sdk + * ipk/ Removed the obsolete OpenWRT RC4 scripts + * README.openwrt: Update + * scripts/openwrt/ remove obsolete dir. + * contrib/dump_fw.sh: Convenience script for firewall debugging. + +2007-01-06 Benoit GrĂ©goire + * Documentation update in the code + * Released 1.1.3_beta6 + +2006-10-26 Benoit GrĂ©goire + * src/conf.h: Fix #238 by using $sysconfdir to compute the default config-file location. + +2006-10-08 Alexandre Carmel-Veilleux + * Changed my email in a few files. + * Broken down some printf's on multiple lines. + * Added comments. + +2006-09-14 Benoit GrĂ©goire + * src/util.c, src/conf.h: Fix autodectection of the External interface if not specified in the config file. If the interface (typically pppoe) wasn't yet fully up when wifidog starts, wifidog would stop every connection from going trough. It will now retry every second for up to two minutes, and then exit with a fatal error if it can't successfully detect it. + +2006-02-23 Philippe April + * src/fw_iptables.c: + * Changed order in the filter.FORWARD chain + * Added TCPMSS rule + * Fixed deleting the rules on shutdown + * Fixed wdctl reset problem + * Released 1.1.3_beta4 + +2006-02-06 Benoit GrĂ©goire + * src/fw_iptables.c: Fix deleting the rules on shutdown. + +2006-01-31 Benoit GrĂ©goire + * Release 1.1.3_beta2 + +2006-01-31 Benoit GrĂ©goire + * src/fw_iptables.c: Add the global ruleset to the nat table to fix #65. + Add the table parameter to iptables_load_ruleset() and iptables_compile + * libhttpd/protocol.c: Fix pointer type mismatch + * src/conf.c,h: Remove deprecated option AuthServMaxTries (which was already ignored anyway. + +2006-01-23 Benoit GrĂ©goire + * src/conf.h: Fix the value of DEFAULT_AUTHSERVPATH and completely wrong code comment. Not the default indicated in the config file and the define are in sync. + +2006-01-17 Mina Naguib + * Ingisgnificant cleanup of CVS artifacts after svn migration + +2005-11-24 Philippe April + * Bad idea + +2005-11-01 Max Horvath + * Added .project to .cvsignore + +2005-11-01 Philippe April + * Added OPTIONS section in wifidog-init (example: enable syslog) + +2005-10-09 Philippe April + * Changed html pages, added info to wdctl status + +2005-10-07 Philippe April + * Released 1.1.3_beta1 + +2005-10-03 Philippe April + * libhttpd: Fixed two bugs parsing the GET query string making wifidog segfault + +2005-09-24 Mina Naguib + * New wdctl command "restart" which will get wifidog to restart itself + while preserving the existing clientlist. Perfect for 0-downtime + upgrading! + * safe.c: New safe_fork that croaks if the fork fails, also takes care of + closing some global file descriptors for the child + * debug.c: Now also logs the PID as part of every entry + * gateway.c: Handler for SIGCHLD now waitpid()s with WNOHANG flag to prevent deadlock + when the handler is called and another wait() or waitpid() is used + * util.c: execute() now uses waitpid() instead of wait() to reap only the child + it fork/executed + * Extra debugging entries throughout code + +2005-09-24 Mina Naguib + * conf.c: Pre-emptive bugfix - harsh lockdown of parsing trusted MAC + addresses from config file + +2005-09-24 Philippe April + * (finally) Added {Saul Albert,Jo Walsh,Schuyler}'s patch (thank you!) to send + the GW interface's mac address as the node_id if no node_id is specified. It allows + the use of generic configuration files without the need to hardcode the + node_id in. + * Added TrustedMACList configuration variable which allows specifying + MAC addresses which are allowed to go through without authentication. + * Updated OpenWrt instructions. + +2005-09-08 Philippe April + * Added compile instructions and installation for OpenWrt Whiterussian-rc2 + * Released 1.1.2 + +2005-05-30 Mina Naguib + * New wdctl command "restart" which will get wifidog to restart itself while preserving the existing clientlist. Perfect for 0-downtime upgrading! + * safe.c: New safe_fork that croaks if the fork fails, also takes care of closing some global file descriptors for the child + * debug.c: Now also logs the PID as part of every entry + * gateway.c: Handler for SIGCHLD now waitpid()s with WNOHANG flag to prevent deadlock when the handler is called and another wait() or waitpid() is used + * util.c: execute() now uses waitpid() instead of wait() to reap only the child it fork/executed + * Extra debugging entries throughout code + +2005-05-24 Mina Naguib + * wdctl.c: Minor bugfix pointed out by David Vincelli: When an invalid + command is given to wdctl, the error message showed "Invalid command: + wdctl" instead of the actual command supplied + +2005-05-23 Philippe April + * Released 1.1.2_pre1 + +2005-05-23 Mina Naguib + * fw_uptables.c: When appending call to chain WiFiDog_Outgoing from + nat.prerouting, add it via -A (at end) instead of -I 1 (at beginning) to + allow for existing nat forwarding. + +2005-05-16 Mina Naguib + * centralserver.c: read()s from central server in auth_server_request() are + now timed-out (via select). This is hopefully a bugfix to the + thread-freezing problem. + +2005-05-06 Mina Naguib + * Bugfix non-RFC compliant HTTP requests using \n instead of \r\n as line + terminations as per email from ludocornut@users.sourceforge.net + +2005-04-28 Philippe April + * Released 1.1.2_beta2 + +2005-04-28 Mina Naguib + * wifidog.conf: Make the default ruleset for validating users = allow all + (except sending SMTP) + +2005-04-20 Philippe April + * fw_iptables.c: Insert ourselves at the end of filter.FORWARD instead of + at the beginning since important FW instructions are located there on the + WRT54Gs when used with some DSL providers and we never execute them + otherwise. + * Released 1.1.2_beta1 + +2005-04-03 Philippe April + * Fixed issue with FAQ + * ipkg/rules: If autogen.sh doesn't exist, it's ok. 'configure' will. + +2005-04-01 Philippe April + * Duplicated auth server list in NAT table to fix the issue + of using an auth server on port 80, since port 80 was being systematically + redirected to 2060 otherwise. + * Released 1.1.1 + +2005-03-29 Mina Naguib + * Added FAQ document copied from wiki + +2005-03-22 Philippe April + * Released 1.1.0 + +2005-03-20 Mina Naguib + * More verbose debugging output + +2005-03-12 Mina Naguib + * More debugging output + * Document ugly hack involving tid_fw_thread + * SIGPIPE now ignored (as it's comment said) instead of being sent to the + handler for SIGCHLD + * Bugfix firewall destruction not happening from termination handler - had + to move explicit thread kills after, not before, firewall destruction + +2005-03-11 Mina Naguib + * If external interface was unspecified in the conf file, try to determine + it from the default route + * If external interface is known, specify it in the trigger rule in + nat.PREROUTING to prevent the rule from matching traffic inbound to the + router itself. This should fix the issue raised by Philippe and Pascal on + the mailing list + * Bugfix: UNDO ABOVE 2 ITEMS. Aparently you cannot use the "-o" iptables + option in nat.PREROUTING which makes knowing external_interface useless + * Added new chain in nat.PREROUTING that explicitly allows all traffic to + the router's internal IP from the internal interface, effectively + addressing the same above problem + +2005-03-07 Mina Naguib + * auth.c: Got rid of legacy _http_output and _http_redirect - replaced them + with libhttpd functions and http_wifidog_header/http_wifidog_footer + * auth.c: When re-directing to auth server now respects SSL setting instead + of always http+port 80 + * auth.c: Better debugging output of what it's doing when it acts on auth + server response + * A little bit more care with buffers and their sizes + * Minor whitespace tweaking and a couple of internal doc typo fixes + +2005-03-06 Mina Naguib + * Check return values of pthread_create + * Internal documentation touch-ups + * auth.c: Bugfix invalid http header sent by _http_output + * Bugfix traffic counter read from iptables as long int instead of long + long int + * Minor insignificant code touch-ups: + * Replace pthread_mutex_lock/unlock calls with appropriate + LOCK_FOO/UNLOCK_FOO macros for consistency + * Lock first before using some variables, not after + * Indentation adjustments + +2005-03-04 Mina Naguib + * Bugfix huge uptime pointed out to be by Philippe - was caused when the + date is set (with ntpclient for example) after wifidog starts + * Beautified "Uh oh!" apology screens and redirection screen + +2005-03-02 Alexandre Carmel-Veilleux + * Ifdef'd out the bits that are Linux specific if __linux__ is not + defined. + +2005-03-01 Mina Naguib + * Minor visual tweaks to the web interface + +2005-03-01 Philippe April + * Tagged v1_1_0_beta3 + +2005-02-28 Mina Naguib + * Do not update the last_updated field on incoming traffic - update it on + outgoing traffic only. This should be a much more reliable indication of + client no longer being there + * WifiDog status is now viewable with a web browser at + http://ip:port/wifidog/status + * Added new web hook for http://ip:port/wifidog + * Beautified web interface at http://ip:port/wifidog/* + +2005-02-24 Mina Naguib + * auth_server_request now returns AUTH_ERROR on error instead of AUTH_VALIDATION_FAILED + * centralserver.c: Fix typo (was =+, made it +=) that made the response + from the auth server corrupted in memory if the entire response would not + fit in 1 packet and retrieved with 1 read() call + * Better logging of details and calling of mark_* (auth+online/offline) + +2005-02-22 Philippe April + * Tagged v1_1_0_beta2 + +2005-02-20 Mina Naguib + * New safe.c with safe_malloc, safe_strdup, safe_asprintf and + safe_vasprintf with propper logging and exit when error. Replaced all + instances of original with safe versions in all files + * Fix memory leak in iptables_fw_counters_update + * Partial merge from CaptiveDNS branch: Consolidated much of the networking + calls to the auth servers into a magical function called connect_auth_server() + that's responsible for dns lookup, connecting, marking servers bad, marking + online/auth_online, and refreshing the firewall rules. + * Partial merge from CaptiveDNS branch: Added new functions mark_auth_online(), + mark_auth_offline() and is_auth_online() - similar in nature to is_online() + etc. except tailored to decide on auth servers status - currently being called by + connect_auth_server() + * Partial merge from CaptiveDNS branch: Different apology in 404 handler + depending on whether internet is down or just auth server is down + * Partial merge from CaptiveDNS branch: wdctl status now shows status of + is_online and is_auth_online + * Fixed several inconsistencies regarding the parity and size of + incoming/outgoing counters. Standardized on "unsigned long long int" in + declarations and *printf/*scanf formats + +2005-02-16 Philippe April + * ipkg/rules - When we clean, forgot to delete ipkg-build-stamp + +2005-02-15 Mina Naguib + * Now also reports wifidog_uptime when it pings the server, as well as + shows it in wdctl status + +2005-02-13 Mina Naguib + * Completely re-did the iptables rules. Most of the rules are now in the + filter table instead of the nat table. Also DROPs are now replaced with + REJECTs to help tell the user connection refused instead of endless pauses + * Bugfix: Traffic from client to router was counted twice in the "outgoing" + bytecount since it increased both counters in mangle.* and filter.* - Got + rid of TABLE_WIFIDOG_WIFI_TO_GW completely since it's unneeded + +2005-02-12 Mina Naguib + * Stricter format rules for all *scan* functions hunting for IPs and MAC addresses + * fw_iptables.c: Make sure scanned IP address is a valid IP address + * firewall.c: Fix memory leak in arp_get + * libhttpd/protocol.c: Abort connection if read non-ascii from client. This + is often a telltale sign of a program such as skype using port 80 for + non-http requests - this therefore ends the thread as early as possible + instead of having it lay around for a while trying to get a valid http + request and taking up resources + * ping_thread.c: When pinging auth server now also sends sys_uptime, sys_memfree + and sys_load + * -v commandline option now shows wifidog version + +2005-02-11 Philippe April + * Tagged v1_1_0_beta1 + +2005-02-11 Philippe April + * Fixed a bug in counting the traffic between client and gateway + * Alpha8 + +2005-02-04 Mina Naguib + * Partially bugfix apology when offline + * ipkg/rules: More tweaking to make it build nicely with recent openwrt + buildroots + +2005-02-03 Mina Naguib + * Keep track of last times we successfully & unsuccessfully spoke to the + auth server/used DNS. Then, if we know we're not online, show a little + apology to the user instead of re-directing them to the auth server. + * ipkg/rules: Added some extra version detection to auto-detect versions + of kernel, iptables and ipkg-utils instead of having them hardcoded. This + makes creating ipkg's work with different OpenWRT releases + * fw_iptables.c: Fixed memory leak caused by not freeing return from + iptables_compile in iptables_load_ruleset + * http.c: Deleted unused call to client_list_find + * http.c: /about URL now shows wifidog version + * Cosmetic typo fixes + +2005-02-03 Philippe April + * Ping the users everytime we check their counters, that way we keep them + alive + * Optional ExternalInterface + * Optional GatewayAddress (we discover it. finally.) + * We check for the traffic from the clients to the firewall, to catch the + traffic the icmp ping is generating + * Fixed bug where we were doing the opposite of what desired when checking if authentication server was alive + * Bumped to alpha7 + +2005-01-23 Philippe April + * wdctl status will return the auth servers in the linked list + * We'll now forward to the auth server to display the used-to-be-ugly + messages like "go ahead and validate your account you have 15 minutes" + * Bumped to alpha6 + +2005-01-06 Philippe April + * fw_iptables.c: Changed REJECT to DROP for the end of the table Unknown, + REJECT doesn't seem to be available in the NAT table. + * fw_iptables.c: Indented things + * fw_iptables.c Fix: Created the authservers table at the beginning and destroy + at exit time only to avoid recreating it everytime + * Bumped to alpha5 + +2005-01-05 Philippe April + * Typo, fixed some spaces (mostly esthetic) + * Bumped to alpha4 + +2004-12-19 Alexandre Carmel-Veilleux + * src/fw_iptables.c: Tweak of auth_server firewall rule setting + code. (and promptly undone, fixing the cause is better then + fixing the symptom) + * src/conf.c: NULL-fill auth_server struct so that + auth_server->last_ip always equals NULL when first filled. + +2004-12-16 Benoit GrĂ©goire + * src/fw_iptables.c: Display iptables command that is run in debug mode. + +2004-12-07 Benoit GrĂ©goire + * src/firewall.c: Fix reversed incoming and outgoing connections in statistics code + * bump version to alpha3 + +2004-11-29 Alexandre Carmel-Veilleux + * wifidog.conf: Fixed firewall rule bug. + * src/fw_iptables.c: Unknown user default block rule not "REJECT" + instead of "DROP" + +2004-11-23 Alexandre Carmel-Veilleux + * src/conf.c: Fixed a NULL pointer dereference in get_ruleset(). + +2004-11-22 Alexandre Carmel-Veilleux + * libhttpd/api.c: Fix leak in HttpdEndRequest(). + * src/ping_thread.c: Fix auth_server IP change code with latest + from previous branch. + * src/conf.h: Same as above. + * src/fw_iptables.c: Same as above. + * src/conf.[ch]: Firewall rule set parsing code. + * wifidog.conf: Default firewall rule set defined. + * src/fw_iptables.[ch]: Firewall rule set enacting code. + * configure.in: bumped version to 1.1.0-alpha2 + +2004-11-18 Benoit GrĂ©goire + * src/ping_thread.c: Merge phil's bug fixes from stable branch + * ipkg/rules: Merge phil's bug fixes from stable branch + * configure.in: Set version to 1.1.0alpha + +2004-11-18 Alexandre Carmel-Veilleux + * src/fw_iptables.[ch]: Merged in Phil's patch. + * src/*: Added ping_thread hooks to reset authserver table in the + firewall if it notices the auth_servers changing IPs. + +2004-11-17 Alexandre Carmel-Veilleux + * libhttpd/*: libhttpd has been taken behind the shed and shot in + the back of the head. The replacement separates the request struct + from the server struct. It's thread safe if none of OUR threads + write to server. + * src/*: All the changes to handle the new libhttpd and also to + move over to a worker thread system. http_callback_auth() no + longer spawns a thread either. + * *: this update preceded by a cvs tag PRE_NEW_LIBHTTPD. + * *: You want to check the mailing list archive also. + +2004-11-10 Alexandre Carmel-Veilleux + * libhttpd/protocol.c: select() based timeout. + +2004-10-31 Alexandre Carmel-Veilleux + * configure.in: bumped version number to "1.0.2-pre1" since we + already have ile sans fil hot spots advertising "1.0.1". + +2004-10-30 Alexandre Carmel-Veilleux + * src/ping_thread.c: asynch read(). fixed bug in byte counting. + +2004-10-29 Philippe April + * ipkg/rules: added conffiles so it does not overwrite config files + +2004-10-29 Alexandre Carmel-Veilleux + * src/ping_thread.c: Much new debugging information + * multiple files: Logging for all mutexes + +2004-10-28 Philippe April + * ipkg/rules: building ipkg-tools before packaging + +2004-10-28 Alexandre Carmel-Veilleux + * multiple files: Implemented a FirewallRule config command, it + doesn't actually do anything yet. + * libhttpd: #if 0'd out lots of request parsing code. + * libhttpd: changed URL parsing. + +2004-10-27 Philippe April + * ipkg/rules: removed --build=mipsel from ./configure + +2004-10-26 Philippe April + * ipkg/rules: sed -i is not standard, did a workaround. + * ipkg/rules: openwrt's buildroot has changed, modified ipkg + accordingly, please read README.openwrt + +2004-10-22 Alexandre Carmel-Veilleux + * src/various: Added wd_gethostbyname, a thread-safe (serialized) + version of gethostbyname. + +2004-10-15 Alexandre Carmel-Veilleux + * src/auth.c: Fixed hard coded port. + +2004-10-09 Alexandre Carmel-Veilleux + * src/gateway.c: More logging on termination_handler. + +2004-10-08 Alexandre Carmel-Veilleux + * src/wdctl_thread.c: Fix wdctl_status to return all connected + users. + +2004-10-07 Alexandre Carmel-Veilleux + * src/conf.c: Fixed mark_auth_server_bad() for the case where there + is only one auth server. + * src/ping_thread.c: Added extra debugging. + * src/ping_thread.c: Fixed file descriptor leak. + * src/centralserver.c: Fixed many file descriptor leaks. + * src/centralserver.c: Failure of read() no longer fatal. + * src/centralserver.c: In case of failure, return from + auth_server_request() is no longer an undefined authresponse. + * src/util.c: Fixed typo in logging. + * src/wdctl_thread.c: Added logging when socket path is too long. + * src/debug.c: Debug now logs the time of an event. + +2004-08-30 Alexandre Carmel-Veilleux + * wifidog.conf: Corrected an example + * README.openwrt: Typo fixed, editorial changes + * ChangeLog: Benoit's last update entry was set in the future ;-). + * All over src/: Compiled with -Wall and fixed all nagging. + +2004-08-30 Benoit GrĂ©goire + * Makefile.am: Add rpm target + * wifidog.spec.in: Rework spec file. Now works and include the init script + * ipkg/rules: Deal with the incomplete init.d system of the OpenWrt. Install scripts/init.d/wifidog as /usr/bin/wifidog-init, and call wifidog-init start from S65wifidog. + * scripts/openwrt/S65wifidog: Add file + * scripts/init.d/wifidog: Fix performance and protability problem. Make it chkconfig compliant. Test that chkconfig --add wifidog works (at least on mandrake) + * src/wdctl.c: Change some message, make sure wdctl return 0 unless there is an error. + +2004-08-30 Benoit GrĂ©goire + * README.openwrt: Documentation update + * Makefile.am: Make a ipkg target to ease WRT54G installation + * ipkg/rules: Add wdctl and the init.d script. + * Add BUILDROOT variable to the build system so we can use it when needed + * src/ping_thread.c: Have the server ping immediately on boot. Note that this will only help if the second server responds. The logic of the ping itself should be changed so it iterates in the list until it finds one that responds or exausts the list + * wifidog.conf: Add more doc, and (most) of ISF's default config in comments. + * Bump version in anticipation for release + +2004-08-29 Guillaume Beaudoin + * wifidog.spec.in: Changed prefix to match scripts/init.d/wifidog. + * debian/rules: Configuration and init.d file added. + * debian/control: Description and Depends field changed. + * Makefile.am: Added scripts directory and ipkg/rules file. + +2004-08-29 Pascal Leclerc + * scripts/init.d/wifidog: Startup/shutdown script for Wifidog deamon + +2004-08-29 Guillaume Beaudoin + * wifidog.spec.in: Must be in decending chronological order. + +2004-08-29 Guillaume Beaudoin + * wifidog.spec.in: Remove some leftover from libOFX. + * Makefile.am: Include debian/* files. + * We should now be able to package .deb and .rpm from dist. + +2004-08-27 Benoit GrĂ©goire + * README.openwrt,src/conf.c,h: Documentation update + * src/gateway.c, src/ping_thread.c, src/wdctl.c, src/wdctl_thread.c: Fix linking problems related to errno.h and extern int errno + +2004-08-26 Pascal Leclerc + * Makefile.am: Remove phpauth from EXTRA_DIST + +2004-08-25 Alexandre Carmel-Veilleux + * src/auth.c: Path as changed in 1.26 was preceded by a /, the path already contains a / so it would yield http://host//path/ + +2004-08-25 Benoit GrĂ©goire + * src/auth.c: Remove hardcoded path. + +2004-08-23 Benoit GrĂ©goire + * src/ping_thread.c: Send the gateway id to the central server during ping, so the server know which gateway checked in, and then knows for sure that it is up (well, once the server implements it...). + +2004-08-23 Benoit GrĂ©goire + * src/centralserver.c: Fix path for auth by appending /auth/ to auth_server->authserv_path. Wifidog works again. + +2004-08-20 Alexandre Carmel-Veilleux + * Debug output of all HTTP transactions and their responses. + * Changed ipkg to use wifidog.conf from the base tree + * Send url to central server for link back out + +2004-08-19 Alexandre Carmel-Veilleux + * Sort of fixed the hanging thread (with an explicit thread kill) + * Fixed ping code + +2004-08-13 Alexandre Carmel-Veilleux + * All Auth Server configuration now handled by the "AuthServer" + directive. + * The "AuthServer" directive is now multi line. + +2004-08-11 Alexandre Carmel-Veilleux + * Added code to do heartbeat. + * Changed AuthServer yet again. + +2004-08-09 Alexandre Carmel-Veilleux + * WiFiDog now can read multiple auth servers in its config file. + * Added functions to handle the auth servers list. + * WiFiDog can failover between servers for its internal requests. + * Firewall sets rules for all auth servers. + +2004-08-06 Alexandre Carmel-Veilleux + * AuthservPath no longer mandatory in config file. + +2004-08-04 Philippe April + * Renamed iptables.[ch] to fw_iptables.[ch] + +2004-08-03 Alexandre Carmel-Veilleux + * Fixed broken sockaddr_un usage in wdctl.c and wdctl_thread.c + +2004-08-01 Benoit GrĂ©goire + * Delete everything in phpauth, it will now live in it's own module (wifidog-auth) + +2004-08-01 Alexandre Carmel-Veilleux + * Added wdctl facility + +2004-07-21 Philippe April + * Cleaned up the ipkg makefile + * Added makefile to build on Debian + +2004-07-19 Alexandre Carmel-Veilleux + * Build script for OpenWRT ipkg + +2004-07-06 Alexandre Carmel-Veilleux + * Added cache control to default error message returned. + +2004-07-05 Philippe April + * Fixed an endless loop in client_list_delete + +2004-06-10 Alexandre Carmel-Veilleux + * Added debugging to libhttpd so that httpdGetConnection() traces + its execution into ./httpdGetConnection.log. This should be removed + once it's no longer needed or put within #ifdef DEBUG's. + +2004-06-01 Philippe April + * Sending User-Agent header to central server + +2004-05-28 Philippe April + * Fixed bugs implemented after major changes + +2004-05-27 Benoit GrĂ©goire + * Massive Doxygen update in all files. IMPORTANT: The new convention is: @brief in the .h, long description and parameters in the .c + * Cleaned up some more issues in my notes taken at the formal review + * client_list.c,h: Make client_list_free_node() private, define and document client_list_mutex here + * config.c: Start the hunt for evil globals: Get rid of the config global + * doc/doxygen.cfg.in: Enable generation of internal doc, a few other tweaks + * Documentation now generates a TODO list and DEPRECATED list, please look at them + +2004-05-27 Alexandre Carmel-Veilleux + * Cleaned up all the issues brought forward in the code review + on 2004-05-26 at Benoit's. There are to many changes to list + individually. + +2004-05-15 Philippe April + * Commented out cookie handling in libhttpd because it segfaults if + you pass a particular formatting/buggy one + +2004-05-14 Philippe April + * Fixed crash when receiving SIGPIPE signal with write() would fail + +2004-05-13 Philippe April + * Advertise to the central server when we logged out a user + +2004-05-12 Philippe April + * Sending a "stage" when doing authentication for the server + to be able to know if it's a login, or just a counters update. + +2004-05-11 Philippe April + * Now tracking the hotspot id and ip in database + +2004-05-07 Philippe April + * Now we store both incoming and outgoing counters on server + and expire if no activity at all on both + * Changed the structure of nodes a little + +2004-05-07 Philippe April + * New parameter ExternalInterface + * Made possible to count inbound traffic by inserting new rules + +2004-05-07 Philippe April + * Cleaned up common.h from files + +2004-05-07 Philippe April + * Made iptables' tables DEFINEs instead of being hardcoded + +2004-05-07 Philippe April + * Fixed typo + +2004-05-06 Philippe April + * Cleanups and standardized things + +2004-05-06 Philippe April + * Cleanups in fw_counter function + +2004-05-05 Philippe April + * Calling iptables directly instead of using shell scripts + for fw_init, fw_destroy and fw_allow/fw_deny + * Removed shell script for fw.counters + * Fixed memory leaks + * Moved most of the iptables-specific (all but the counters) + to iptables.c to modularize a bit more + * Hack to allow deciding if we want FW calls' messages quiet or not + +2004-04-23 Philippe April + * Fixed a debug line + +2004-04-22 Philippe April + * Major changes, cleaned up code + * Changed the way firewall tags traffic + +2004-04-21 Philippe April + * Changed fw.destroy so it cleans up more in a while loop + +2004-04-20 Alexandre Carmel-Veilleux + * fixed expiration time + +2004-04-20 Philippe April + * A lot of changes regarding debugging facilities and added logging + to syslog + * Removed possibility to specify port on command line + +2004-04-19 Philippe April + * Changed some debugging severity + +2004-04-19 Benoit GrĂ©goire + * Properly integrate libhttpd into the source tree ;) Note that this will create a proper system wide shared library for libghttpd. Still to be done: 1- Store Mina's patch somewhere, in case we want to upgrade libhttpd. 2-Add configure option not to build httpd, and use an already installed one. + +2004-04-18 Alexandre Carmel-Veilleux + * Fixed pthread_cond_timedwait. The mutex needed to be locked as + per the POSIX spec, yet Linux or Mac OS X don't care... + * Fixed the double SIGTERM handler on Linux... + +2004-04-17 Alexandre Carmel-Veilleux + * Added work around for uClibc bug in auth.c + +2004-04-17 Philippe April + * Fixed firewall scripts to make them standard and some firewall functions + +2004-04-17 Alexandre Carmel-Veilleux + * Updated documentation in firewall.c + +2004-04-17 Philippe April + * Fixed path returning to gateway in phpauth/login/index.php + +2004-04-16 Alexandre Carmel-Veilleux + * Merged in libhttpd into the source tree + +2004-04-16 Philippe April + * Fixed CRLF/formatting in phpauth/login/index.php + * Added some documentation for firewall.c, commandline.c + * Removed an unnecessary line dist_sysconf_DATA from Makefile.am + +2004-04-15 Alexandre Carmel-Veilleux + * Changed the locking mechanism, now all access to t_node * structs + are properly protected. + +2004-04-15 Alexandre Carmel-Veilleux + * Connection now closed if counter hasn't change for one full + period. + +2004-04-14 Philippe April + * Fixed shell script hardcoded interface + +2004-04-14 Alexandre Carmel-Veilleux + * Existing IPs are logged off when they're authenticated again. + +2004-04-14 Alexandre Carmel-Veilleux + * Fixed clean up so it happens at the right time. + +2004-04-14 Alexandre Carmel-Veilleux + * Major retooling of insert_userclass(), fixed seg fault. + * The program now works as advertised. + +2004-04-14 Alexandre Carmel-Veilleux + * Switched to threads. Alpha quality build, at best + +2004-04-12 Alexandre Carmel-Veilleux + * Changed child return value handling, again. Now it's actually + using the real value instead of the flag. + * The http.c authentication code now closes the http connection + from the user. + +2004-04-11 Alexandre Carmel-Veilleux + * Added extra debugging information. + * Fixed return value handling in debugging calls. + +2004-04-11 Alexandre Carmel-Veilleux + * Removed duplicates signal handling hooks + * Additional comments in SIGCHLD handler + +2004-04-11 Alexandre Carmel-Veilleux + * Node find if's expressions changed + +2004-04-11 Alexandre Carmel-Veilleux + * SIGCHLD Handler initializaed outside of deamon mode now. + +2004-04-11 Alexandre Carmel-Veilleux + * Very large modification. The entire architecture has been reworked + so that authentications to the central server are performed in a + fork()'d child process and the exit code from that child is then + used to set the User Class of the connection. + * The UserClasses (global definitions) and Rights (per connection) + have been integrated. + +2004-03-16 Mina Naguib + * Changed HTTP server tasks to be handled by libhttpd - merged + incorporate_libhttpd branch + +2004-03-13 Philippe April + * Modified the way firewall scripts are called so we can configure + them in the config file (a bit more modular than it was) + * Added simple linked list to keep track of clients and to + keep a counter of the utilization and send it to the auth server + * Fixed CRLF/formatting in phpauth/auth/index.php + * Hacked phpauth/auth/index.php to handle very basic utilization tracking + +2004-03-12 Philippe April + * Changed all perror()s into debug()s and added errno.h to common.h + +2004-03-10 Philippe April + * Small fix to firewall.c so we don't define variables after + the function has started (so it builds on gcc-2.95) + +2004-03-09 Philippe April + * Major changes, not forking anymore for new connections, now using + select() instead. It will allow us to efficiently use a linked list to track + users and other things. It introduces some bugs and design issues but will + be better in the end. + +2004-03-09 Philippe April + * Small fix in the default.php login page + * exit() where the program was supposed to exit but wasn't when the + firewall could not be setup + +2004-03-09 Alexandre Carmel-Veilleux + * Tiny change to increase cross-platform compatibility. It can now build on OS X and it comes close to building on my old BSD box. + +2004-03-08 Benoit GrĂ©goire + * Initial CVS import. Integrate a standrad GNU build system and Doxygen to the build process. Add Doxygen and CVS headers, .cvsignores, etc. Note that the imported code is Philippe April (papril777 at yahoo.com)'s work. Tell me if I forgot anything. Please note that the paths in the src/fw* scripts are still hardcoded. Don't forget to update the ChangeLog file every commit and add doxygen comments to your code. Happy hacking. + diff --git a/FAQ b/FAQ new file mode 100755 index 00000000..fb8d82d2 --- /dev/null +++ b/FAQ @@ -0,0 +1,488 @@ +# +# $Id$ +# +# The latest version of this document lives at: +# http://www.ilesansfil.org/wiki/WiFiDog/FAQ +# +# Please check the above URL if you have a FAQ that does not appear here. +# + +WiFiDog/FAQ + +The WiFi Dog Captive Portal Frequently Asked Questions + + To alleviate the repetition on the [9][WWW] WiFiDog mailing list, and + to help people get started quickly, here are the FAQs: + 1. [10]The WiFi Dog Captive Portal Frequently Asked Questions + 1. [11]General questions + 1. [12]What is WiFiDog ? + 2. [13]Who makes WiFiDog ? + 3. [14]Who can use WiFiDog ? + 4. [15]Who currently uses WiFiDog ? + 5. [16]What can it do ? + 6. [17]What is it composed of ? + 7. [18]What are the main differences between it and NoCat ? + 8. [19]How does it work ? + 9. [20]What does it run on ? + 10. [21]Can I write my own client ? + 11. [22]Can I write my own auth server ? + 12. [23]What does it look like ? + 2. [24]The WiFiDog Client + 1. [25]What do I need ? + 2. [26]Pre-installation + 3. [27]Installation + 4. [28]Configuration + 5. [29]Running + 6. [30]Testing + 3. [31]The WiFiDog client on a linksys WRT54G + 1. [32]What do I need ? + 2. [33]Pre-installation + 3. [34]Installation + 1. [35]Introduction + 2. [36]Compiling a MIPS-friendly WiFiDog + 3. [37]Getting the new MIPS-friendly WiFiDog onto the + router + 4. [38]Actual installation + 4. [39]Configuration, Running and Testing + 5. [40]The intricate link between WiFiDog and OpenWRT + 6. [41]I am not comfortable with linux and don't know how + to do all this compiling stuff. Is there an easier way + for me to get the WiFiDog client running on a Linksys + WRT54G ? + 4. [42]The WiFiDog auth server + 1. [43]What do I need ? + 2. [44]Installation + 3. [45]Configuration + 4. [46]Testing + +General questions + +What is WiFiDog ? + + [47]WiFiDog is software used to create wireless hotspots. It is a + next-generation alternative to [48][WWW] NoCat. + +Who makes WiFiDog ? + + The technical team of [49]IleSansFil created and maintains + [50]WiFiDog. + +Who can use WiFiDog ? + + On the legal/licensing front, anyone can use [51]WiFiDog. It is free + software released under the GPL license. + + On the practical front, we would like the answer to also be + "everyone", however this would not be the truth. The main target user + base of [52]WiFiDog is network administrators, hotspot administrators + and hackers who "know what they're doing". Odds are that an average + windows user would not benefit from, or be able to correctly setup and + continually administer a [53]WiFiDog installation. + + If the software ever reaches a point of complete point-and-click ease + that we feel average users can safely administer, we will update this + document. + +Who currently uses WiFiDog ? + + The following companies, organizations, groups or persons are known to + use [54]WiFiDog on their hotspots: + * [55]IleSansFil + * [56][WWW] BC Wireless + +What can it do ? + + See the [57]WiFiDog/FeatureList page for the feature list. + +What is it composed of ? + + It is composed of 2 components: + 1. The client is a daemon process - this gets installed on every + wireless router + 2. The auth server is a web application - this gets installed in a + central location + +What are the main differences between it and NoCat ? + + On the client side, it's smaller, has far fewer dependencies, and runs + well on embedded devices. + + On the auth server side, it's more customizable, and is geared towards + capitalizing the infrastructure for the purposes of building portals + and communities. + +How does it work ? + + The client daemon uses firewall rules to control traffic going through + the router. When a new user tries to access a web site, the client + will transparently re-direct them to the auth server where they can + either log-in or sign-up. The client and the auth server then + negotiate what to do with the client and either allow or deny them + certain network access. + + The client also talks to the auth server every X minutes to update it + on vital statistics including uptime, load, traffic count per client, + and to let it know it's still there. + + Refer to the [58]WiFiDog/FlowDiagram document for some more details. + +What does it run on ? + + The client runs on any linux machine that has a working + netfilter+iptables installation. + + The auth server runs on any PHP-enabled web server. + +Can I write my own client ? + + Sure, but why ? We've done all the work. The client is written in C + and is extremely lightweight so that it runs comfortably in embedded + environments such as the [59][WWW] Linksys WRT54G router. + + The client is time-tested and is fairly stable. It is used extensively + in [60][WWW] IleSansFil's deployed hotspots. + +Can I write my own auth server ? + + Again, we've done all the work. However our auth server at the time of + this writing is not as polished as the client. Feel free to make it + better or write your own from scratch. If you go with the later option + you'll have to respect the same protocol the client uses for the whole + system to work correctly. + +What does it look like ? + + The client is a daemon process that runs in the background. It looks + like zen, chi, the ether, zilch. It has no user interface. + + The auth server is a web application that can be customized via + templates to look however you want it to look. To check out + [61]IleSansFil's auth server installation see [62][WWW] + https://auth.ilesansfil.org + +The WiFiDog Client + +What do I need ? + + 1. Basic proficiency in a linux environment + 2. A linux OS with netfilter compiled into the kernel + 3. The iptables package + 4. The GNU C compiler (gcc). Other compilers may work, but we have + not tested and will not support them. + 5. The latest [63]WiFiDog tarball which can be obtained from + [64][WWW] SourceForge + +Pre-installation + + This is where a lot of people run into problems, so let's state this + in bold: + + MAKE SURE EVERYTHING WORKS FIRST BEFORE INTRODUCING [65]WiFiDog INTO + THE ENVIRONMENT + + That especially means: + * The router must boot properly + * The router must bring up the interfaces properly + * The router must set up the routes properly + * The router must connect to the internet properly + * DNS settings must be set or obtained properly. DNS must work. + * DHCP settings (client, server or both) must be set or obtained + properly. + * If using NAT, the router must setup NAT/masquerading rules with + iptables properly + * Clients on the desired ([66]WiFi) network must be able to bind, + associate, lease and connect the internet properly + * All the above must happen automatically when the router starts or + gets rebooted + + Do NOT proceed with installing [67]WiFiDog until you've satisfied the + above. It will not work otherwise and you will waste lots of time. + +Installation + + [68]WiFiDog, like many open source projects, is distributed with + standard autotools utilities to make installation easy. Unpack the + tarball, then follow the standard: +./configure +make +make install + +Configuration + + Edit /etc/wifidog.conf and follow the instructions in the file. Things + should be self-explanatory. + +Running + + For the first time, run [69]WiFiDog with the following switches: +wifidog -f -d 7 + + -f means to run in foreground (do not become a background daemon) + + -d 7 increases debug output level to the maximum + +Testing + + As a client on the [70]WiFi network (or whatever interface is + configured as the LAN interface in /etc/wifidog.conf), open a web + browser and try to browse to your favourite web site. + + Monitor the output of the running [71]WiFiDog to see what it's doing. + +The WiFiDog client on a linksys WRT54G + + Due to the lightness of the [72]WiFiDog client it is often installed + inside the linksys WRT54G. There are some profound issues that arise + with this setup that it warrants its own section in this FAQ: + +What do I need ? + + You will need to have basic/full proficiency in a linux environment + + You need to re-flash your router with a hacker-friendly firmware + called [73][WWW] OpenWRT. [74][WWW] Follow the user guide on the + OpenWRT site to get this part done. + + Do not proceed until you've completed the above. We also recommend you + spend some time familiarizing yourself with your new router's OS + before introducing [75]WiFiDog into that environment. This especially + includes the nvram settings, network interfaces and existing interface + bridges. + +Pre-installation + + The same rules apply as the pre-installation in a non-WRT54G + environment above. Do not proceed until you've satisfied them. In + summary: Make sure EVERYTHING works first. + +Installation + +Introduction + + Installation of the client on the WRT54G is a bit tricky. The space + limitations on the device mean there is no compiler in the OpenWRT + operating system. That means that you must compile the client on an + external machine then transfer the compiled form onto the router. + + To complicate things more, if you compile your client regularly on a + standard x86 desktop the produced binary will not run on the router + due to the different type of processor (MIPS) on that router. + + What is needed is called cross-compilation, In that scenario you use + an architecture (such as your x86 desktop) to produce binaries + explicitly designed to run on a different architecture (your MIPS + router). + + The above was the bad news since it makes things sound complicated. + The good news is that it's not too complicated and we've built scripts + to make this a snap for you. As a matter of fact, you've already done + this before! + + Remember when you followed the OpenWRT building instructions ? Without + knowing it, you already cross-compiled stuff! You used your desktop to + cross-compile an entire operating system for the MIPS architecture + which resulted in one compressed firmware image you installed on your + router. + +Compiling a MIPS-friendly WiFiDog + + 1. Download the latest [76][WWW] WiFiDog tarball from sourceforge. + 2. Uncompress the tarball, enter the directory + 3. Run the following, replacing /usr/local/openwrt/ with wherever you + unpacked the OpenWRT tarball earlier: + +ipkg/rules BUILDROOT=/usr/local/openwrt/ + + You're done. If all is well you should now have a new file named + wifidog_1.1.0_mipsel.ipk (version number may be different depending on + the tarball you downloaded). + +Getting the new MIPS-friendly WiFiDog onto the router + + The .ipk is a data file for the simple "ipkg/i-Package" package + manager already on your router. All that's needed now is to copy that + file onto your router. If you have installed the dropbear SSH daemon + package on your router you can use scp on your desktop to copy the + .ipk file to the router. Otherwise copy that file to any web server + you have access to, then use wget on the router to download the file + from the web server. + + Either way, place the file in the /tmp/ directory on the router. + +Actual installation + + Once you have the .ipk file on the router, use this command to install + it: +ipkg install /tmp/wifidog_1.1.0_mipsel.ipk + + Once that is successful delete the .ipk file from /tmp/ to free the + occupied memory. + +Configuration, Running and Testing + + Same as the earlier section in a non-WRT54G environment + +The intricate link between WiFiDog and OpenWRT + + Repeat after me: + + A [77]WiFiDog RUNNING ON AN OpenWRT INSTALLATION MUST HAVE BEEN + COMPILED AGAINST THE SAME OpenWRT BUILDROOT USED TO CREATE THAT + INSTALLATION + + What does that mean ? + 1. If you downloaded and compiled OpenWRT yourself, download and + compile [78]WiFiDog yourself against the same buildroot - Do not + use someone else's pre-compiled [79]WiFiDog + 2. If you downloaded a pre-compiled OpenWRT firmware image: + 1. Ask the person who built it to compile [80]WiFiDog for you + against the same buildroot + 2. Or ask them for a copy of their OpenWRT buildroot so you may + compile [81]WiFiDog against it + +I am not comfortable with linux and don't know how to do all this compiling +stuff. Is there an easier way for me to get the WiFiDog client running on a +Linksys WRT54G ? + + You can use an OpenWRT and [82]WiFiDog compiled by someone else. They + must be compiled by the same person against the same OpenWRT + buildroot. + + [83]IleSansFil makes it's own pair of OpenWRT images and [84]WiFiDog + .ipk compiled files available to the public: + * You can download a pre-compiled OpenWRT firmware image [85][WWW] + here + * And you can download a compatible [86]WiFiDog .ipk file [87][WWW] + here + + Look in the [88][WWW] OpenWRT site for instructions on how to re-flash + your router with the firmware image (skip any download/building + instructions). + + Then follow the above installation instructions for installing the + [89]WiFiDog .ipk file into the OpenWRT-flashed router. + + Please note that the above saves you from the knowledge and time + needed to compile and produced these binary files. It is however no + magical cure for linux illiteracy. You need to be proficient enough in + a unix environment to be able to telnet/ssh into the router and + perform the outlined installation and configuration tasks. If you do + not feel comfortable doing this we advise you consult with someone who + is proficient in linux and networking. + +The WiFiDog auth server + +What do I need ? + + Refer to [90]WiFiDog/AuthServerDoc + +Installation + + Refer to [91]WiFiDog/AuthServerDoc + +Configuration + + Refer to [92]WiFiDog/AuthServerDoc + +Testing + + Refer to [93]WiFiDog/AuthServerDoc + + last edited 2005-03-27 13:11:15 by [94]MinaNaguib + +References + + 1. http://www.ilesansfil.org/wiki/FrontPage + 2. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=raw + 3. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print + 4. http://www.ilesansfil.org/wiki/WiFiDog + 5. http://www.ilesansfil.org/wiki/FindPage + 6. http://www.ilesansfil.org/wiki/TitleIndex + 7. http://www.ilesansfil.org/wiki/WordIndex + 8. http://www.ilesansfil.org/wiki/HelpOnFormatting + 9. http://listes.ilesansfil.org/ + 10. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-b9d27a8844e66371abfbb27bf54669896d8bf4fa + 11. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-eb7dd5c81583187efb2d29ebc9ab2b6457417b13 + 12. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-e05420efb19364f3fa0844223f1bcfc71be7db00 + 13. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-80293173c84355ebeff2ecbfabaa32edb3c3ae75 + 14. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2aa554753e8b93818ba5ef190e67e401421931b9 + 15. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-975f3574aa59265dd2b0c45ae96e90c98c8bc7d5 + 16. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-dccf73ff2dcc305d6334dfd0ed90d1c4221b8a12 + 17. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-ebd81c14ab1b66d6aada9fc399597b644e120036 + 18. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-9b4c49acb692c6ba8bc2c0e43a991c5fc7b80220 + 19. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-5aa44a01d2ff78d1e2b5240e0a6c75910d584a0e + 20. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-738ab14de6f62065ca3daf9dd3341bfcabc06223 + 21. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-6059fbd6c262224baf06331fbe83f319ffe730fa + 22. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-e8131f271e42589291d507afd89d0c5d24f02ad1 + 23. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-6a764a3be722e0ff8d1446586643ea57d70cd489 + 24. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-a650736551182819fd6f742597362be729d9b70d + 25. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-57aaa0d1e21d38a7f5bedea65950c36b422cbbb6 + 26. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2b75ffe2445295c9982d0873d48e11d5cd89816e + 27. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-930f69b528374c4c55fc91b52e030deef8a93648 + 28. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-4b221edbf4c2383afab601694f2db039700c21cc + 29. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-9fcf91fbcf4712b6de6d5b70e703192dd882afa8 + 30. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-18cc26d84a97b42f3bc06af0203038062a8efb06 + 31. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-8ba37f479842312562f131032bb11e4fb68942aa + 32. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-57aaa0d1e21d38a7f5bedea65950c36b422cbbb6-2 + 33. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2b75ffe2445295c9982d0873d48e11d5cd89816e-2 + 34. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-930f69b528374c4c55fc91b52e030deef8a93648-2 + 35. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-b6830b2e74230b45153f4fa98ee189d5748ec9f0 + 36. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-78504516e51f8fc43cc111b9a8a41a85cb652fff + 37. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-92221794cfda95baa91352d087656f27754027d2 + 38. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2474f5bb689b7b06fc3334eb8e29a26ed60c4280 + 39. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-37c9cfe0aa830fa8ef3e6f617bd3c741cca6947c + 40. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-1dee9a0f840701e6518a0763c48aef734d1996f8 + 41. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-158e6f354a348c9374107d0a66a7f4c84603ba8a + 42. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-30106563831cfdb0840b05fa48e9194d7876f12e + 43. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-57aaa0d1e21d38a7f5bedea65950c36b422cbbb6-3 + 44. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-930f69b528374c4c55fc91b52e030deef8a93648-3 + 45. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-4b221edbf4c2383afab601694f2db039700c21cc-2 + 46. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-18cc26d84a97b42f3bc06af0203038062a8efb06-2 + 47. http://www.ilesansfil.org/wiki/WiFiDog + 48. http://nocat.net/ + 49. http://www.ilesansfil.org/wiki/IleSansFil + 50. http://www.ilesansfil.org/wiki/WiFiDog + 51. http://www.ilesansfil.org/wiki/WiFiDog + 52. http://www.ilesansfil.org/wiki/WiFiDog + 53. http://www.ilesansfil.org/wiki/WiFiDog + 54. http://www.ilesansfil.org/wiki/WiFiDog + 55. http://www.ilesansfil.org/wiki/IleSansFil + 56. http://www.bcwireless.net/ + 57. http://www.ilesansfil.org/wiki/WiFiDog/FeatureList + 58. http://www.ilesansfil.org/wiki/WiFiDog/FlowDiagram + 59. http://www.linksys.com/products/product.asp?prid=508&scid=35 + 60. http://auth.ilesansfil.org/hotspot_status.php + 61. http://www.ilesansfil.org/wiki/IleSansFil + 62. https://auth.ilesansfil.org/ + 63. http://www.ilesansfil.org/wiki/WiFiDog + 64. http://sourceforge.net/projects/wifidog + 65. http://www.ilesansfil.org/wiki/WiFiDog + 66. http://www.ilesansfil.org/wiki/WiFi + 67. http://www.ilesansfil.org/wiki/WiFiDog + 68. http://www.ilesansfil.org/wiki/WiFiDog + 69. http://www.ilesansfil.org/wiki/WiFiDog + 70. http://www.ilesansfil.org/wiki/WiFi + 71. http://www.ilesansfil.org/wiki/WiFiDog + 72. http://www.ilesansfil.org/wiki/WiFiDog + 73. http://openwrt.org/ + 74. http://openwrt.org/OpenWrtDocs + 75. http://www.ilesansfil.org/wiki/WiFiDog + 76. http://sourceforge.net/projects/wifidog + 77. http://www.ilesansfil.org/wiki/WiFiDog + 78. http://www.ilesansfil.org/wiki/WiFiDog + 79. http://www.ilesansfil.org/wiki/WiFiDog + 80. http://www.ilesansfil.org/wiki/WiFiDog + 81. http://www.ilesansfil.org/wiki/WiFiDog + 82. http://www.ilesansfil.org/wiki/WiFiDog + 83. http://www.ilesansfil.org/wiki/IleSansFil + 84. http://www.ilesansfil.org/wiki/WiFiDog + 85. http://www.ilesansfil.org/dist/openwrt/ + 86. http://www.ilesansfil.org/wiki/WiFiDog + 87. http://www.ilesansfil.org/dist/wifidog/ + 88. http://www.openwrt.org/ + 89. http://www.ilesansfil.org/wiki/WiFiDog + 90. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 91. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 92. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 93. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 94. http://www.ilesansfil.org/wiki/MinaNaguib diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 00000000..686ee881 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,53 @@ +# $Id$ + +SUBDIRS = libhttpd src . doc + +docdir = ${prefix}/share/doc/wifidog-@VERSION@ + +doc_DATA = \ + AUTHORS \ + COPYING \ + INSTALL \ + NEWS \ + README \ + ChangeLog + +EXTRA_DIST = \ + FAQ \ + wifidog.spec.in \ + wifidog.spec \ + config \ + scripts \ + contrib \ + wifidog.conf + +.PHONY: doc +doc: + $(MAKE) -C doc doc + +.PHONY: whiterussianipk +whiterussianipk: dist + make -C $(OPENWRTSDK) distclean + mkdir -p $(OPENWRTSDK)/dl + cp -f ${srcdir}/wifidog-@VERSION@.tar.gz $(OPENWRTSDK)/dl/ + make -C ${srcdir}/contrib/build-openwrt-whiterussianipk/wifidog TOPDIR=$(OPENWRTSDK) PKG_MD5SUM= V=99 + @echo DONE. If there were no errors, your package should be in: $(OPENWRTSDK)/bin/packages/ + +.PHONY: kamikazeipk +kamikazeipk: dist + make -C $(OPENWRTSDK) distclean + mkdir -p $(OPENWRTSDK)/dl + cp -f ${srcdir}/wifidog-@VERSION@.tar.gz $(OPENWRTSDK)/dl/ + make -C ${srcdir}/contrib/build-openwrt-kamikazeipk/wifidog TOPDIR=$(OPENWRTSDK) PKG_MD5SUM= V=99 SDK=1 DEVELOPER=1 + @echo DONE. If there were no errors, your package should be in: $(OPENWRTSDK)/bin/packages/ + +.PHONY: rpm +rpm: dist + cp ${builddir}wifidog.spec /usr/src/RPM/SPECS + cp ${builddir}wifidog-@VERSION@.tar.gz /usr/src/RPM/SOURCES + rpmbuild -ta ${builddir}wifidog-@VERSION@.tar.gz + +#clean-local: +# echo "clean-local: " && pwd +# rm -f /usr/src/RPM/SPECS/wifidog.spec +# rm -f /usr/src/RPM/SOURCES/wifidog-@VERSION@.tar.gz diff --git a/NEWS b/NEWS new file mode 100755 index 00000000..ad25e269 --- /dev/null +++ b/NEWS @@ -0,0 +1,116 @@ +# $Id$ +WiFiDog 1.1.5: + * First supported version on OpenWRT kamikaze + +WiFiDog 1.1.4: + * Fix incorrect firewal rule deletion introduced in 1.1.3rc1. Caused the incoming byte count reported to be incorrect for users that logged in a second time on a gateway that wasn't restarted in between. + +WiFiDog 1.1.3: + * Fix incomplete change to make te gateway retry external interface forever. + * Remove hardcoded authserver paths. Can now be defined in the config file (auth server section). + * Add manual logout URL, based in part on work by David Bird + +WiFiDog 1.1.3rc1: + * Close #321: Make the Gateway retry forever if it cannot find it's interface. You never know when someone may finally replug the network cable or something... + * Close #332: Apply patch from Laurent Marchal. biguphpcgmailcom + * fw_iptables.c: Fix error in iptables_fw_access(). Rules were created as ACCEPT instead of DROP + * firewall.c: Fix bug in fw_sync_with_authserver(). The traffic for the validation period of a user who validated his account while connected wouldn't get counted. + * doc/wifidog_firewall_map.dia: At long last, full documentation of the firewall. We would have avoided a lot of stupid mistakes if we produced that sooner. + * Release 1.1.3_rc1 + * Fix #324 + * wifidog.conf: Improve comments and add examples of blocking access to the upstream LAN. + * conf.h: The DEFAULT_CHECKINTERVAL was 5 instead of 60 (as stated in the config file) which caused huge needless load on the auth servers, and needless ping traffic towards the clients if it wasn't manually set. + * contrib/ Add contrib dir to collect the scripts and other code distributed with, but not really part of wifidog. + * Modify the build system to finally be able to build wifidog directly from the wifidog directory using the same files + used to make the official .ipk, without having to copy ANYTHNG to the openwrt SDK. + There is now a new target: make ipk make ipk OPENWRTSDK=path_to_openwrt_sdk + +WiFiDog 1.1.3beta6: + -Fix bug #238 (config file location was hardcoded) + -Fix problem with autodectection of the External interface if the interface isn't fully up yet. wifidog wil now retry for up to two minutes. + +WiFiDog 1.1.3beta4: + -Changed ordering in the filter.FORWARD chain + -Added TCPMSS rule + -Fixed rules bieng left over on shutdown + -Fixed wdctl reset problem + +WiFiDog 1.1.3beta2: + -Fix bug #65 (Whitelisted servers would still splash on port 80 + -Fix incorrect default value for Path in the AuthServer configuration + -Add more info to wdctl status + +WiFiDog 1.1.3beta1: + -Added patch by wireless London to use the GW interface's mac address as the node_id + if no node_id is specified. It allows the use of generic configuration files without + the need to hardcoding the node_id in. + -Added TrustedMACList configuration variable which allows specifying + MAC addresses which are allowed to go through without authentication. + -New wdctl command "restart" which will get wifidog to restart itself + while preserving the existing clientlist. Perfect for 0-downtime + upgrading! + -libhttpd: Fixed two bugs parsing the GET query string making wifidog segfault + + +WiFiDog 1.1.2: + - Added some informations so it compiles on newer OpenWRT's (whiterussian-rc2) + - Fixed minor issue with wdctl + - Changed the iptables rules priority to allow existing NAT rules to work + - read()s from central server in auth_server_request() are + now timed-out (via select). This is hopefully a bugfix to the + thread-freezing problem. + - Bugfix non-RFC compliant HTTP requests using \n instead of \r\n as line + terminations as per email from ludocornut@users.sourceforge.net + - Firewall: make the default ruleset for validating users = allow all + (except sending SMTP) + +Fixed issue with FAQ + +WiFiDog 1.1.1: + - An auth server on port 80 will now work + - Added an FAQ + +WiFiDog 1.1.0: + - Changes: + - Visual tweaks in the web interface + - Internal code & documentation touch-ups + - More debugging output + - Bugfixes: + - Wrong reported uptime + - Invalid http header sent during redirection + - Mixed long/long long type for counter + - Respect SSL setting in auth server definition + - Explicitly allow traffic coming into the router + - SIGPIPE handling + - Firewall destruction not occuring on wifidog termination + +WiFiDog 1.1.0_beta3: + - Completely re-did the iptables rules. Most of the rules are now in the filter table instead of the nat table. Also DROPs are now replaced with REJECTs to help tell the user connection refused instead of endless pauses + - wdctl status will return more informations + - Some error messages are now displayed by the auth server (used to be done in a non-pretty way by wifidog) + - We now 'ping' authserver and detect when authservers are changing IPs + - Fixed memory leaks + - Incoming and outgoing counters were reversed + - More verbose debugging + - ICMP Ping the users everytime we check their counters to keep them alive + - Optional ExternalInterface + - Optional GatewayAddress + - /about URL now shows wifidog version + - Keep track of last times we successfully & unsuccessfully spoke to the auth server/used DNS. Then, if we know we're not online, show a little apology to the user instead of re-directing them to the auth server. + - When pinging auth server now also sends sys_uptime, sys_memfree and sys_load + - Bugfix: Traffic from client to router was counted twice in the "outgoing" bytecount since it increased both counters in mangle.* and filter.* - Got rid of TABLE_WIFIDOG_WIFI_TO_GW completely since it's unneeded + - Do not update the last_updated field on incoming traffic - update it on outgoing traffic only. This should be a much more reliable indication of client no longer being there + - WiFiDog status is now viewable with a web browser at http://ip:port/wifidog/status + +WiFiDog 1.0.2: + - Fix reversed incoming and outgoing connections in statistics reported to the auth server + - Will now gracefully handle auth servers changing IP adress. + - Fixes two bugs in byte counting. (Possible missed data, and incoming and outgoing were reversed. + - Fixed file descriptor leaks + - wdctl_status now returns all connected users. + - worked around sed -i not being available on all platform + - ipkg no longuer overwrites config file + - Several code changes in thread handling and libhttpd to fix occasional hangs. + +WiFiDog 1.0.0: + - Initial release diff --git a/README b/README new file mode 100755 index 00000000..15c6bc87 --- /dev/null +++ b/README @@ -0,0 +1,16 @@ +# +# $Id$ +# + +The WiFi Guard Dog project is a complete and embeddable captive portal +solution for wireless community groups or individuals who wish to open a +free HotSpot while still preventing abuse of their Internet connection. + +The project's homepage is: + http://dev.wifidog.org/ + +Mailing list interface: + http://listes.ilesansfil.org/cgi-bin/mailman/listinfo/wifidog + +The project's software is released under the GPL license and is copyright it's respective owners. + diff --git a/README.openwrt b/README.openwrt new file mode 100755 index 00000000..f40cc473 --- /dev/null +++ b/README.openwrt @@ -0,0 +1,96 @@ +$Id$ + +OpenWRT specific README +======================= + +So, you want to run wifidog on one of linksys's WRT wireless routers! + +OpenWRT is the embedded linux-gnu bundle that runs on the linksys WRT +series routers (among numerous others). + +OpenWRT's home page is http://openwrt.org/ + +---- I just want to RUN the thing: ---- +-DO NOT use the wifidog packages distributed by OpenWRT (you are asking for trouble, they are broken in various ways; you will get no support if you do) +-Use the official wifidog packages on sourceforge (currently only available for whiterussian. + +---- I want to develop and test on OpenWRT ---- + +To build wifidog so that it may be run on the linksys wrt routers you +must first obtain the OpenWRT toolchain. This toolchain is a set of +compilers and other software development tools that will allow you, +running on your intel/pentium/mac computer to compile and develop software +that is to run on the mips based linksys wrt series routers, which is +based on another computer cpu chip entirely. + +You have several options for building wifidog using the OpenWRT toolchain. + +Option 1. get the prebuilt, minimal OpenWRT toolchain (The OpenWRT SDK), and give the makefile it's path. This is the best option, assuming you have a x86_64 Os (the SDK is distributed only for x86_64). + +For OpenWRT 0.9 (Whiterussian): + cd ~ + wget http://downloads.openwrt.org/whiterussian/newest/OpenWrt-SDK-Linux-i686-1.tar.bz2 + tar -jxvf OpenWrt-SDK-Linux-i686-1.tar.bz2 + cd wifidog + make whiterussianipk OPENWRTSDK=~/OpenWrt-SDK-Linux-i686-1/ + +For OpenWRT Kamikaze up till 7.09: + cd ~ + wget http://downloads.openwrt.org/kamikaze/7.09/brcm-2.4/OpenWrt-SDK-brcm-2.4-for-Linux-x86_64.tar.bz2 + tar -jxvf OpenWrt-SDK-brcm-2.4-for-Linux-x86_64.tar.bz2 + cd wifidog + make kamikazeipk OPENWRTSDK=~/OpenWrt-SDK-brcm-2.4-for-Linux-x86_64 + +For OpenWRT Kamikaze 8.09 and up, there is no SDK available and the 7.09 SDK does not work. So Option 1 is not an option. Option 2 is not an option either since building the SDK did not seem to work (https://forum.openwrt.org/viewtopic.php?id=17879). So jump to Option 3! + + If it works (!) you will have an ipkg file in $(OPENWRTSDK)/bin/packages/ + You can then boot up your OpenWrt + router, copy the .ipk to it, and install it using the ipkg commands. + + You should also make sure that the wifidog prereqs are already + installed on the router before you try to run wifidog. Note that if you build the + packages with the instructions above, they will download the required dependencies auomatically (if you have an internet connecion on yout router) and will refuse to install without them. + + The prereqs are: + * iptables command and modules mac, mark and MARK + * iptables kernel module mac + * libpthread + + These are all packages you can install on your running OpenWrt router + using the ipkg commands. If the router is on the net, the ipkg + commands can download the packages from www.openwrt.org, just like + debian apt-get or fedora yum or up2date. + +Option 2. Build your own SDK (or find someone to do it for you) +cd ~ +wget http://downloads.openwrt.org/kamikaze/7.09/kamikaze_7.09.tar.bz2 +tar -jxvf kamikaze_7.09.tar.bz2 +cd kamikaze_7.09 +make menuconfig #(Make sure you build the SDK in "special targets") +make #(could take hours downloading and compiling all dependencies) +Follow the instructions in Option 1, using the SDK you build instead of downloading it. + +Option 3. Use the full buildroot directly (time consuming...) + cd wifidog + make dist + cd ~ + wget http://downloads.openwrt.org/kamikaze/7.09/kamikaze_7.09.tar.bz2 + tar -jxvf kamikaze_7.09.tar.bz2 + cp -R wifidog/contrib/build-openwrt-kamikazeipk/wifidog kamikaze_7.09/package/ + cp wifidog/wifidog-1.1.5.tar.gz kamikaze_7.09/dl/ + cd kamikaze_7.09 + make menuconfig #(Follow instructions on OpenWRT's site to setup your buildroot for your platform) + make #(could take hours downloading and compiling all dependencies) + +For Kamikaze 8.09 and up, there is an extra dependency to add to the package, so here would be the new procedure + cd wifidog + make dist + cd ~ + wget http://downloads.openwrt.org/kamikaze/8.09/kamikaze_8.09.tar.bz2 + tar -jxvf kamikaze_8.09.tar.bz2 + cp -R wifidog/contrib/build-openwrt-kamikazeipk8.09up/wifidog kamikaze_8.09/package/ + cp wifidog/wifidog-1.1.5.tar.gz kamikaze_8.09/dl/ + cd kamikaze_8.09 + make menuconfig #(Follow instructions on OpenWRT's site to setup your buildroot for your platform) + make #(could take hours downloading and compiling all dependencies) + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..b0f95786 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +# +# $Id$ + +if [ -r Makefile ] +then + echo "Doing distclean" + make distclean +fi + +if [ "X$1" != "X" ] +then + BUILDROOT=`echo "$1" | sed 's/^[^=]*[=]//'` + + OLDCC=${CC} + OLDRANLIB=${RANLIB} + OLDAR=${AR} + + CC=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-gcc + RANLIB=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-ranlib + AR=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-ar + + POSTCONF=--host=mipsel + + export CC + export RANLIB + export AR +else + OLDCC=${CC} + OLDRANLIB=${RANLIB} + OLDAR=${AR} + POSTCONF= +fi + +echo "Running mkdir -p config" +mkdir -p config + +if [ "X"`uname` = "XDarwin" ] +then + echo "Running glibtoolize --force" + glibtoolize --force +else + echo "Running libtoolize --force" + libtoolize --force +fi + +echo "Running aclocal" +aclocal +echo "Running autoheader" +autoheader +echo "Running automake -a" +automake -a +echo "Running autoconf" +autoconf +echo "Running ./configure ${POSTCONF} --enable-maintainer-mode $conf_flags $@" +./configure ${POSTCONF} --enable-maintainer-mode $conf_flags "$@" + +CC=${OLDCC} +RANLIB=${OLDRANLIB} +AR=${OLDAR} + +export CC +export RANLIB +export AR diff --git a/configure.in b/configure.in new file mode 100755 index 00000000..cdc818c3 --- /dev/null +++ b/configure.in @@ -0,0 +1,105 @@ +## -*-m4-*- +# $Id$ + +dnl Process this file with autoconf to produce a configure script. + +# FILE: +# configure.in +# +# FUNCTION: +# implements checks for a variety of system-specific functions + +AC_INIT(src/common.h) +AM_CONFIG_HEADER(config.h) +AC_CONFIG_AUX_DIR(config) +AC_PROG_CC +AC_PROG_CXX +#AC_PROG_RANLIB + +AC_SUBST(BUILDROOT) + +WIFIDOG_MAJOR_VERSION=1 +WIFIDOG_MINOR_VERSION=1 +WIFIDOG_MICRO_VERSION=5 +WIFIDOG_VERSION=20140822 + +AC_SUBST(WIFIDOG_MAJOR_VERSION) +AC_SUBST(WIFIDOG_MINOR_VERSION) +AC_SUBST(WIFIDOG_MICRO_VERSION) +AC_SUBST(WIFIDOG_VERSION) +AM_INIT_AUTOMAKE(wifidog,$WIFIDOG_VERSION) + + +AM_MAINTAINER_MODE + +AC_PROG_INSTALL + +AC_LIBTOOL_DLOPEN +AM_PROG_LIBTOOL + +AC_ISC_POSIX +AC_C_BIGENDIAN +AC_PROG_MAKE_SET +AC_HEADER_STDC + + +# check for doxygen, mostly stolen from http://log4cpp.sourceforge.net/ +# ---------------------------------------------------------------------------- +AC_DEFUN([BB_ENABLE_DOXYGEN], +[ +AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)]) +AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) +AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) +AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX documentation generation with doxygen (no)], [], [ enable_latex_docs=no]) +if test "x$enable_doxygen" = xno; then + enable_doc=no +else + AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) + if test x$DOXYGEN = x; then + if test "x$enable_doxygen" = xyes; then + AC_MSG_ERROR([could not find doxygen]) + fi + enable_doc=no + else + enable_doc=yes + AC_PATH_PROG(DOT, dot, , $PATH) + fi +fi +AM_CONDITIONAL(DOC, test x$enable_doc = xyes) + +if test x$DOT = x; then + if test "x$enable_dot" = xyes; then + AC_MSG_ERROR([could not find dot]) + fi + enable_dot=no +else + enable_dot=yes +fi +AM_CONDITIONAL(ENABLE_DOXYGEN, test x$enable_doc = xtrue) +AC_SUBST(enable_dot) +AC_SUBST(enable_html_docs) +AC_SUBST(enable_latex_docs) +]) + +# Acutally perform the doxygen check +BB_ENABLE_DOXYGEN + +# check for pthread +AC_CHECK_HEADER(pthread.h, , AC_MSG_ERROR(You need the pthread headers) ) +AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(You need the pthread library) ) + +# libhttpd dependencies +echo "Begining libhttpd dependencies check" +AC_CHECK_HEADERS(string.h strings.h stdarg.h unistd.h) +AC_HAVE_LIBRARY(socket) +AC_HAVE_LIBRARY(nsl) +echo "libhttpd dependencies check complete" + +AC_OUTPUT( Makefile + wifidog.spec + wifidog-msg.html + src/Makefile + libhttpd/Makefile + doc/Makefile + ) + diff --git a/contrib/airos/wifidog/Makefile b/contrib/airos/wifidog/Makefile new file mode 100755 index 00000000..4195dbf1 --- /dev/null +++ b/contrib/airos/wifidog/Makefile @@ -0,0 +1,70 @@ +# +# Copyright (C) 2006,2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=wifidog +PKG_VERSION:=20090925 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:= @SF/$(PKG_NAME) +PKG_MD5SUM:= + +PKG_FIXUP = libtool + +include $(INCLUDE_DIR)/package.mk + +define Package/wifidog + SUBMENU:=Captive Portals + SECTION:=net + CATEGORY:=Network + DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +iptables-mod-nat +iptables-mod-nat-extra +libpthread + TITLE:=A wireless captive portal solution + URL:=http://www.wifidog.org +endef + +define Package/wifidog/description + The Wifidog project is a complete and embeddable captive + portal solution for wireless community groups or individuals + who wish to open a free Hotspot while still preventing abuse + of their Internet connection. +endef + +define Package/wifidog/conffiles + /usr/etc/wifidog.conf +endef + +MAKE_FLAGS += \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + all install + +define Package/wifidog/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/etc + $(INSTALL_DATA) ./files/wifidog.conf $(1)/usr/etc/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/usr/etc/ + $(INSTALL_DIR) $(1)/usr/etc/init.d + $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/usr/etc/init.d/wifidog +endef + +define Package/wifidog/postinst +#!/bin/sh + +# # check if the wifidog is already running, if so restart it +if /etc/init.d/wifidog status | grep 'Authentication servers' > /dev/null; then + # create copies of passwd and group, if we use squashfs + /etc/init.d/wifidog restart +fi +endef + +$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/airos/wifidog/files.patch b/contrib/airos/wifidog/files.patch new file mode 100755 index 00000000..a877a64b --- /dev/null +++ b/contrib/airos/wifidog/files.patch @@ -0,0 +1,87 @@ +--- SDK.UBNT.v5.2.clean/openwrt/package/ubnt-base-files/files/init 2010-05-14 06:11:06.000000000 -0400 ++++ SDK.UBNT.v5.2/openwrt/package/ubnt-base-files/files/init 2010-07-27 12:52:36.087267563 -0400 +@@ -64,7 +64,7 @@ echo "...filesystem init done" + # making sure that critical files are in place + mkdir -p /etc/rc.d /etc/init.d + # forced update +-for f in inittab rc.d/rc.sysinit rc.d/rc rc.d/rc.stop ppp; do ++for f in inittab rc.d/rc.sysinit rc.d/rc rc.d/rc.stop ppp wifidog.conf wifidog-msg.html ; do + cp -f -r /usr/etc/$f /etc/$f + done + echo "...base ok" +@@ -139,6 +139,14 @@ if [ -e /sbin/ubntconf ]; then + /sbin/ubntconf + fi + ++#adding wifidog to startup programs ++if [ -f /usr/etc/init.d/wifidog ]; then ++ cp -f /usr/etc/init.d/wifidog /etc/sysinit/wifidog.conf ++ echo "null::respawn:/usr/bin/wifidog -f" >> /etc/inittab ++ echo "wifidog" >> /etc/startup.list ++fi ++ ++ + echo "...running /sbin/init" + exec /sbin/init + +--- SDK.UBNT.v5.2.clean/openwrt/package/ubnt-base-files/files/usr/etc/rc.d/rc.softrestart 2010-05-14 06:11:06.000000000 -0400 ++++ SDK.UBNT.v5.2/openwrt/package/ubnt-base-files/files/usr/etc/rc.d/rc.softrestart 2010-07-27 12:03:15.604767622 -0400 +@@ -80,3 +80,10 @@ if [ $# -gt 0 ]; then + -p /etc/ 2>/dev/null & + fi + fi ++ ++#adding wifidog to startup programs ++if [ -f /usr/etc/init.d/wifidog ]; then ++ cp -f /usr/etc/init.d/wifidog /etc/sysinit/wifidog.conf ++ echo "null::respawn:/usr/bin/wifidog -f" >> /etc/inittab ++ echo "wifidog" >> /etc/startup.list ++fi + +--- SDK.UBNT.v5.2.clean/openwrt/.config 2010-05-18 05:03:40.000000000 -0400 ++++ SDK.UBNT.v5.2/openwrt/.config 2010-07-26 14:59:08.131750309 -0400 +@@ -888,7 +888,7 @@ CONFIG_PACKAGE_hotplug2=y + CONFIG_PACKAGE_iptables=y + CONFIG_PACKAGE_iptables-mod-conntrack=y + CONFIG_PACKAGE_iptables-mod-conntrack-extra=y +-# CONFIG_PACKAGE_iptables-mod-extra is not set ++CONFIG_PACKAGE_iptables-mod-extra=y + CONFIG_PACKAGE_iptables-mod-filter=y + # CONFIG_PACKAGE_iptables-mod-imq is not set + CONFIG_PACKAGE_iptables-mod-ipopt=y +@@ -896,7 +896,7 @@ CONFIG_PACKAGE_iptables-mod-ipopt=y + # CONFIG_PACKAGE_iptables-mod-ipsec is not set + # CONFIG_PACKAGE_iptables-mod-ipset is not set + CONFIG_PACKAGE_iptables-mod-nat=y +-# CONFIG_PACKAGE_iptables-mod-nat-extra is not set ++CONFIG_PACKAGE_iptables-mod-nat-extra=y + # CONFIG_PACKAGE_iptables-mod-ulog is not set + # CONFIG_PACKAGE_iptables-utils is not set + # CONFIG_PACKAGE_ldconfig is not set +@@ -963,6 +963,7 @@ CONFIG_PACKAGE_php2=y + # + # Network + # ++CONFIG_PACKAGE_wifidog=y + + # + # Monitoring +@@ -1149,7 +1150,7 @@ CONFIG_PACKAGE_kmod-ebtables=y + CONFIG_PACKAGE_kmod-ipt-core=y + CONFIG_PACKAGE_kmod-ipt-conntrack=y + CONFIG_PACKAGE_kmod-ipt-conntrack-extra=y +-# CONFIG_PACKAGE_kmod-ipt-extra is not set ++CONFIG_PACKAGE_kmod-ipt-extra=y + CONFIG_PACKAGE_kmod-ipt-filter=y + # CONFIG_PACKAGE_kmod-ipt-imq is not set + CONFIG_PACKAGE_kmod-ipt-ipopt=y +@@ -1157,7 +1158,7 @@ CONFIG_PACKAGE_kmod-ipt-ipopt=y + # CONFIG_PACKAGE_kmod-ipt-ipsec is not set + # CONFIG_PACKAGE_kmod-ipt-ipset is not set + CONFIG_PACKAGE_kmod-ipt-nat=y +-# CONFIG_PACKAGE_kmod-ipt-nat-extra is not set ++CONFIG_PACKAGE_kmod-ipt-nat-extra=y + CONFIG_PACKAGE_kmod-ipt-nathelper=y + # CONFIG_PACKAGE_kmod-ipt-nathelper-extra is not set + # CONFIG_PACKAGE_kmod-ipt-queue is not set + diff --git a/contrib/airos/wifidog/files/wifidog.conf b/contrib/airos/wifidog/files/wifidog.conf new file mode 100755 index 00000000..32e9ea90 --- /dev/null +++ b/contrib/airos/wifidog/files/wifidog.conf @@ -0,0 +1,253 @@ +# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface eth0 + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: auth-is-down +# +# Used when auth server is down +FirewallRuleSet auth-is-down { +# FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/airos/wifidog/files/wifidog.init b/contrib/airos/wifidog/files/wifidog.init new file mode 100755 index 00000000..2c6857e9 --- /dev/null +++ b/contrib/airos/wifidog/files/wifidog.init @@ -0,0 +1,27 @@ +plugin_start() { + echo "Inserting kernel modules: " + insmod ip_conntrack + insmod ip_nat + insmod ip_tables + insmod ipt_MARK + insmod ipt_mark + insmod ipt_mac + insmod ipt_REDIRECT + insmod ipt_MASQUERADE + insmod ipt_state + insmod iptable_mangle + insmod iptable_nat + insmod iptable_filter + + # echo "Starting wifidog: " + + #/usr/bin/wifidog-init start + echo + true +} +plugin_stop() { + killall wifidog + #/usr/bin/wifidog-init stop + true +} + diff --git a/contrib/airos/wifidog/patches/100-counter_outoing.patch b/contrib/airos/wifidog/patches/100-counter_outoing.patch new file mode 100755 index 00000000..3fa8a1ad --- /dev/null +++ b/contrib/airos/wifidog/patches/100-counter_outoing.patch @@ -0,0 +1,24 @@ +--- a/src/fw_iptables.c 2009-09-18 19:01:57.000000000 -0400 ++++ b/src/fw_iptables.c 2010-08-21 19:37:28.975094088 -0400 +@@ -513,6 +513,7 @@ iptables_fw_counters_update(void) + char *script, + ip[16], + rc; ++ char mystring[250]; + unsigned long long int counter; + t_client *p1; + struct in_addr tempaddr; +@@ -533,8 +534,11 @@ iptables_fw_counters_update(void) + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (output && !(feof(output))) { +- rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); ++ rc = fgets(mystring,250,output); ++ rc = sscanf(mystring, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); ++ //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); + //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); ++ + if (2 == rc && EOF != rc) { + /* Sanity*/ + if (!inet_aton(ip, &tempaddr)) { + diff --git a/contrib/airos/wifidog/readme.txt b/contrib/airos/wifidog/readme.txt new file mode 100755 index 00000000..38e28aa3 --- /dev/null +++ b/contrib/airos/wifidog/readme.txt @@ -0,0 +1,43 @@ +-- Compiling airos with the wifidog package running at boot + +Because airos doesn't have a package manager like opkf and has a (mostly) read-only file system, we need to build the the firmware with wifidog in it to have wifidog running on airos + +1- Get the latest wifidog source code tarball from sourceforge (http://sourceforge.net/projects/wifidog/files/) and copy it to the ~/dev/wifidog directory + +2- Get the wifidog airos package directory + +cd ~/dev/wifidog +wget http://dev.wifidog.org/wiki/doc/install/airos/wifidog_airos.tar.gz +tar xvzf wifidog_airos.tar.gz + +If compiling from source, this directory is located in wifidog/contrib/airos + +3- Download the airos SDK from http://www.ubnt.com/support/downloads and copy it to the ~/dev/airos directory + +4- Untar the SDK and prepare the files + +cd ~/dev/airos +tar xvjf SDK.UBNT.v5.2.tar.bz2 +cd SDK.UBNT.v5.2 + +cd openwrt/package +ln -s ~/dev/wifidog/airos/wifidog/ +cd ../dl +ln -s ~/dev/wifidog/wifidog-20090925.tar.gz + +cd ../.. +patch -p1 < openwrt/package/wifidog/files.patch + +5- Prepare the wifidog.conf file for your network, since airos is readonly, changes to the config files cannot be done in the router + +cd ~/dev/airos/SDK.UBNT.v5.2/openwrt +mkdir -p files/usr/etc +cp package/wifidog/files/wifidog.conf files/usr/etc/wifidog.conf + +6- Edit the files/usr/etc/wifidog.conf file for your authentication server settings. Also the GatewayInterface may need to be changed if you are not using a SOHO router configuration (eth0 for SOHO router, ath0 for router) + +7- Make the os + +make world V=99 + +8- Your new image should be available in the openwrt/bin directory as XM.v5.2....bin diff --git a/contrib/build-deb/changelog b/contrib/build-deb/changelog new file mode 100755 index 00000000..d0274250 --- /dev/null +++ b/contrib/build-deb/changelog @@ -0,0 +1,14 @@ +wifidog (1.0.0-1) stable; urgency=low + + * New init.d file. + * Inclu + * debian/rules: Configuration and init.d file added. + * Bump version in anticipation for release + + -- Guillaume Beaudoin Sun, 29 Aug 2004 23:14:12 -0400 + +wifidog (0.2.0-1) stable; urgency=low + + * Initial Package + + -- Philippe April Wed, 21 Jul 2004 15:22:50 -0500 diff --git a/contrib/build-deb/control b/contrib/build-deb/control new file mode 100755 index 00000000..330f63af --- /dev/null +++ b/contrib/build-deb/control @@ -0,0 +1,15 @@ +Source: wifidog +Section: net +Priority: optional +Maintainer: Philippe April + +Package: wifidog +Architecture: any +Depends: iptables, modutils, grep, mawk | awk +Provides: libhttpd +Description: The WiFi Guard Dog client + The WiFi Gaurd Dog project is a complete and embeddable captive portal + solution for wireless community groups or individuals who wish to open + a free HotSpot while still preventing abuse of their Internet connection. + . + This package contains only the client part. diff --git a/contrib/build-deb/rules b/contrib/build-deb/rules new file mode 100755 index 00000000..45291ed2 --- /dev/null +++ b/contrib/build-deb/rules @@ -0,0 +1,74 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +build: build-stamp +build-stamp: + dh_testdir + + ./configure --prefix=/usr + $(MAKE) + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + -$(MAKE) clean + -$(MAKE) distclean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + mkdir -p $(CURDIR)/debian/tmp/etc + cp wifidog.conf $(CURDIR)/debian/tmp/etc + cp scripts/init.d/wifidog debian/wifidog.init + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs +# dh_installexamples +# dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installcatalogs +# dh_installpam +# dh_installmime + dh_installinit +# dh_installcron +# dh_installinfo +# dh_undocumented + dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_python + dh_makeshlibs + dh_installdeb +# dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/Makefile b/contrib/build-openwrt-kamikazeipk/wifidog/Makefile new file mode 100755 index 00000000..adec69eb --- /dev/null +++ b/contrib/build-openwrt-kamikazeipk/wifidog/Makefile @@ -0,0 +1,62 @@ +# +# Copyright (C) 2006,2008 OpenWrt.org +# Copyright (C) 2008 Technologies Coeus inc. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id$ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=wifidog +PKG_VERSION:=20090925 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:= @SF/$(PKG_NAME) +PKG_MD5SUM:= + +PKG_FIXUP = libtool + +include $(INCLUDE_DIR)/package.mk + +define Package/wifidog + SUBMENU:=Captive Portals + SECTION:=net + CATEGORY:=Network + DEPENDS:=+kmod-ipt-extra +iptables-mod-extra +kmod-ipt-ipopt +iptables-mod-ipopt +kmod-ipt-nat +iptables-mod-nat +libpthread + TITLE:=A wireless captive portal solution + URL:=http://www.wifidog.org +endef + +define Package/wifidog/description + The Wifidog project is a complete and embeddable captive + portal solution for wireless community groups or individuals + who wish to open a free Hotspot while still preventing abuse + of their Internet connection. +endef + +define Package/wifidog/conffiles +/etc/wifidog.conf +endef + +MAKE_FLAGS += \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + all install + +define Package/wifidog/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog +endef + +$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf new file mode 100755 index 00000000..c905f04c --- /dev/null +++ b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf @@ -0,0 +1,246 @@ +# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init new file mode 100755 index 00000000..68d4eea6 --- /dev/null +++ b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org +START=65 +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print the status of the service" + + +start() { + /usr/bin/wifidog-init start +} + +stop() { + /usr/bin/wifidog-init stop +} + +status() { + /usr/bin/wifidog-init status +} \ No newline at end of file diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile new file mode 100755 index 00000000..3be5dbbf --- /dev/null +++ b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile @@ -0,0 +1,60 @@ +# +# Copyright (C) 2006,2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=wifidog +PKG_VERSION:=20090925 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:= @SF/$(PKG_NAME) +PKG_MD5SUM:= + +PKG_FIXUP = libtool + +include $(INCLUDE_DIR)/package.mk + +define Package/wifidog + SUBMENU:=Captive Portals + SECTION:=net + CATEGORY:=Network + DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +iptables-mod-nat +iptables-mod-nat-extra +libpthread + TITLE:=A wireless captive portal solution + URL:=http://www.wifidog.org +endef + +define Package/wifidog/description + The Wifidog project is a complete and embeddable captive + portal solution for wireless community groups or individuals + who wish to open a free Hotspot while still preventing abuse + of their Internet connection. +endef + +define Package/wifidog/conffiles +/etc/wifidog.conf +endef + +MAKE_FLAGS += \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + all install + +define Package/wifidog/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog +endef + +$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf new file mode 100755 index 00000000..c905f04c --- /dev/null +++ b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf @@ -0,0 +1,246 @@ +# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init new file mode 100755 index 00000000..1cbbafda --- /dev/null +++ b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init @@ -0,0 +1,17 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org +START=65 +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print the status of the service" + +start() { + /usr/bin/wifidog-init start +} + +stop() { + /usr/bin/wifidog-init stop +} + +status() { + /usr/bin/wifidog-init status +} diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/Config.in b/contrib/build-openwrt-whiterussianipk/wifidog/Config.in new file mode 100755 index 00000000..7b67874b --- /dev/null +++ b/contrib/build-openwrt-whiterussianipk/wifidog/Config.in @@ -0,0 +1,16 @@ +config BR2_PACKAGE_WIFIDOG + prompt "wifidog........................... A wireless captive portal solution" + tristate + default m if CONFIG_DEVEL + select BR2_PACKAGE_LIBPTHREAD + select BR2_PACKAGE_IPTABLES + select BR2_PACKAGE_IPTABLES_MOD_NAT + select BR2_PACKAGE_IPTABLES-MOD_IPOPT + help + The Wifidog project is a complete and embeddable captive + portal solution for wireless community groups or individuals + who wish to open a free Hotspot while still preventing abuse + of their Internet connection. + + http://dev.wifidog.org/ + diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/Makefile b/contrib/build-openwrt-whiterussianipk/wifidog/Makefile new file mode 100755 index 00000000..42df3f22 --- /dev/null +++ b/contrib/build-openwrt-whiterussianipk/wifidog/Makefile @@ -0,0 +1,65 @@ +# $Id: $ +ifndef TOPDIR + ERR := $(Please set TOPDIR to OpenWRT SDK's buildroot) +endif + +include $(TOPDIR)/rules.mk + +PKG_NAME:=wifidog +PKG_VERSION:=20090925 +PKG_RELEASE:=1 +PKG_MD5SUM:= + +PKG_SOURCE_URL:= @SF/$(PKG_NAME) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_CAT:=zcat +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install +include $(TOPDIR)/package/rules.mk +$(eval $(call PKG_template,WIFIDOG,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH))) +$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared + (cd $(PKG_BUILD_DIR); \ + $(TARGET_CONFIGURE_OPTS) \ + CFLAGS="$(TARGET_CFLAGS)" \ + CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \ + LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \ + ./configure \ + --target=$(GNU_TARGET_NAME) \ + --host=$(GNU_TARGET_NAME) \ + --build=$(GNU_HOST_NAME) \ + --prefix=/usr \ + --sysconfdir=/etc \ + --without-libiconv-prefix \ + --without-libintl-prefix \ + --disable-nls \ + ); + ## Add software specific configurable options above + ## See : ./configure --help + touch $@ + +$(PKG_BUILD_DIR)/.built: + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) + mkdir -p $(PKG_INSTALL_DIR) + $(MAKE) -C $(PKG_BUILD_DIR) \ + DESTDIR="$(PKG_INSTALL_DIR)" \ + all install + touch $@ + +$(IPKG_WIFIDOG): + install -m0755 -d $(IDIR_WIFIDOG)/etc/init.d + install -m0755 ./files/$(PKG_NAME).init $(IDIR_WIFIDOG)/etc/init.d/S65wifidog + install -m0644 ./files/wifidog.conf $(IDIR_WIFIDOG)/etc/ + install -m0644 $(PKG_BUILD_DIR)/wifidog-msg.html $(IDIR_WIFIDOG)/etc/ + install -m0755 -d $(IDIR_WIFIDOG)/usr/bin + install -m0755 -d $(IDIR_WIFIDOG)/usr/lib + install -m0755 $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(IDIR_WIFIDOG)/usr/bin/wifidog-init + $(CP) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(IDIR_WIFIDOG)/usr/bin/ + $(CP) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(IDIR_WIFIDOG)/usr/bin/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(IDIR_WIFIDOG)/usr/lib/ + $(RSTRIP) $(IDIR_WIFIDOG) + $(IPKG_BUILD) $(IDIR_WIFIDOG) $(PACKAGE_DIR) +mostlyclean: + make -C $(PKG_BUILD_DIR) clean + rm $(PKG_BUILD_DIR)/.built +all: $(IPKG_WIFIDOG) \ No newline at end of file diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf new file mode 100755 index 00000000..c275b887 --- /dev/null +++ b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf @@ -0,0 +1,246 @@ +# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br0 + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init new file mode 100755 index 00000000..44a272a6 --- /dev/null +++ b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org +START=50 + +start() { + /usr/bin/wifidog-init start +} + +stop() { + /usr/bin/wifidog-init stop +} + +status() { + /usr/bin/wifidog-init status +} \ No newline at end of file diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles new file mode 100755 index 00000000..aaa3dd14 --- /dev/null +++ b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles @@ -0,0 +1 @@ +/etc/wifidog.conf diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control new file mode 100755 index 00000000..dcf25e87 --- /dev/null +++ b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control @@ -0,0 +1,8 @@ +Package: wifidog +Priority: optional +Section: net +Depends: libpthread, iptables, iptables-mod-nat, iptables-mod-ipopt +Description: WiFiDog is a complete and embeddable captive portal + solution for wireless community groups or individuals who + wish to open a free Hotspot while still preventing abuse + of their Internet connection. diff --git a/contrib/dump_fw.sh b/contrib/dump_fw.sh new file mode 100755 index 00000000..37552efd --- /dev/null +++ b/contrib/dump_fw.sh @@ -0,0 +1,5 @@ +#!sh +iptables --list --table filter +iptables --list --table mangle +iptables --list --table nat + diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100755 index 00000000..85cc11d5 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,52 @@ +SUBDIRS = + +docdir = ${prefix}/share/doc/wifidog-@VERSION@ + +EXTRA_DIST = \ + doxygen.cfg \ + doxygen.cfg.in \ + README.developers.txt + +all: + +doc: doxygen.cfg + echo "doc: " && pwd && echo "distdir: " && echo $(distdir) + rm -rf html/ refman.pdf + $(DOXYGEN) doxygen.cfg +# $(MAKE) -C latex/ +# mv latex/refman.pdf ./refman.pdf + +dist-hook: doxygen.cfg + echo "dist-hook: " && pwd + cd $(srcdir) && pwd && rm -rf html refman.pdf && $(DOXYGEN) doxygen.cfg + cp -rp html ${distdir} + +clean-local: + echo "clean-local: " && pwd + rm -rf latex/ + rm -f *~ + rm -f doxygen.log + rm -f doxygen.cfg + +maintainer-clean-local: clean-local + echo "maintainer-clean-local: " && pwd + rm -rf html refman.pdf + +install-data-hook: + $(mkinstalldirs) $(DESTDIR)$(docdir) + mkdir -p html #Workaround to allow libofx-cvs user to install without doc. + cp -rp html $(DESTDIR)$(docdir) + +uninstall-hook: + chmod +w -R $(DESTDIR)${docdir}/html #Why chmod is needed is a mystery + rm -rf $(DESTDIR)${docdir}/html + +## We borrow guile's convention and use @-...-@ as the substitution +## brackets here, instead of the usual @...@. This prevents autoconf +## from substituting the values directly into the left-hand sides of +## the sed substitutions. +doxygen.cfg: doxygen.cfg.in Makefile + rm -f $@.tmp + sed < $< > $@.tmp \ + -e 's:@-top_srcdir-@:${top_srcdir}:g' + mv $@.tmp $@ \ No newline at end of file diff --git a/doc/README.developers.txt b/doc/README.developers.txt new file mode 100755 index 00000000..d19645dd --- /dev/null +++ b/doc/README.developers.txt @@ -0,0 +1,37 @@ + +$Id$ + + +This file contains some small notes on developing the WiFiDog application. + +The application's home page is: + http://www.ilesansfil.org/wiki/WiFiDog + +The application's sourceforge page is: + http://sourceforge.net/projects/wifidog/ + +As a developer, you must subscribe to sourceforge as a "developer" under WiFiDog, as well as subscribe to the WiFiDog mailing list located at: + http://listes.ilesansfil.org/cgi-bin/mailman/listinfo/wifidog + + +SOURCE CODE: + - Please do not contribute unless you agree with the GPL license and are contributing your portion under that license. See the included LICENSE.txt + - Please respect the intellectual property of others. You are not allowed to taint WiFiDog by including source code from projects that do not allow so. + - Keep in mind that this application will run on extremely simple embedded devices. The binary size needs to be small, the dependencies absolutely minimal, and the memory footprint negligible. + - Always place the subversion "Id" macro at the top of every file + - Since this is a collaborative project, please aim for clearness instead of cleverness when faced with a choice. + - If you must use some cleverness, please add appropriate clear comments. + - Please re-indent your code before committing to subversion - see the "Formatting Your Source Code" section in the GNU Coding Standards at http://www.gnu.org/prep/standards_toc.html - the entire document makes a good reading if you haven't read it before. Also see the "indent" program. + - Before writing any brand-new large chunks of code, make sure it's logic has been discussed with the other team of developers or included in the design stage. + + +MEMORY ALLOCATION IN SOURCE CODE: + - Safe versions of C functions that allocate memory (safe_malloc, safe_asprintf, etc..) have been created in safe.c . You must use them instead of the original functions. + - If you need to use a memory-allocating C function that does not have a safe version in safe.c, create the safe wrapper first (following the template of the others) and use that instead of calling the original. + + +DOCUMENTATION: + - Please use DoxyGen-style comments (see http://www.doxygen.org/ for details) for source code documentation. + - Please use DocBook-SGML documentation for user documentation. This will make it easy to export documentation in multiple formats. Otherwise submit your documentation in plaintext format to someone who will change it to DocBook. + - Please thoroughly-comment non-clear sections in your code. + diff --git a/doc/doxygen.cfg.in b/doc/doxygen.cfg.in new file mode 100755 index 00000000..41b0857f --- /dev/null +++ b/doc/doxygen.cfg.in @@ -0,0 +1,1294 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = WifiDog + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = YES + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @-top_srcdir-@/src + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = @-top_srcdir-@/libhttpd/ + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/doc/wifidog_firewall_diagram.dia b/doc/wifidog_firewall_diagram.dia new file mode 100755 index 0000000000000000000000000000000000000000..2946cc770d0ac8c8bafbb34fab1a9bdff80b0af0 GIT binary patch literal 8702 zcmVEt z=A-H4+hRUhn1&&IXGCeQ)*M!D2BR zz5B2j_9lbN;kVD;4Nm{Km`y)S&Ymr=T3vTK9ZzSyKL_J)pZ)DT{dx9$b(`n6?(@LC zuLc*xceCN(kLFv;_$P!-ZhbYJ-M#JQ)pS0Jmn=SA-MggWKJ@<^*Q~CZ$BQNx-~H_c z{B8M`R^Rw?uevwdc*x>%FuNE{?w=EXH{<0mLJQPd$6tmG7^DZUu74-%ANQ`?0lfmv4_OUkm7u_SWF*z|L248 zyo~_MZ-3Udbv5^5HadG)ac^DGaF>sxv&H+9e=_~LmUsWeboW0;^U=HUuH}U`oEyJ|>AU|oJYB5B`(Zr&c=~=YTlD_k`+oY* zXJ6co=yZ(EzI}EmZ~uPoN)+!FP2as=(AD(wQ)DW*EAM@4(RAx~@9y4t7T^3}axorW zTk&8k6aUv&QW#e`;q7L}4adXFlhf&Ja^D}=hBWE+$z-}(a z@qW>Km=<2%`lB~HZ2o@w@ubEsAOIpu0_c6J;2?uaABhM)Ul_|JR4rMp((&NWTH ziRAy?y6%pvc)5IX-yR(t9sYLw`pu6Gp5p`Nwh6nZlSSRh^!?uX;Bqwn6yM-rGJn>a zFFui7hzh>^(f=5Z{~Rtxr-Pg3YyEd{?|G~Jknr|1Cn4|9+oq>ZVV!W+R#rgJHt($4 zDD*(6B4yq|(Z{=(Tn_6$(Bb66Weq$(1kiOD(}a`Hzd*$1n4xkp!&b^Nf(8(1C`hQG zgwj5~a`6=>aBMD88{}|8dJi{{!!sg>5}{Fv3v%!v$7HZ5u+brGppXWac0m^8=nOe@ zE^>s*1V-e*6mDQb4)Q7DE0D~{vAIa?kOLq@=SblSKd>OjKE@nB93K7t;^_S0~?vTUeBL}b}2P}~Tgmdwg`cL%_&vn{KYt@*O(=sswmP=uurtuMr4$%-ZG)RIAtB~zNil--Q!kB76%(PS{L z3G6Z3FB8ESAHC`z6sKP%5Ld^@B_{>YS4t|OScCk0@!ACY$_Q`}te4=t52zIO-__(_Xyca28EjFKXy;c0M>Amc$7^N7Ol|O|-UBXwW5b@>t@e=>Z#$u1?-Z z5A%QG6BW_;A#-r2|8(tRBGA+Gn19GN!={iQHhoUv@y1OmJ@8=_H|dZL4IBF!Z3Cw| z=^nVwKO7D%wYKF|o4ao%Y${>XW?_@f37e2RYI-#qTuxJq@x8vU>}FvtjIlOUMhX`+ zvNjHDygmsuQX`l))>p~RPUH|iTHl&X+F4DpPF z04ZeY7TZtMIQ;GS$HRgeorWG(NE1y$fsC$s|0=ud_y*$h)_i>`s>Wkd&3E}K7-q6; zy>!jj1@#CE_H%K#^@XO?eM{Z9)4H$9V*Xq1!f%5MY`2k$*X%y9QYjga0%?Q-rBv9{ z@tU=?tNqPfO7V*K-7B697R4p*A{!6NAQ_0_6?d3O$!>%-rc#bGAD>nYD4M9y2NV6^ zN_l1s$q=b!GR1`g8+!>G^!4QU@Pwu)92^z!=mtCt3Imo5L&1&?u_L?fScOWnvVqd{ zPc2tzc&#hVO$W*lsTFo8p~~c){l<>hZz6QOIXEup(OKwW(UNH>=+Pm1;1=>%hChF0 z)R!Wz=^%S$bSdK&^jIG~etYxNo5SDV6wv6hglkH+s#DAeTZlNovPT?g${95vM9cuk zA8~*!m{Bleea!gr=fm$`{9GWTvp6F{29(Waoo+Uh+Xyo(f0%I%8NrwsX!wnJKJ5by z%iD5b)Qx%3{^<>nDuA&*V7&P4_&(koN+y1*5m9(|zdC>k^cS31O%>>g<4H(qPs4p>}5mg|@#T1ZnV zny2AdCp2Y<)e2g)u;`5OK?i_ft!ACeWWA#~P}W6+0dHKvmK|Wr*>JuXO@?PQto7n! zFN!%E&gTVQ*uxehbbL<8I|U;{ftM|Jx!vh+`wT7ljnQ9-*qr@sM8uNb&@mVvls+Ac zkchs~FWE4@pjMlc;pFVmHn(~qA9#v4M5Xw|oL=31A79|E^nC5E=PPU2r@qrMCbzxr zrAfWB+gGDEM?MhQWsL}&8XiwF%2m;q1n{<>YUM#CM6lX&Yj~5K4RrsFi?l_>pX@%T zJ4y;`Z9#Fjf7oxmt@G_*HW-hG2=I@7t*-84WAJ``@|H>t?Uk0;3dO!Sr^2>{(pH33>t^}3b zL8Vo~DXl79N?|N1%SR!}ZGlW-B|Dh{!fNJ#wb22!nx9OusZi}^4p^z&4OnsomI^F2 zjiNtz_4?@G<#Eb)4i>|YgHHvQI^bw%E3u0BRDh}DTAJU+00Z{<1u05`_*Z3p1;QA# zj(dawE4|NI7h=d4JUE4{^gcrg9P5DCgvy$*X$i6v(lQEZ^IrUw%ooG6-Y+j+7C>Pi zXy9q`IL1K7qbuu8I;);#_oPM>A5Ei=ADjbVU8F@PNlK@SXoQ37gQo%-&?6%yI_C6x zqnvd)J7I`tRMP8vmR|Q6>2+;6((5fWJiCJsjBp{RVAM{#<0%@D&Ornu?UvwNMUjTF zid(zuWURT&iRhO_BLGFW_pCa8r}~BK=(aH&6Hy=6ZIj>Xbxrr6wOfvr{t{2p+NG1E zOZ1n37#%((VnD#H-;HuM4@Xf&#rL~9zLttBzq@U>Cc7&~;l_~Ft_b1N*fEm^$I!s8 z=$0EPz*t~qPj4<(EB3SzN`rC1t7x$tW}Wp|(#HvdHaa>^fwR;GRM^vF(o&)<1_bol*?RiHXLk}% zfK@gpm16Wr=`IWeev?;!Q12FXL9?Q;DnaaSJ8tgG?oti z%xy+6JJU4o^n&x~oUJPetXf%5!*IAlx<&%k! zp$zxzXxV_tW|wPK@p^~}NUTfLG%Z|o3oDD$NS=@fX>OSx}@a-kGEJ zLrn&vtgPt{ML=$2@Rtniqra5IH2llco-?H+GmPX&RW_adwNd2rcFY1EUCrv!l;R_+ zPy&$dphIl|I)Y?J4h&y_BPf2{2(rLNfsM@-@sFB_10=C+8Dq%a+ zpiMNDw+S_@FvhydBR2(pbD>(|hDPgH6IW$5W@k`wYc*!Ui>~lO5>*{5?+azUOT@@- znsTy2&H*|$4Fblr!OWomqkM&qyI#JzQ0>a)29;OnulFkJ5_aq*mi&D9@~4AW1xC87 zmxEA22C@((@aPamU<=GE);VlT;#Gia-jxZy3XY$46Js87wAdh1RS)l{Xiv-6Z$` z)_VgEX-XG(#kx{Cc#Y`daoPt|n+}aAL&17EE0xb@)5~6bzJ{|&6lHWiI2{&X;RY6^ z=;05QwZdsE`;dbbon-2POuZF=j&vQ$m5UC9N5fhI-CV48nFwc{ zRq;P3$$NB$)q6A=we_e`>gYZC;ymtPjnI5Ch(GZ9P0CFax3PozXng7o`2a@V9HLy@ z#%@-oLUwbpbwWAn!r&zI(;;fv>Oq-qDWud`ImJw|$(5}Q$QWv3xv@UAjG8Q?CL0mz z)zRVGf=cYDMAW^IJlMk8=`fj*-JWc8YPHP?-`g%twOV;P$2kLipmE13T^`Lha*vs; z7qUJ&!U$kcmgDT(47!jp#|G|BMDJ=;mCbG(wU8q6yvMqo!nh*C_$F{L0(wXEiE1NjszabaK@7 z%AxSVa>IC|oV6=zrIL=`n049}Mc;2lUklBx=H5`!T$iwV3;U>*wkq$*Zo7|K`qfEF zyS`N-fYX&XG$~%ORw=e2WIMKt_e!D-*K8MLtyf??1$4j_+XYL(Vh06_i};*fL{rd< zw=86rjuw%u@YpM%z!$Ph=T!@9wh&21>xGq5%DjH$flu3BWu)&^>v z0O`RyX;urebg5dDszn1#osI{WSH0txZ-4pq*Md%6RWA}cmFh)T)eD>5EEYo&3>1o2vZ9$4+Akd%yKxIt`^-m^oHdumH>N^_vQom>w^95$BfDvLv?$AF z_wZ1~Fwk@u&T;$@1Ug9S979>4L1x~WsBqD1bC#QFT_@rLlQBvtTr1<#4g@K*REBm|Ii0nn;L)s6hFC4PASkPhmIh2JPH^^8SlaOAoK#+UA5be> zY7@JxO$hlaZtk&ZFl9nRt@K z=)}?bWa76)r%q{02ct#cX0SGiS;t`&-da@^*2}){V$9lGPo>T-dw=Ut>M zF*bS85OF)68MLWP46lM^PyN(LSTkfycqd)de<@thMZNc}`6Mg9tK{zZ zsxE*13{;+VahXYr1eSZtT#OtMDl{}F2U!`an~T*d_oJf|Pc%`b!GlwQm6oclMj0e1 zi&{FPOX{bje*RJeHGI$&DxqDO!`3}D)n)fY*ia!WD>c;@{F0Mu1duz4?3~oig=&K^ zAV4aEnk;`AqEYCm55m)nmoE?A9v3WPA2uB^NJ>vwREVhEl_8wj!bm6b*V6~5S!aUM zNzz4Vpe8)sw?RO(;&iZ;ioFB3Nz6L<62{S$C7H2b$qc75st``^hKB0$_maqEA`dxf zs3Ag*PUb&AprLJu-cvfm%1!sAx7O`C0quyM@^q zOTHyCv&&H_+G!X}NbJ+7*M=fWMmiHMVL+o0$_|*$ z^E>Yc^WG1?pZxOT=%>}H%9870uRBmLr&ARY9|20Lr=wI)b~6K+c|~U43U3wb#$#$| z@QzLb@XI0IApq?(1-t2%`SxyOlbj7(lFRy+{fh}*&OAlKz5eCV!eTbN+%xYqcQB1m&;I^lKAiPtAI8IZ@jkh| zPY*<6@Z?LBN@IuaXLd7$Lt&6UILkY*pUyGTCg(F?=+odE?HoNYRx0j+Hw{wOf!VUm zSel*oEo*5q+U4DjW_f$LjalA_jc5`pmovJICrLy)Ng<8AQBlE_A#c>!&_Pk6Ud{&+ zB~WyHzo`W4>A2fX*OOOUm|C}dpgpC&6|as5kbzEusBV3$g;mN`K?-dg|IoU6F>5Z> zLYnxlih}QV0%^UOH;Q}a&0`59pUq5mb~$_hG8_Im8h-3WbJB~NKDikFpMNcWXa`HBkoZtEiLdyf-T9%} zO&2hk`GD=zjU3Dre!i2W~&K zx#_~^H(fXZ=qL~Afq5G-m~@T{hT1QT(^Wv~k7o5n^Tlg9{u{NE;DU6LfBbh)Mrs4J z8J)&|yV8WQ%O;GsM~C0PIDUQjrg)L;eHdDp5ULQp1klBY?8t}QMjM7vnm#rcc+;6E zG<9Kw>n;o>B<*4gU3Fp9idkQkD@_>t=ScdjCJfjS5iYy+Vnqp2BJgf?3|a;{1`R0U z$DsF$e7k^weeGL~h|Tzv;cgb?{#vRP>-FY)x4YhaAM(S*N=Z&~OiI2~A(3OOkD5&f z#_u`98y;>hR*4HsT=-yI_|u!i-%Cu`MQ?t5?xP+X>bNdJVK+e`$}KpJ$yY+*tmE|? zL0hDQY|!L3f}_Vp3avc9*H|ax0}pYbRquI7xL$1`?51x5)fVV$(esH9w5GWjybLz) zZAd4FN^k%j@YiaEtWEeVuPW-jXX+ht_Pp(=^%3JyF+6?Zz z(9&b2l;m!Z$`!BO0uL3OQ_dC2YN4z?l0rH<_`e4)%l?ioI-{fwOHV=-HbG~JBiK%7 z6n$*`tx<;JHl(RKX_*uRw}d3=J86x&D`d@6Y=qHP7teDK>y0wQ^F*_w&@!8FZX`YV zo>#f)5a}=;O`!$3MyJ?Za3ZWSv32}^38MRWre%@$90EH z0?a0yD_0?BK3F9p0Xm8zwG+x=>Sk6>vl7iS#A-z(kU}Z+Xp~3kG)m37WH?6RP6ApC zTGHPNk)ZP>!{@!@!`>g0>BmX$bUca;e3D&ZpzfRBsBiT8zkM znrkn>lge?{BIpoJhon+O3=M-ffyUJERw8m`YvV`8BfynS;-wPNev^1FdMl+S(TxXc zu6K%uG9{x+4>Y?!f-((?26X2*UhTjs`kc;daswft>qpcGR4FGXR4VpK8BKE5!Wn`h z@3^?3`{jmWPM0I%?#5+=Y|^@cij%8u(u&eFt_^6>RN|fqK;9u4n+w%4bs416Us9Kf zHFXKJpA-SXS*7i!4Ob;~nU%Wy;pp&}lDzEJbqoTmbQQ)&#$%zgY{hk4C%F;S7Mg55 zdyB1Gb=Vp-Rp6cky0Jhln`@0RQtPl9K941rQF0j#pfn#YdV{O0+4O2Q8pNNw9L)ac zMfdb7em27bPhE8BI_HRBQxY59B{o8KqYs54k~WRyFp=896V0b4#Gt%}i~&#@-A5-| zsRB18t5MF{nSyDJVM%N3S6bsPv1+ZfMo_!qTZZiZp6Es?w7xPrYJlZTUD8P!=^zB} z`brD0T@?ct75zBw>UootHJ56kHN;Cx;&R{W=Q$d#Ia>KzC^&3E!BGZZ(Sku8^mvBK?6E@$D)JnI5 z@RU!lFzR&hNb3u2u#Sk;(mHPDTb+pauL=Sk(c_+yVvpmeev$(HX3Z`(V~5TCIfOdc zkwf6NU@|;LtPIRcJ>oGEr6#LkrSxPq5Q3s<%(Qfl-)huJSqw)p99!tkgs;$W_$?R? zBw}pND65v1!&$FamLnv81B3L-A&<)NTaH>Wi|Ht)V+(N#eubtZo48Mlyo`kkSc&@} ztX7t`h6S+Lr$aF~N(xxXzW$+3#2Q*82&Vw!dnz`g*o?Mu3gjd=wA+!@$fi|$VS;i{ zX_NlKIe$!Oi&~|VjJJJil%Y*BM#d<@a!-3{l(WV;5#C9c-k1xz6e0Ia({;{D?7Q`i z?eCa49?mXDlfk$~+i7-nF1xzoOk$EVU(rJBzLGSSJ5+|5|F*F_?OOQ^1oRlR@;;!J zPmunW{EA2QN!=kMqVPB`g1rh3_tdHio$sa(T6Dvzg7&trsr!sx;lA3osIq{K2Q;8AJYHx!Fax* z0Z7M045!C2|B&s(3rc2F=&v6_!x}0m3o%j<0fJO9Qc#vQm(%Q+z)f?gk+1e5Ybz+B z!M?GV?oNJNi@zjylLSyQn}du(8l-%@VK1RpX>q?=}!Eq~gy^PJ7 z0#zdaeN*qO6rbANc1b1kImi`fS%6~xG;Os{EI~smPP3d9??A{3S$nEIQa>;_w6s@J zv+k87lVe;wO;e&lm6qxqv{awZrkB0=bPZ>dD9Y%3a5^k8Eq_eALfd$@K~sX-ZrawA z%qG2i)>dj8T}6aI&D2JjKF#V!Pp$V-Tkf4yw03l@3XNWG$^%EHF4eN9viq)k}DJ7@X3NbAL{u>~@|#iHPQ58i9lSk#WDK+y8i zTn*RDM_==6xL#?vjw-I*QpH1{leyzFe>e~#sPDsH*w*S?(%&xYqw(a+*v zr>DdDyjJ5we$fRichx0LvF$rSJC8N>W$+R%Hy5c*)y2|4DzB`K{=G2@!4<}3VO$o* z<#m z=!4K;eTaxpJT309p;68U6te^ldpGis^!j5wLDw|jR`I+Xds+$;*OHhPp0X#(w zQY&2{2x%nuxR^Q#YYKc7nvxONL&Xj`)N0sK)=yp`;l}LBE6*mmS`}kpRIJ^OnieBio!T9Z zH2rv{kyb_3woJ=lzZiH?>eZ>fUl}0EO z_oui&#r-Lkr)$fjvk8}AnB5;k7AIOBI;U8kVtMX8a>epIWy{l4meTngP#S{ed=(^b zbEq*06$TN2sABQZ;8Ybr00i#MUv(nZwva;5whB*-3R<@KJndQ+VopKZ<_?coz8()g c4QJndvwRW%yO<3wzx(EY0d`2g%YSnM0GHJxJpcdz literal 0 HcmV?d00001 diff --git a/libhttpd/Makefile.am b/libhttpd/Makefile.am new file mode 100755 index 00000000..0338fca8 --- /dev/null +++ b/libhttpd/Makefile.am @@ -0,0 +1,19 @@ +# +# $Id$ +# + +lib_LTLIBRARIES = libhttpd.la + +libhttpd_la_SOURCES = protocol.c \ + api.c \ + version.c \ + ip_acl.c + +noinst_HEADERS = httpd_priv.h + +pkginclude_HEADERS = httpd.h + +EXTRA_DIST = README + +#AM_CPPFLAGS = \ +# -I${top_srcdir}/inc diff --git a/libhttpd/README b/libhttpd/README new file mode 100755 index 00000000..6d720519 --- /dev/null +++ b/libhttpd/README @@ -0,0 +1,23 @@ + +Welcome to LibHTTPD, a library for the creation of embedded web servers. +Complete documentation is available in the PDF file location in the doc +directory. + +To build this software simply run + + ./configure + make all + make install + +The software will be compiled and installed into /usr/local/lib and +/usr/local/include. To use the software you will have to include the +library's header file into your application and link against the library +itself. Details are privided in the documentation. + +This software has been developed by David J. Hughes (aka Bambi) of +Hughes Technologies in Australia. You can always find a current verion +of this software at www.Hughes.com.au + +This software is released under the GPL. If you wish to incorporate +this code in a commercial application then OEM licenses are available +from Hughes Technology. Please email info@Hughes.com.au for details. diff --git a/libhttpd/api.c b/libhttpd/api.c new file mode 100755 index 00000000..afc205ef --- /dev/null +++ b/libhttpd/api.c @@ -0,0 +1,1067 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "config.h" +#include "httpd.h" +#include "httpd_priv.h" + +#ifdef HAVE_STDARG_H +# include +#else +# include +#endif + + +char *httpdUrlEncode(str) + const char *str; +{ + char *new, + *cp; + + new = (char *)_httpd_escape(str); + if (new == NULL) + { + return(NULL); + } + cp = new; + while(*cp) + { + if (*cp == ' ') + *cp = '+'; + cp++; + } + return(new); +} + + + +char *httpdRequestMethodName(request *r) +{ + static char tmpBuf[255]; + + switch(r->request.method) + { + case HTTP_GET: return("GET"); + case HTTP_POST: return("POST"); + default: + snprintf(tmpBuf,255,"Invalid method '%d'", + r->request.method); + return(tmpBuf); + } +} + + +httpVar *httpdGetVariableByName(request *r, const char *name) +{ + httpVar *curVar; + + curVar = r->variables; + while(curVar) + { + if (strcmp(curVar->name, name) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); +} + + + +httpVar *httpdGetVariableByPrefix(request *r, const char *prefix) +{ + httpVar *curVar; + + if (prefix == NULL) + return(r->variables); + curVar = r->variables; + while(curVar) + { + if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); +} + + +httpVar *httpdGetVariableByPrefixedName(request *r, const char *prefix, const char *name) +{ + httpVar *curVar; + int prefixLen; + + if (prefix == NULL) + return(r->variables); + curVar = r->variables; + prefixLen = strlen(prefix); + while(curVar) + { + if (strncmp(curVar->name, prefix, prefixLen) == 0 && + strcmp(curVar->name + prefixLen, name) == 0) + { + return(curVar); + } + curVar = curVar->nextVariable; + } + return(NULL); +} + + +httpVar *httpdGetNextVariableByPrefix(curVar, prefix) + httpVar *curVar; + const char *prefix; +{ + if(curVar) + curVar = curVar->nextVariable; + while(curVar) + { + if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); +} + + +int httpdAddVariable(request *r, const char *name, const char *value) +{ + httpVar *curVar, *lastVar, *newVar; + + while(*name == ' ' || *name == '\t') + name++; + newVar = malloc(sizeof(httpVar)); + bzero(newVar, sizeof(httpVar)); + newVar->name = strdup(name); + newVar->value = strdup(value); + lastVar = NULL; + curVar = r->variables; + while(curVar) + { + if (strcmp(curVar->name, name) != 0) + { + lastVar = curVar; + curVar = curVar->nextVariable; + continue; + } + while(curVar) + { + lastVar = curVar; + curVar = curVar->nextValue; + } + lastVar->nextValue = newVar; + return(0); + } + if (lastVar) + lastVar->nextVariable = newVar; + else + r->variables = newVar; + return(0); +} + +httpd *httpdCreate(host, port) + char *host; + int port; +{ + httpd *new; + int sock, + opt; + struct sockaddr_in addr; + + /* + ** Create the handle and setup it's basic config + */ + new = malloc(sizeof(httpd)); + if (new == NULL) + return(NULL); + bzero(new, sizeof(httpd)); + new->port = port; + if (host == HTTP_ANY_ADDR) + new->host = HTTP_ANY_ADDR; + else + new->host = strdup(host); + new->content = (httpDir*)malloc(sizeof(httpDir)); + bzero(new->content,sizeof(httpDir)); + new->content->name = strdup(""); + + /* + ** Setup the socket + */ +#ifdef _WIN32 + { + WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD( 2, 2 ); + + err = WSAStartup( wVersionRequested, &wsaData ); + + /* Found a usable winsock dll? */ + if( err != 0 ) + return NULL; + + /* + ** Confirm that the WinSock DLL supports 2.2. + ** Note that if the DLL supports versions greater + ** than 2.2 in addition to 2.2, it will still return + ** 2.2 in wVersion since that is the version we + ** requested. + */ + + if( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) { + + /* + ** Tell the user that we could not find a usable + ** WinSock DLL. + */ + WSACleanup( ); + return NULL; + } + + /* The WinSock DLL is acceptable. Proceed. */ + } +#endif + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + free(new); + return(NULL); + } +# ifdef SO_REUSEADDR + opt = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int)); +# endif + new->serverSock = sock; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + if (new->host == HTTP_ANY_ADDR) + { + addr.sin_addr.s_addr = htonl(INADDR_ANY); + } + else + { + addr.sin_addr.s_addr = inet_addr(new->host); + } + addr.sin_port = htons((u_short)new->port); + if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0) + { + close(sock); + free(new); + return(NULL); + } + listen(sock, 128); + new->startTime = time(NULL); + return(new); +} + +void httpdDestroy(server) + httpd *server; +{ + if (server == NULL) + return; + if (server->host) + free(server->host); + free(server); +} + + + +request *httpdGetConnection(server, timeout) + httpd *server; + struct timeval *timeout; +{ + int result; + fd_set fds; + struct sockaddr_in addr; + socklen_t addrLen; + char *ipaddr; + request *r; + + FD_ZERO(&fds); + FD_SET(server->serverSock, &fds); + result = 0; + while(result == 0) + { + result = select(server->serverSock + 1, &fds, 0, 0, timeout); + if (result < 0) + { + server->lastError = -1; + return(NULL); + } + if (timeout != 0 && result == 0) + { + return(NULL); + server->lastError = 0; + } + if (result > 0) + { + break; + } + } + /* Allocate request struct */ + r = (request *)malloc(sizeof(request)); + if (r == NULL) { + server->lastError = -3; + return(NULL); + } + memset((void *)r, 0, sizeof(request)); + /* Get on with it */ + bzero(&addr, sizeof(addr)); + addrLen = sizeof(addr); + r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr, + &addrLen); + ipaddr = inet_ntoa(addr.sin_addr); + if (ipaddr) { + strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN); + r->clientAddr[HTTP_IP_ADDR_LEN-1]=0; + } else + *r->clientAddr = 0; + r->readBufRemain = 0; + r->readBufPtr = NULL; + + /* + ** Check the default ACL + */ + if (server->defaultAcl) + { + if (httpdCheckAcl(server, r, server->defaultAcl) + == HTTP_ACL_DENY) + { + httpdEndRequest(r); + server->lastError = 2; + return(NULL); + } + } + return(r); +} + + + +int httpdReadRequest(httpd *server, request *r) +{ + static char buf[HTTP_MAX_LEN]; + int count, + inHeaders; + char *cp, *cp2; + int _httpd_decode(); + + + /* + ** Setup for a standard response + */ + strcpy(r->response.headers, + "Server: Hughes Technologies Embedded Server\n"); + strcpy(r->response.contentType, "text/html"); + strcpy(r->response.response,"200 Output Follows\n"); + r->response.headersSent = 0; + + + /* + ** Read the request + */ + count = 0; + inHeaders = 1; + while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0) + { + count++; + + /* + ** Special case for the first line. Scan the request + ** method and path etc + */ + if (count == 1) + { + /* + ** First line. Scan the request info + */ + cp = cp2 = buf; + while(isalpha((unsigned char)*cp2)) + cp2++; + *cp2 = 0; + if (strcasecmp(cp,"GET") == 0) + r->request.method = HTTP_GET; + if (strcasecmp(cp,"POST") == 0) + r->request.method = HTTP_POST; + if (r->request.method == 0) + { + _httpd_net_write( r->clientSock, + HTTP_METHOD_ERROR, + strlen(HTTP_METHOD_ERROR)); + _httpd_net_write( r->clientSock, cp, + strlen(cp)); + _httpd_writeErrorLog(server, r, LEVEL_ERROR, + "Invalid method received"); + return(-1); + } + cp = cp2+1; + while(*cp == ' ') + cp++; + cp2 = cp; + while(*cp2 != ' ' && *cp2 != 0) + cp2++; + *cp2 = 0; + strncpy(r->request.path,cp,HTTP_MAX_URL); + r->request.path[HTTP_MAX_URL-1]=0; + _httpd_sanitiseUrl(r->request.path); + continue; + } + + /* + ** Process the headers + */ + if (inHeaders) + { + if (*buf == 0) + { + /* + ** End of headers. Continue if there's + ** data to read + */ + if (r->request.contentLength == 0) + break; + inHeaders = 0; + break; + } +#if 0 + /** + * Philippe commenting this out, it crashed with a + * particular pattern sent from the browser + * and we don't need it + if (strncasecmp(buf,"Cookie: ",7) == 0) + { + char *var, + *val, + *end; + + var = strchr(buf,':'); + while(var) + { + var++; + val = strchr(var, '='); + *val = 0; + val++; + end = strchr(val,';'); + if(end) + *end = 0; + httpdAddVariable(r, var, val); + var = end; + } + } + */ +#endif + if (strncasecmp(buf,"Authorization: ",15) == 0) + { + cp = strchr(buf,':'); + if (cp) { + cp += 2; + + if (strncmp(cp,"Basic ", 6) != 0) + { + /* Unknown auth method */ + } + else + { + char authBuf[100]; + + cp = strchr(cp,' ') + 1; + _httpd_decode(cp, authBuf, 100); + r->request.authLength = + strlen(authBuf); + cp = strchr(authBuf,':'); + if (cp) + { + *cp = 0; + strncpy( + r->request.authPassword, + cp+1, HTTP_MAX_AUTH); + r->request.authPassword[HTTP_MAX_AUTH-1]=0; + } + strncpy(r->request.authUser, + authBuf, HTTP_MAX_AUTH); + r->request.authUser[HTTP_MAX_AUTH-1]=0; + } + } + } +#if 0 + if (strncasecmp(buf,"Referer: ",9) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + { + strncpy(r->request.referer,cp, + HTTP_MAX_URL); + r->request.referer[HTTP_MAX_URL-1]=0; + } + } +#endif + /* acv@acv.ca/wifidog: Added decoding of host: if + * present. */ + if (strncasecmp(buf,"Host: ",6) == 0) + { + cp = strchr(buf,':'); + if(cp) + { + cp += 2; + strncpy(r->request.host,cp, + HTTP_MAX_URL); + r->request.host[HTTP_MAX_URL-1]=0; + } + } + /* End modification */ +#if 0 + if (strncasecmp(buf,"If-Modified-Since: ",19) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + { + strncpy(r->request.ifModified,cp, + HTTP_MAX_URL); + r->request.ifModified[HTTP_MAX_URL-1]=0; + cp = strchr(r->request.ifModified, + ';'); + if (cp) + *cp = 0; + } + } + if (strncasecmp(buf,"Content-Type: ",14) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + { + strncpy(r->request.contentType,cp, + HTTP_MAX_URL); + r->request.contentType[HTTP_MAX_URL-1]=0; + } + } + if (strncasecmp(buf,"Content-Length: ",16) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + r->request.contentLength=atoi(cp); + } +#endif + continue; + } + } + + +#if 0 + /* XXX: For WifiDog, we only process the query string parameters + but keep the GET variables in the request.query! + */ + /* + ** Process and POST data + */ + if (r->request.contentLength > 0) + { + bzero(buf, HTTP_MAX_LEN); + _httpd_readBuf(r, buf, r->request.contentLength); + _httpd_storeData(r, buf); + + } +#endif + + /* + ** Process any URL data + */ + cp = strchr(r->request.path,'?'); + if (cp != NULL) + { + *cp++ = 0; + strncpy(r->request.query, cp, sizeof(r->request.query)); + r->request.query[sizeof(r->request.query)-1]=0; + _httpd_storeData(r, cp); + } + + return(0); +} + + +void httpdEndRequest(request *r) +{ + _httpd_freeVariables(r->variables); + shutdown(r->clientSock,2); + close(r->clientSock); + free(r); +} + + +void httpdFreeVariables(request *r) +{ + _httpd_freeVariables(r->variables); +} + + + +void httpdDumpVariables(request *r) +{ + httpVar *curVar, + *curVal; + + curVar = r->variables; + while(curVar) + { + printf("Variable '%s'\n", curVar->name); + curVal = curVar; + while(curVal) + { + printf("\t= '%s'\n",curVal->value); + curVal = curVal->nextValue; + } + curVar = curVar->nextVariable; + } +} + +void httpdSetFileBase(server, path) + httpd *server; + const char *path; +{ + strncpy(server->fileBasePath, path, HTTP_MAX_URL); + server->fileBasePath[HTTP_MAX_URL-1]=0; +} + + +int httpdAddFileContent(server, dir, name, indexFlag, preload, path) + httpd *server; + char *dir, + *name; + int (*preload)(); + int indexFlag; + char *path; +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_FILE; + newEntry->indexFlag = indexFlag; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + if (*path == '/') + { + /* Absolute path */ + newEntry->path = strdup(path); + } + else + { + /* Path relative to base path */ + newEntry->path = malloc(strlen(server->fileBasePath) + + strlen(path) + 2); + snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", + server->fileBasePath, path); + } + return(0); +} + + + +int httpdAddWildcardContent(server, dir, preload, path) + httpd *server; + char *dir; + int (*preload)(); + char *path; +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = NULL; + newEntry->type = HTTP_WILDCARD; + newEntry->indexFlag = HTTP_FALSE; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + if (*path == '/') + { + /* Absolute path */ + newEntry->path = strdup(path); + } + else + { + /* Path relative to base path */ + newEntry->path = malloc(strlen(server->fileBasePath) + + strlen(path) + 2); + snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", + server->fileBasePath, path); + } + return(0); +} + + + + +int httpdAddC404Content(server, function) + httpd *server; + void (*function)(); +{ + if (!server->handle404) { + server->handle404 = (http404*)malloc(sizeof(http404)); + } + + if (!server->handle404) { + return(-1); + } + + server->handle404->function = function; + return(0); +} + +int httpdAddCContent(server, dir, name, indexFlag, preload, function) + httpd *server; + char *dir; + char *name; + int (*preload)(); + void (*function)(); +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_C_FUNCT; + newEntry->indexFlag = indexFlag; + newEntry->function = function; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); +} + + +int httpdAddCWildcardContent(server, dir, preload, function) + httpd *server; + char *dir; + int (*preload)(); + void (*function)(); +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = NULL; + newEntry->type = HTTP_C_WILDCARD; + newEntry->indexFlag = HTTP_FALSE; + newEntry->function = function; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); +} + +int httpdAddStaticContent(server, dir, name, indexFlag, preload, data) + httpd *server; + char *dir; + char *name; + int (*preload)(); + char *data; +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_STATIC; + newEntry->indexFlag = indexFlag; + newEntry->data = data; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); +} + +void httpdSendHeaders(request *r) +{ + _httpd_sendHeaders(r, 0, 0); +} + +void httpdSetResponse(request *r, const char *msg) +{ + strncpy(r->response.response, msg, HTTP_MAX_URL); + r->response.response[HTTP_MAX_URL-1]=0; +} + +void httpdSetContentType(request *r, const char *type) +{ + strcpy(r->response.contentType, type); +} + + +void httpdAddHeader(request *r, const char *msg) +{ + int size; + size = HTTP_MAX_HEADERS - 2 - strlen(r->response.headers); + if(size > 0) + { + strncat(r->response.headers,msg,size); + if (r->response.headers[strlen(r->response.headers) - 1] != '\n') + strcat(r->response.headers,"\n"); + } +} + +void httpdSetCookie(request *r, const char *name, const char *value) +{ + char buf[HTTP_MAX_URL]; + + snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value); + httpdAddHeader(r, buf); +} + +void httpdOutput(request *r, const char *msg) +{ + const char *src; + char buf[HTTP_MAX_LEN], + varName[80], + *dest; + int count; + + src = msg; + dest = buf; + count = 0; + while(*src && count < HTTP_MAX_LEN) + { + if (*src == '$') + { + const char *tmp; + char *cp; + int count2; + httpVar *curVar; + + tmp = src + 1; + cp = varName; + count2 = 0; + while (*tmp && (isalnum((unsigned char)*tmp) || *tmp == '_') && + count2 < 80) + { + *cp++ = *tmp++; + count2++; + } + *cp = 0; + curVar = httpdGetVariableByName(r,varName); + if (curVar) + { + strcpy(dest, curVar->value); + dest = dest + strlen(dest); + count += strlen(dest); + } + else + { + *dest++ = '$'; + strcpy(dest, varName); + dest += strlen(varName); + count += 1 + strlen(varName); + } + src = src + strlen(varName) + 1; + continue; + } + *dest++ = *src++; + count++; + } + *dest = 0; + r->response.responseLength += strlen(buf); + if (r->response.headersSent == 0) + httpdSendHeaders(r); + _httpd_net_write( r->clientSock, buf, strlen(buf)); +} + + + +#ifdef HAVE_STDARG_H +void httpdPrintf(request *r, const char *fmt, ...) +{ +#else +void httpdPrintf(va_alist) + va_dcl +{ + request *r;; + const char *fmt; +#endif + va_list args; + char buf[HTTP_MAX_LEN]; + +#ifdef HAVE_STDARG_H + va_start(args, fmt); +#else + va_start(args); + r = (request *) va_arg(args, request * ); + fmt = (char *) va_arg(args, char *); +#endif + if (r->response.headersSent == 0) + httpdSendHeaders(r); + vsnprintf(buf, HTTP_MAX_LEN, fmt, args); + r->response.responseLength += strlen(buf); + _httpd_net_write( r->clientSock, buf, strlen(buf)); +} + + + + +void httpdProcessRequest(httpd *server, request *r) +{ + char dirName[HTTP_MAX_URL], + entryName[HTTP_MAX_URL], + *cp; + httpDir *dir; + httpContent *entry; + + r->response.responseLength = 0; + strncpy(dirName, httpdRequestPath(r), HTTP_MAX_URL); + dirName[HTTP_MAX_URL-1]=0; + cp = strrchr(dirName, '/'); + if (cp == NULL) + { + printf("Invalid request path '%s'\n",dirName); + return; + } + strncpy(entryName, cp + 1, HTTP_MAX_URL); + entryName[HTTP_MAX_URL-1]=0; + if (cp != dirName) + *cp = 0; + else + *(cp+1) = 0; + dir = _httpd_findContentDir(server, dirName, HTTP_FALSE); + if (dir == NULL) + { + _httpd_send404(server, r); + _httpd_writeAccessLog(server, r); + return; + } + entry = _httpd_findContentEntry(r, dir, entryName); + if (entry == NULL) + { + _httpd_send404(server, r); + _httpd_writeAccessLog(server, r); + return; + } + if (entry->preload) + { + if ((entry->preload)(server) < 0) + { + _httpd_writeAccessLog(server, r); + return; + } + } + switch(entry->type) + { + case HTTP_C_FUNCT: + case HTTP_C_WILDCARD: + (entry->function)(server, r); + break; + + case HTTP_STATIC: + _httpd_sendStatic(server, r, entry->data); + break; + + case HTTP_FILE: + _httpd_sendFile(server, r, entry->path); + break; + + case HTTP_WILDCARD: + if (_httpd_sendDirectoryEntry(server, r, entry, + entryName)<0) + { + _httpd_send404(server, r); + } + break; + } + _httpd_writeAccessLog(server, r); +} + +void httpdSetAccessLog(server, fp) + httpd *server; + FILE *fp; +{ + server->accessLog = fp; +} + +void httpdSetErrorLog(server, fp) + httpd *server; + FILE *fp; +{ + server->errorLog = fp; +} + +void httpdAuthenticate(request *r, const char *realm) +{ + char buffer[255]; + + if (r->request.authLength == 0) + { + httpdSetResponse(r, "401 Please Authenticate"); + snprintf(buffer,sizeof(buffer), + "WWW-Authenticate: Basic realm=\"%s\"\n", realm); + httpdAddHeader(r, buffer); + httpdOutput(r,"\n"); + } +} + + +void httpdForceAuthenticate(request *r, const char *realm) +{ + char buffer[255]; + + httpdSetResponse(r, "401 Please Authenticate"); + snprintf(buffer,sizeof(buffer), + "WWW-Authenticate: Basic realm=\"%s\"\n", realm); + httpdAddHeader(r, buffer); + httpdOutput(r,"\n"); +} diff --git a/libhttpd/httpd.h b/libhttpd/httpd.h new file mode 100755 index 00000000..732a992b --- /dev/null +++ b/libhttpd/httpd.h @@ -0,0 +1,250 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** hUghes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +/* +** libhttpd Header File +*/ + + +/*********************************************************************** +** Standard header preamble. Ensure singular inclusion, setup for +** function prototypes and c++ inclusion +*/ + +#ifndef LIB_HTTPD_H + +#define LIB_HTTPD_H 1 + +#include + +#if !defined(__ANSI_PROTO) +#if defined(_WIN32) || defined(__STDC__) || defined(__cplusplus) +# define __ANSI_PROTO(x) x +#else +# define __ANSI_PROTO(x) () +#endif +#endif + +#ifndef u_int +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*********************************************************************** +** Macro Definitions +*/ + + +#define HTTP_PORT 80 +#define HTTP_MAX_LEN 10240 +#define HTTP_MAX_URL 1024 +#define HTTP_MAX_HEADERS 1024 +#define HTTP_MAX_AUTH 128 +#define HTTP_IP_ADDR_LEN 17 +#define HTTP_TIME_STRING_LEN 40 +#define HTTP_READ_BUF_LEN 4096 +#define HTTP_ANY_ADDR NULL + +#define HTTP_GET 1 +#define HTTP_POST 2 + +#define HTTP_TRUE 1 +#define HTTP_FALSE 0 + +#define HTTP_FILE 1 +#define HTTP_C_FUNCT 2 +#define HTTP_EMBER_FUNCT 3 +#define HTTP_STATIC 4 +#define HTTP_WILDCARD 5 +#define HTTP_C_WILDCARD 6 + +#define HTTP_METHOD_ERROR "\nERROR : Method Not Implemented\n\n" + +#define httpdRequestMethod(s) s->request.method +#define httpdRequestPath(s) s->request.path +#define httpdRequestContentType(s) s->request.contentType +#define httpdRequestContentLength(s) s->request.contentLength + +#define HTTP_ACL_PERMIT 1 +#define HTTP_ACL_DENY 2 + + + +extern char LIBHTTPD_VERSION[], + LIBHTTPD_VENDOR[]; + +/*********************************************************************** +** Type Definitions +*/ + +typedef struct { + int method, + contentLength, + authLength; + char path[HTTP_MAX_URL], + query[HTTP_MAX_URL], + host[HTTP_MAX_URL], /* acv@acv.ca/wifidog: Added decoding + of host: header if present. */ + ifModified[HTTP_MAX_URL]; +#if(0) + userAgent[HTTP_MAX_URL], + referer[HTTP_MAX_URL], + contentType[HTTP_MAX_URL], +#endif + char authUser[HTTP_MAX_AUTH]; + char authPassword[HTTP_MAX_AUTH]; +} httpReq; + + +typedef struct _httpd_var{ + char *name, + *value; + struct _httpd_var *nextValue, + *nextVariable; +} httpVar; + +typedef struct _httpd_content{ + char *name; + int type, + indexFlag; + void (*function)(); + char *data, + *path; + int (*preload)(); + struct _httpd_content *next; +} httpContent; + +typedef struct { + int responseLength; + httpContent *content; + char headersSent, + headers[HTTP_MAX_HEADERS], + response[HTTP_MAX_URL], + contentType[HTTP_MAX_URL]; +} httpRes; + + +typedef struct _httpd_dir{ + char *name; + struct _httpd_dir *children, + *next; + struct _httpd_content *entries; +} httpDir; + + +typedef struct ip_acl_s{ + int addr; + char len, + action; + struct ip_acl_s *next; +} httpAcl; + +typedef struct _httpd_404 { + void (*function)(); +} http404; + +typedef struct { + int port, + serverSock, + startTime, + lastError; + char fileBasePath[HTTP_MAX_URL], + *host; + httpDir *content; + httpAcl *defaultAcl; + http404 *handle404; + FILE *accessLog, + *errorLog; +} httpd; + +typedef struct { + int clientSock, + readBufRemain; + httpReq request; + httpRes response; + httpVar *variables; + char readBuf[HTTP_READ_BUF_LEN + 1], + *readBufPtr, + clientAddr[HTTP_IP_ADDR_LEN]; +} request; + +/*********************************************************************** +** Function Prototypes +*/ + + +int httpdAddCContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),void(*)())); +int httpdAddFileContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); +int httpdAddStaticContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); +int httpdAddWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),char*)); +int httpdAddCWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),void(*)())); +int httpdAddVariable __ANSI_PROTO((request*, const char*, const char*)); +request *httpdGetConnection __ANSI_PROTO((httpd*, struct timeval*)); +int httpdReadRequest __ANSI_PROTO((httpd*, request*)); +int httpdCheckAcl __ANSI_PROTO((httpd*, request *, httpAcl*)); +int httpdAddC404Content __ANSI_PROTO((httpd*,void(*)())); + +char *httpdRequestMethodName __ANSI_PROTO((request*)); +char *httpdUrlEncode __ANSI_PROTO((const char *)); + +void httpdAddHeader __ANSI_PROTO((request*, const char*)); +void httpdSetContentType __ANSI_PROTO((request*, const char*)); +void httpdSetResponse __ANSI_PROTO((request*, const char*)); +void httpdEndRequest __ANSI_PROTO((request*)); + +httpd *httpdCreate __ANSI_PROTO(()); +void httpdFreeVariables __ANSI_PROTO((request*)); +void httpdDumpVariables __ANSI_PROTO((request*)); +void httpdOutput __ANSI_PROTO((request*, const char*)); +void httpdPrintf __ANSI_PROTO((request*, const char*, ...)); +void httpdProcessRequest __ANSI_PROTO((httpd*, request *)); +void httpdSendHeaders __ANSI_PROTO((request*)); +void httpdSetFileBase __ANSI_PROTO((httpd*, const char*)); +void httpdSetCookie __ANSI_PROTO((request*, const char*, const char*)); + +void httpdSetErrorLog __ANSI_PROTO((httpd*, FILE*)); +void httpdSetAccessLog __ANSI_PROTO((httpd*, FILE*)); +void httpdSetDefaultAcl __ANSI_PROTO((httpd*, httpAcl*)); + +httpVar *httpdGetVariableByName __ANSI_PROTO((request*, const char*)); +httpVar *httpdGetVariableByPrefix __ANSI_PROTO((request*, const char*)); +httpVar *httpdGetVariableByPrefixedName __ANSI_PROTO((request*, const char*, const char*)); +httpVar *httpdGetNextVariableByPrefix __ANSI_PROTO((httpVar*, const char*)); + +httpAcl *httpdAddAcl __ANSI_PROTO((httpd*, httpAcl*, char*, int)); + +void httpdAuthenticate __ANSI_PROTO((request*, const char*)); +void httpdForceAuthenticate __ANSI_PROTO((request*, const char*)); + +/*********************************************************************** +** Standard header file footer. +*/ + +#ifdef __cplusplus + } +#endif /* __cplusplus */ +#endif /* file inclusion */ + + diff --git a/libhttpd/httpd_priv.h b/libhttpd/httpd_priv.h new file mode 100755 index 00000000..d6d067f6 --- /dev/null +++ b/libhttpd/httpd_priv.h @@ -0,0 +1,83 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +/* +** libhttpd Private Header File +*/ + + +/*********************************************************************** +** Standard header preamble. Ensure singular inclusion, setup for +** function prototypes and c++ inclusion +*/ + +#ifndef LIB_HTTPD_PRIV_H + +#define LIB_HTTPD_H_PRIV 1 + +#if !defined(__ANSI_PROTO) +#if defined(_WIN32) || defined(__STDC__) || defined(__cplusplus) +# define __ANSI_PROTO(x) x +#else +# define __ANSI_PROTO(x) () +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#define LEVEL_NOTICE "notice" +#define LEVEL_ERROR "error" + +char * _httpd_unescape __ANSI_PROTO((char*)); +char *_httpd_escape __ANSI_PROTO((const char*)); +char _httpd_from_hex __ANSI_PROTO((char)); + + +void _httpd_catFile __ANSI_PROTO((request*, char*)); +void _httpd_send403 __ANSI_PROTO((request*)); +void _httpd_send404 __ANSI_PROTO((httpd*, request*)); +void _httpd_sendText __ANSI_PROTO((request*, char*)); +void _httpd_sendFile __ANSI_PROTO((httpd*, request*, char*)); +void _httpd_sendStatic __ANSI_PROTO((httpd*, request *, char*)); +void _httpd_sendHeaders __ANSI_PROTO((request*, int, int);) +void _httpd_sanitiseUrl __ANSI_PROTO((char*)); +void _httpd_freeVariables __ANSI_PROTO((httpVar*)); +void _httpd_formatTimeString __ANSI_PROTO((char*, int)); +void _httpd_storeData __ANSI_PROTO((request*, char*)); +void _httpd_writeAccessLog __ANSI_PROTO((httpd*, request*)); +void _httpd_writeErrorLog __ANSI_PROTO((httpd*, request *, char*, char*)); + + +int _httpd_net_read __ANSI_PROTO((int, char*, int)); +int _httpd_net_write __ANSI_PROTO((int, char*, int)); +int _httpd_readBuf __ANSI_PROTO((request*, char*, int)); +int _httpd_readChar __ANSI_PROTO((request*, char*)); +int _httpd_readLine __ANSI_PROTO((request*, char*, int)); +int _httpd_checkLastModified __ANSI_PROTO((request*, int)); +int _httpd_sendDirectoryEntry __ANSI_PROTO((httpd*, request *r, httpContent*, + char*)); + +httpContent *_httpd_findContentEntry __ANSI_PROTO((request*, httpDir*, char*)); +httpDir *_httpd_findContentDir __ANSI_PROTO((httpd*, char*, int)); + +#endif /* LIB_HTTPD_PRIV_H */ diff --git a/libhttpd/ip_acl.c b/libhttpd/ip_acl.c new file mode 100755 index 00000000..87435f7d --- /dev/null +++ b/libhttpd/ip_acl.c @@ -0,0 +1,224 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +#include "config.h" + +#include +#include +#include + +#if defined(_WIN32) +#else +#include +#endif + +#include "httpd.h" +#include "httpd_priv.h" + + +/************************************************************************** +** GLOBAL VARIABLES +**************************************************************************/ + + +/************************************************************************** +** PRIVATE ROUTINES +**************************************************************************/ + +static int scanCidr(val, result, length) + char *val; + u_int *result, + *length; +{ + u_int res, res1, res2, res3, res4, res5; + char *cp; + + cp = val; + res1 = atoi(cp); + cp = strchr(cp,'.'); + if (!cp) + return(-1); + cp++; + res2 = atoi(cp); + cp = strchr(cp,'.'); + if (!cp) + return(-1); + cp++; + res3 = atoi(cp); + cp = strchr(cp,'.'); + if (!cp) + return(-1); + cp++; + res4 = atoi(cp); + cp = strchr(cp,'/'); + if (!cp) + { + res5 = 32; + } + else + { + cp++; + res5 = atoi(cp); + } + + if (res1>255 || res2>255 || res3>255 || res4>255 || res5>32) + { + return(-1); + } + res = (res1 << 24) + (res2 << 16) + (res3 << 8) + res4; + *result = res; + *length = res5; + return(0); +} + + +static int _isInCidrBlock(httpd *server, request *r, int addr1, int len1, + int addr2, int len2) +{ + int count, + mask; + + /* if (addr1 == 0 && len1 == 0) + { + return(1); + }*/ + + if(len2 < len1) + { + _httpd_writeErrorLog(server, r, LEVEL_ERROR, + "IP Address must be more specific than network block"); + return(0); + } + + mask = count = 0; + while(count < len1) + { + mask = (mask << 1) + 1; + count++; + } + mask = mask << (32 - len1); + if ( (addr1 & mask) == (addr2 & mask)) + { + return(1); + } + else + { + return(0); + } +} + + +/************************************************************************** +** PUBLIC ROUTINES +**************************************************************************/ + +httpAcl *httpdAddAcl(server, acl, cidr, action) + httpd *server; + httpAcl *acl; + char *cidr; + int action; +{ + httpAcl *cur; + int addr, + len; + + /* + ** Check the ACL info is reasonable + */ + if(scanCidr(cidr, &addr, &len) < 0) + { + _httpd_writeErrorLog(server, NULL, LEVEL_ERROR, + "Invalid IP address format"); + return(NULL); + } + if (action != HTTP_ACL_PERMIT && action != HTTP_ACL_DENY) + { + _httpd_writeErrorLog(server, NULL, LEVEL_ERROR, + "Invalid acl action"); + return(NULL); + } + + /* + ** Find a spot to put this ACE + */ + if (acl) + { + cur = acl; + while(cur->next) + { + cur = cur->next; + } + cur->next = (httpAcl*)malloc(sizeof(httpAcl)); + cur = cur->next; + } + else + { + cur = (httpAcl*)malloc(sizeof(httpAcl)); + acl = cur; + } + + /* + ** Add the details and return + */ + cur->addr = addr; + cur->len = len; + cur->action = action; + cur->next = NULL; + return(acl); +} + + +int httpdCheckAcl(httpd *server, request *r, httpAcl *acl) +{ + httpAcl *cur; + int addr, len, + res, + action; + + + action = HTTP_ACL_DENY; + scanCidr(r->clientAddr, &addr, &len); + cur = acl; + while(cur) + { + res = _isInCidrBlock(server, r, cur->addr, cur->len, addr, len); + if (res == 1) + { + action = cur->action; + break; + } + cur = cur->next; + } + if (action == HTTP_ACL_DENY) + { + _httpd_send403(r); + _httpd_writeErrorLog(server, r, LEVEL_ERROR, + "Access denied by ACL"); + } + return(action); +} + + +void httpdSetDefaultAcl(server, acl) + httpd *server; + httpAcl *acl; +{ + server->defaultAcl = acl; +} diff --git a/libhttpd/protocol.c b/libhttpd/protocol.c new file mode 100755 index 00000000..5528c59b --- /dev/null +++ b/libhttpd/protocol.c @@ -0,0 +1,791 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#else +#include +#include +#endif + +#include "config.h" +#include "httpd.h" +#include "httpd_priv.h" + +int _httpd_net_read(sock, buf, len) + int sock; + char *buf; + int len; +{ +#if defined(_WIN32) + return( recv(sock, buf, len, 0)); +#else + /*return( read(sock, buf, len));*/ + /* XXX Select based IO */ + + int nfds; + fd_set readfds; + struct timeval timeout; + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + timeout.tv_sec = 10; + timeout.tv_usec = 0; + nfds = sock + 1; + + nfds = select(nfds, &readfds, NULL, NULL, &timeout); + + if (nfds > 0) { + return(read(sock, buf, len)); + } + return(nfds); +#endif +} + + +int _httpd_net_write(sock, buf, len) + int sock; + char *buf; + int len; +{ +#if defined(_WIN32) + return( send(sock, buf, len, 0)); +#else + return( write(sock, buf, len)); +#endif +} + +int _httpd_readChar(request *r, char *cp) +{ + if (r->readBufRemain == 0) + { + bzero(r->readBuf, HTTP_READ_BUF_LEN + 1); + r->readBufRemain = _httpd_net_read(r->clientSock, + r->readBuf, HTTP_READ_BUF_LEN); + if (r->readBufRemain < 1) + return(0); + r->readBuf[r->readBufRemain] = 0; + r->readBufPtr = r->readBuf; + } + *cp = *r->readBufPtr++; + r->readBufRemain--; + return(1); +} + + +int _httpd_readLine(request *r, char *destBuf, int len) +{ + char curChar, + *dst; + int count; + + + count = 0; + dst = destBuf; + while(count < len) + { + if (_httpd_readChar(r, &curChar) < 1) + return(0); + // Fixed by Mina - if we read binary junk it's probably not a regular HTTP client + //if (curChar == '\n') + if (curChar == '\n' || !isascii(curChar)) + { + *dst = 0; + return(1); + } + if (curChar == '\r') + { + continue; + } + else + { + *dst++ = curChar; + count++; + } + } + *dst = 0; + return(1); +} + + +int _httpd_readBuf(request *r, char *destBuf, int len) +{ + char curChar, + *dst; + int count; + + + count = 0; + dst = destBuf; + while(count < len) + { + if (_httpd_readChar(r, &curChar) < 1) + return(0); + *dst++ = curChar; + count++; + } + return(1); +} + +void _httpd_writeAccessLog(httpd *server, request *r) +{ + char dateBuf[30]; + struct tm *timePtr; + time_t clock; + int responseCode; + + + if (server->accessLog == NULL) + return; + clock = time(NULL); + timePtr = localtime(&clock); + strftime(dateBuf, 30, "%d/%b/%Y:%T %Z", timePtr); + responseCode = atoi(r->response.response); + fprintf(server->accessLog, "%s - - [%s] %s \"%s\" %d %d\n", + r->clientAddr, dateBuf, httpdRequestMethodName(r), + httpdRequestPath(r), responseCode, + r->response.responseLength); +} + +void _httpd_writeErrorLog(httpd *server, request *r, char *level, char *message) +{ + char dateBuf[30]; + struct tm *timePtr; + time_t clock; + + + if (server->errorLog == NULL) + return; + clock = time(NULL); + timePtr = localtime(&clock); + strftime(dateBuf, 30, "%a %b %d %T %Y", timePtr); + if (r != NULL && *r->clientAddr != 0) + { + fprintf(server->errorLog, "[%s] [%s] [client %s] %s\n", + dateBuf, level, r->clientAddr, message); + } + else + { + fprintf(server->errorLog, "[%s] [%s] %s\n", + dateBuf, level, message); + } +} + + + +int _httpd_decode (bufcoded, bufplain, outbufsize) + char * bufcoded; + char * bufplain; + int outbufsize; +{ + static char six2pr[64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j','k','l','m', + 'n','o','p','q','r','s','t','u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9','+','/' + }; + + static unsigned char pr2six[256]; + + /* single character decode */ +# define DEC(c) pr2six[(int)c] +# define _DECODE_MAXVAL 63 + + static int first = 1; + + int nbytesdecoded, j; + register char *bufin = bufcoded; + register char *bufout = bufplain; + register int nprbytes; + + /* + ** If this is the first call, initialize the mapping table. + ** This code should work even on non-ASCII machines. + */ + if(first) + { + first = 0; + for(j=0; j<256; j++) pr2six[j] = _DECODE_MAXVAL+1; + for(j=0; j<64; j++) pr2six[(int)six2pr[j]] = (unsigned char)j; + } + + /* Strip leading whitespace. */ + + while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++; + + /* + ** Figure out how many characters are in the input buffer. + ** If this would decode into more bytes than would fit into + ** the output buffer, adjust the number of input bytes downwards. + */ + bufin = bufcoded; + while(pr2six[(int)*(bufin++)] <= _DECODE_MAXVAL); + nprbytes = bufin - bufcoded - 1; + nbytesdecoded = ((nprbytes+3)/4) * 3; + if(nbytesdecoded > outbufsize) + { + nprbytes = (outbufsize*4)/3; + } + bufin = bufcoded; + + while (nprbytes > 0) + { + *(bufout++)=(DEC(*bufin)<<2|DEC(bufin[1])>>4); + *(bufout++)=(DEC(bufin[1])<<4|DEC(bufin[2])>>2); + *(bufout++)=(DEC(bufin[2])<<6|DEC(bufin[3])); + bufin += 4; + nprbytes -= 4; + } + if(nprbytes & 03) + { + if(pr2six[(int)bufin[-2]] > _DECODE_MAXVAL) + { + nbytesdecoded -= 2; + } + else + { + nbytesdecoded -= 1; + } + } + bufplain[nbytesdecoded] = 0; + return(nbytesdecoded); +} + + + +char _httpd_from_hex (c) + char c; +{ + return c >= '0' && c <= '9' ? c - '0' + : c >= 'A' && c <= 'F'? c - 'A' + 10 + : c - 'a' + 10; /* accept small letters just in case */ +} + +char * _httpd_unescape(str) + char *str; +{ + char * p = str; + char * q = str; + static char blank[] = ""; + + if (!str) + return(blank); + while(*p) { + if (*p == '%') { + p++; + if (*p) *q = _httpd_from_hex(*p++) * 16; + if (*p) *q = (*q + _httpd_from_hex(*p++)); + q++; + } else { + if (*p == '+') { + *q++ = ' '; + p++; + } else { + *q++ = *p++; + } + } + } + + *q++ = 0; + return str; +} + + +void _httpd_freeVariables(var) + httpVar *var; +{ + httpVar *curVar, *lastVar; + + if (var == NULL) + return; + _httpd_freeVariables(var->nextVariable); + var->nextVariable = NULL; + curVar = var; + while(curVar) + { + lastVar = curVar; + curVar = curVar->nextValue; + free(lastVar->name); + free(lastVar->value); + free(lastVar); + } + return; +} + +void _httpd_storeData(request *r, char *query) +{ + char *cp, + *cp2, + *var, + *val, + *tmpVal; + + if (!query) + return; + + var = (char *)malloc(strlen(query)); + + cp = query; + cp2 = var; + bzero(var, strlen(query)); + val = NULL; + while(*cp) + { + if (*cp == '=') + { + cp++; + *cp2 = 0; + val = cp; + continue; + } + if (*cp == '&') + { + *cp = 0; + tmpVal = _httpd_unescape(val); + httpdAddVariable(r, var, tmpVal); + cp++; + cp2 = var; + val = NULL; + continue; + } + if (val) + { + cp++; + } + else + { + *cp2 = *cp++; + /* + if (*cp2 == '.') + { + strcpy(cp2,"_dot_"); + cp2 += 5; + } + else + { + */ + cp2++; + /* + } + */ + } + } + if (val != NULL) { + *cp = 0; + tmpVal = _httpd_unescape(val); + httpdAddVariable(r, var, tmpVal); + } + free(var); +} + + +void _httpd_formatTimeString(char *ptr, int clock) +{ + struct tm *timePtr; + time_t t; + + t = (clock == 0) ? time(NULL) : clock; + timePtr = gmtime(&t); + strftime(ptr, HTTP_TIME_STRING_LEN,"%a, %d %b %Y %T GMT",timePtr); +} + + +void _httpd_sendHeaders(request *r, int contentLength, int modTime) +{ + char tmpBuf[80], + timeBuf[HTTP_TIME_STRING_LEN]; + + if(r->response.headersSent) + return; + + r->response.headersSent = 1; + _httpd_net_write(r->clientSock, "HTTP/1.0 ", 9); + _httpd_net_write(r->clientSock, r->response.response, + strlen(r->response.response)); + _httpd_net_write(r->clientSock, r->response.headers, + strlen(r->response.headers)); + + _httpd_formatTimeString(timeBuf, 0); + _httpd_net_write(r->clientSock,"Date: ", 6); + _httpd_net_write(r->clientSock, timeBuf, strlen(timeBuf)); + _httpd_net_write(r->clientSock, "\n", 1); + + _httpd_net_write(r->clientSock, "Connection: close\n", 18); + _httpd_net_write(r->clientSock, "Content-Type: ", 14); + _httpd_net_write(r->clientSock, r->response.contentType, + strlen(r->response.contentType)); + _httpd_net_write(r->clientSock, "\n", 1); + + if (contentLength > 0) + { + _httpd_net_write(r->clientSock, "Content-Length: ", 16); + snprintf(tmpBuf, sizeof(tmpBuf), "%d", contentLength); + _httpd_net_write(r->clientSock, tmpBuf, strlen(tmpBuf)); + _httpd_net_write(r->clientSock, "\n", 1); + + _httpd_formatTimeString(timeBuf, modTime); + _httpd_net_write(r->clientSock, "Last-Modified: ", 15); + _httpd_net_write(r->clientSock, timeBuf, strlen(timeBuf)); + _httpd_net_write(r->clientSock, "\n", 1); + } + _httpd_net_write(r->clientSock, "\n", 1); +} + +httpDir *_httpd_findContentDir(server, dir, createFlag) + httpd *server; + char *dir; + int createFlag; +{ + char buffer[HTTP_MAX_URL], + *curDir; + httpDir *curItem, + *curChild; + + strncpy(buffer, dir, HTTP_MAX_URL); + buffer[HTTP_MAX_URL-1]=0; + curItem = server->content; + curDir = strtok(buffer,"/"); + while(curDir) + { + curChild = curItem->children; + while(curChild) + { + if (strcmp(curChild->name, curDir) == 0) + break; + curChild = curChild->next; + } + if (curChild == NULL) + { + if (createFlag == HTTP_TRUE) + { + curChild = malloc(sizeof(httpDir)); + bzero(curChild, sizeof(httpDir)); + curChild->name = strdup(curDir); + curChild->next = curItem->children; + curItem->children = curChild; + } + else + { + return(NULL); + } + } + curItem = curChild; + curDir = strtok(NULL,"/"); + } + return(curItem); +} + + +httpContent *_httpd_findContentEntry(request *r, httpDir *dir, char *entryName) +{ + httpContent *curEntry; + + curEntry = dir->entries; + while(curEntry) + { + if (curEntry->type == HTTP_WILDCARD || + curEntry->type ==HTTP_C_WILDCARD) + break; + if (*entryName == 0 && curEntry->indexFlag) + break; + if (strcmp(curEntry->name, entryName) == 0) + break; + curEntry = curEntry->next; + } + if (curEntry) + r->response.content = curEntry; + return(curEntry); +} + + +void _httpd_send304(request *r) +{ + httpdSetResponse(r, "304 Not Modified\n"); + _httpd_sendHeaders(r,0,0); +} + + +void _httpd_send403(request *r) +{ + httpdSetResponse(r, "403 Permission Denied\n"); + _httpd_sendHeaders(r,0,0); + _httpd_sendText(r, + "403 Permission Denied\n"); + _httpd_sendText(r, + "

Access to the request URL was denied!

\n"); +} + + +void _httpd_send404(httpd *server, request *r) +{ + char msg[HTTP_MAX_URL]; + + snprintf(msg, HTTP_MAX_URL, + "File does not exist: %s\n", r->request.path); + _httpd_writeErrorLog(server, r, LEVEL_ERROR, msg); + + if (server->handle404 && server->handle404->function) { + /* + * There's a custom C 404 handler defined with httpdAddC404Content + */ + (server->handle404->function)(server, r); + } + else { + /* + * Send stock 404 + */ + httpdSetResponse(r, "404 Not Found\n"); + _httpd_sendHeaders(r,0,0); + _httpd_sendText(r, + "404 Not Found\n"); + _httpd_sendText(r, + "

The request URL was not found!

\n"); + _httpd_sendText(r, "\n"); + } +} + + +void _httpd_catFile(request *r, char *path) +{ + int fd, + len; + char buf[HTTP_MAX_LEN]; + + fd = open(path,O_RDONLY); + if (fd < 0) + return; + len = read(fd, buf, HTTP_MAX_LEN); + while(len > 0) + { + r->response.responseLength += len; + _httpd_net_write(r->clientSock, buf, len); + len = read(fd, buf, HTTP_MAX_LEN); + } + close(fd); +} + + +void _httpd_sendStatic(httpd *server, request *r, char *data) +{ + if (_httpd_checkLastModified(r, server->startTime) == 0) + { + _httpd_send304(r); + } + _httpd_sendHeaders(r, server->startTime, strlen(data)); + httpdOutput(r, data); +} + + + +void _httpd_sendFile(httpd *server, request *r, char *path) +{ + char *suffix; + struct stat sbuf; + + suffix = strrchr(path, '.'); + if (suffix != NULL) + { + if (strcasecmp(suffix,".gif") == 0) + strcpy(r->response.contentType,"image/gif"); + if (strcasecmp(suffix,".jpg") == 0) + strcpy(r->response.contentType,"image/jpeg"); + if (strcasecmp(suffix,".xbm") == 0) + strcpy(r->response.contentType,"image/xbm"); + if (strcasecmp(suffix,".png") == 0) + strcpy(r->response.contentType,"image/png"); + } + if (stat(path, &sbuf) < 0) + { + _httpd_send404(server, r); + return; + } + if (_httpd_checkLastModified(r, sbuf.st_mtime) == 0) + { + _httpd_send304(r); + } + else + { + _httpd_sendHeaders(r, sbuf.st_size, sbuf.st_mtime); + _httpd_catFile(r, path); + } +} + + +int _httpd_sendDirectoryEntry(httpd *server, request *r, httpContent *entry, + char *entryName) +{ + char path[HTTP_MAX_URL]; + + snprintf(path, HTTP_MAX_URL, "%s/%s", entry->path, entryName); + _httpd_sendFile(server, r, path); + return(0); +} + + +void _httpd_sendText(request *r, char *msg) +{ + r->response.responseLength += strlen(msg); + _httpd_net_write(r->clientSock,msg,strlen(msg)); +} + + +int _httpd_checkLastModified(request *r, int modTime) +{ + char timeBuf[HTTP_TIME_STRING_LEN]; + + _httpd_formatTimeString(timeBuf, modTime); + if (strcmp(timeBuf, r->request.ifModified) == 0) + return(0); + return(1); +} + + +static unsigned char isAcceptable[96] = + +/* Overencodes */ +#define URL_XALPHAS (unsigned char) 1 +#define URL_XPALPHAS (unsigned char) 2 + +/* Bit 0 xalpha -- see HTFile.h +** Bit 1 xpalpha -- as xalpha but with plus. +** Bit 2 ... path -- as xpalpha but with / +*/ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + { 7,0,0,0,0,0,0,0,0,0,7,0,0,7,7,7, /* 2x !"#$%&'()*+,-./ */ + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0 }; /* 7X pqrstuvwxyz{\}~ DEL */ + +#define ACCEPTABLE(a) ( a>=32 && a<128 && ((isAcceptable[a-32]) & mask)) + +static char *hex = "0123456789ABCDEF"; + + +char *_httpd_escape(str) + const char *str; +{ + unsigned char mask = URL_XPALPHAS; + const char * p; + char * q; + char * result; + int unacceptable = 0; + for(p=str; *p; p++) + if (!ACCEPTABLE((unsigned char)*p)) + unacceptable +=2; + result = (char *) malloc(p-str + unacceptable + 1); + bzero(result,(p-str + unacceptable + 1)); + + if (result == NULL) + { + return(NULL); + } + for(q=result, p=str; *p; p++) { + unsigned char a = *p; + if (!ACCEPTABLE(a)) { + *q++ = '%'; /* Means hex commming */ + *q++ = hex[a >> 4]; + *q++ = hex[a & 15]; + } + else *q++ = *p; + } + *q++ = 0; /* Terminate */ + return result; +} + + + +void _httpd_sanitiseUrl(url) + char *url; +{ + char *from, + *to, + *last; + + /* + ** Remove multiple slashes + */ + from = to = url; + while(*from) + { + if (*from == '/' && *(from+1) == '/') + { + from++; + continue; + } + *to = *from; + to++; + from++; + } + *to = 0; + + + /* + ** Get rid of ./ sequences + */ + from = to = url; + while(*from) + { + if (*from == '/' && *(from+1) == '.' && *(from+2)=='/') + { + from += 2; + continue; + } + *to = *from; + to++; + from++; + } + *to = 0; + + + /* + ** Catch use of /../ sequences and remove them. Must track the + ** path structure and remove the previous path element. + */ + from = to = last = url; + while(*from) + { + if (*from == '/' && *(from+1) == '.' && + *(from+2)=='.' && *(from+3)=='/') + { + to = last; + from += 3; + continue; + } + if (*from == '/') + { + last = to; + } + *to = *from; + to++; + from++; + } + *to = 0; +} diff --git a/libhttpd/version.c b/libhttpd/version.c new file mode 100755 index 00000000..f88c8b5d --- /dev/null +++ b/libhttpd/version.c @@ -0,0 +1,23 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +char LIBHTTPD_VERSION[] = "1.3", + LIBHTTPD_VENDOR[] = "Hughes Technologies Pty Ltd"; + diff --git a/scripts/Copy of white_black_flush.sh b/scripts/Copy of white_black_flush.sh new file mode 100644 index 00000000..aa0faa3e --- /dev/null +++ b/scripts/Copy of white_black_flush.sh @@ -0,0 +1,95 @@ +#!/bin/sh +run=`pidof wifidog` +gateway_id=$(uci get wifidog_conf.single.gatewayId | awk '{print $NF}') +gateway_interface=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $NF}') +gateway_eninterface=$(uci get wifidog_conf.single.externalInterface | awk '{printf $NF}') +gateway_hostname=$(uci get wifidog_conf.authServer.hostname | awk '{print $NF}') +gateway_httpport=$(uci get wifidog_conf.authServer.httpPort | awk '{print $NF}') +gateway_path=$(uci get wifidog_conf.authServer.path | awk '{print $NF}') +gateway_connmax=$(uci get get wifidog_conf.single) +ssl_enable=$(uci get wifidog.@wifidog[0].ssl_enable) +check_interval=$(uci get wifidog.@wifidog[0].check_interval) +client_timeout=$(uci get wifidog.@wifidog[0].client_timeout) +sslport=$(uci get wifidog.@wifidog[0].sslport) +deamo_enable=$(uci get wifidog.@wifidog[0].deamo_enable) +gatewayport=$(uci get wifidog.@wifidog[0].gatewayport) +myz_mac=$(uci get wifidog.@wifidog[0].myz_mac) +whiteList=$(uci get wifidog.@wifidog[0].bmd_url) +blackList=$(uci get wifidog.@wifidog[0].hmd_url) +whiteList=`echo $tbmd_url | tr " " ","` +blackList=`echo $thmd_url | tr " " ","` +#touch files +mkdir -p /tmp/.white_black_list + +#compare +while [ true ] +do + #detect + iptables -t nat -L WiFiDog_"$gateway_interface"_WhiteList -n --line-numbers|awk '{for(i=6;i $RESULT_FILE +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",")" +RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" +uci show wireless > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"lan\":{" +uci show network.lan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"wan\":{" +uci show network.wan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"dhcp\":{" +uci show dhcp > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," +RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}]}} + +rm $TMP $STMP +echo $RESULT > $RESULT_FILE + + diff --git a/scripts/GET_settings~ b/scripts/GET_settings~ new file mode 100755 index 00000000..0ddaf4ba --- /dev/null +++ b/scripts/GET_settings~ @@ -0,0 +1,48 @@ +#!/bin/sh +# +# description: get the settings of wireless, +# lan,wan,reboot_info and dhcp. +# use in OpenWrt router,based on uci. +# Version: 1.0.0 +# Author: GaomingPan +# 2015-07-29 +# +# Pram: $1 gw_id +# $2 cmd_id +# +TMP=/tmp/.tmpfile +STMP=/tmp/.stmpfile +RESULT_FILE=/tmp/routersettings +RESULT="" +echo "" > $RESULT_FILE +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",")" +RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" +uci show wireless > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"lan\":{" +uci show network.lan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"wan\":{" +uci show network.wan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"dhcp\":{" +uci show dhcp > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," +RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}]}} + +rm $TMP $STMP +echo $RESULT > $RESULT_FILE + + diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf new file mode 100644 index 00000000..1bacbebe --- /dev/null +++ b/scripts/conf/dog_post_conf @@ -0,0 +1,9 @@ + +config dog_post 'url' + option 'info_url' 'http://118.118.118.180:8080/wifidog/TestWge' + option 'normal_url' 'http://118.118.118.180:8080/wifidog/TestWge' + +config dog_post 'rmflag' + option 'info_rmflag' 'TestWget' + option 'normal_rmflag' 'TestWget' + diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf new file mode 100644 index 00000000..0bc58b3d --- /dev/null +++ b/scripts/conf/wifidog_conf @@ -0,0 +1,73 @@ +package 'wifidog_conf' + +config 'wifidog_conf' 'single' + option gatewayId 'GatewayID wifiauth_001' + option externalInterface '# ExternalInterface eth0' + option gatewayInterface 'GatewayInterface br-lan' + option gatewayAddress '# GatewayAddress 192.168.1.1' + option htmlMessageFile '# HtmlMessageFile /opt/wifidog/etc/wifidog-.html' + option daemon '# Deamon 1' + option gatewayPort '# GatewayPort 2060' + option proxyPort '# ProxyPort 0' + option httpdName '# HTTPDName WiFiDog' + option httpdMaxConn '# HTTPDMaxConn' + option httpdRealm '# HTTPDRealm WiFiDog' + option httpdUserName '# HTTPDUserName admin' + option httpdPassword '# HTTPDPassword secret' + option checkInterval '# CheckInterval 60' + option clientTimeout 'ClientTimeout 5' + + +config 'wifidog_conf' 'authServer' + option 'hostname' 'Hostname 118.118.118.8' + option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' + option 'sslPort' '# SSLPort (Optional;Default:443)' + option 'httpPort' 'HTTPPort 8080' + option 'path' 'Path /WiFiAuth/wifidog/' + option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' + option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' + option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'pingScriptPathFragment' '# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'authScriptPathFragment' '# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.)' + +config 'wifidog_conf' 'trustedMACList' + option 'enable' '1' + list 'TrustedMACList' '11:22:33:44:55:66' + list 'TrustedMACList' 'aa:bb:cc:dd:ee:ff' + +config 'wifidog_conf' 'untrustedMACList' + option 'enable' '1' + list 'UntrustedMACList' 'a0:ec:80:ba:90:dc' + list 'UntrustedMACList' 'aa:bb:cc:dd:ee:ff' + + +config 'wifidog_conf' 'whiteBlackList' + option 'white_enable' '1' + option 'black_enable' '1' + list 'WhiteList' 'www.baidu.com' + list 'WhiteList' 'www.taobao.com' + list 'BlackList' 'www.google.com' + list 'BlackList' 'www.hao123.com' + + +config 'wifidog_conf' 'firewallRule_global' + list 'FirewallRuleSet_global' '# FirewallRule block to 192.168.0.0/16 L' + list 'FirewallRuleSet_global' '# FirewallRule block to 172.16.0.0/12 L' + + +config 'wifidog_conf' 'firewallRule_validating_users' + list 'FirewallRuleSet_validating_users' 'FirewallRule allow to 0.0.0.0/0 L' + + +config 'wifidog_conf' 'firewallRule_known_users' + list 'FirewallRuleSet_known_users' 'FirewallRule allow to 0.0.0.0/0 L' + +config 'wifidog_conf' 'firewallRule_unknown_users' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 67 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 67 L' + +config 'wifidog_conf' 'firewallRule_locked_users' + list 'FirewallRuleSet_locked_users' 'FirewallRule block to 0.0.0.0/0 L' + diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh new file mode 100644 index 00000000..810926e3 --- /dev/null +++ b/scripts/dog_conf_generator.sh @@ -0,0 +1,167 @@ +#!/bin/sh +# +# Generates the wifidog config file based on UCI +# +# Author : GaomingPan +# Date : 2015-08-05 +# Version: 1.0.0 +# +########################################################## + +WIFI_DOG_CONF_FILE=/etc/wifidog.conf +WIFI_DOG_CONF=/etc/config/wifidog_conf +SINGLE=wifidog_conf.single +AUTH_SERVER=wifidog_conf.authServer +TRUSTED_MAC_LIST=wifidog_conf.trustedMACList +UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList +WHITE_LIST=wifidog_conf.whiteBlackList +BLACK_LIST=wifidog_conf.whiteBlackList +FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global +FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users +FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users +FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users +FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users + + +generate_single() +{ + echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE +} + +generate_authServer() +{ + echo "AuthServer {" >> $WIFI_DOG_CONF_FILE + echo "$(uci show $AUTH_SERVER | sed 1d | \ + awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_trustedMACList() +{ + enable=$(uci get "$TRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_untrustedMACList() +{ + enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_whiteList() +{ + white_enable=$(uci get "$WHITE_LIST.white_enable") + + if [ $white_enable -ne 1 ] + then + return + fi + + echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_blackList() +{ + black_enable=$(uci get "$BLACK_LIST.black_enable") + + if [ $black_enable -ne 1 ] + then + return + fi + + echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_global() +{ + echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + + +generate_firewallRule_validating_users() +{ + echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_known_users() +{ + echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_unknown_users() +{ + echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_locked_users() +{ + echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_wifidog_conf_file() +{ + echo "#############################################" > $WIFI_DOG_CONF_FILE + echo "## this is wifidog config file ###" >> $WIFI_DOG_CONF_FILE + echo "## auto generate by dog_conf_generator.sh ###" >> $WIFI_DOG_CONF_FILE + echo "## Version: 1.0.0 Based on UCI ###" >> $WIFI_DOG_CONF_FILE + echo "#############################################" >> $WIFI_DOG_CONF_FILE + generate_single + generate_authServer + generate_trustedMACList + generate_untrustedMACList + generate_whiteList + generate_blackList + generate_firewallRule_global + generate_firewallRule_validating_users + generate_firewallRule_known_users + generate_firewallRule_unknown_users + generate_firewallRule_locked_users + +#### +# delete the blank character at the line header + sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE + +#### +# delete the blank character at the line tail + sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE +} + +# +#echo "----- start generate ---------" +# +generate_wifidog_conf_file + +# +#echo "------ generate ok ----------" +# diff --git a/scripts/init.d/wifidog b/scripts/init.d/wifidog new file mode 100755 index 00000000..f5447651 --- /dev/null +++ b/scripts/init.d/wifidog @@ -0,0 +1,201 @@ +#!/bin/sh +# +# Could be better, but it's working as expected +# +# +# +# chkconfig: 345 65 35 +# +# description: Startup/shutdown script for Wifidog captive portal +# processname: wifidog + +# Date : 2004-08-25 +# Version : 1.0 + +IPT=/usr/sbin/iptables +WD_DIR=/usr/bin +OPTIONS="" + +case "$1" in + start) + echo "Starting Wifidog ... " + if $WD_DIR/wdctl status 2> /dev/null + then + echo "FAILED: Wifidog already running" + else + $0 test-module + if $WD_DIR/wifidog $OPTIONS + then + echo "OK" + else + echo "FAILED: Wifidog exited with non 0 status" + fi + fi + ;; + restart) + $0 stop + sleep 2 + $0 start + ;; + reload) + $0 stop + sleep 2 + $0 start + ;; + stop) + echo "Stopping Wifidog ... " + if $WD_DIR/wdctl status 2> /dev/null + then + if $WD_DIR/wdctl stop + then + echo "OK" + else + echo "FAILED: wdctl stop exited with non 0 status" + fi + + else + echo "FAILED: Wifidog was not running" + fi + ;; + status) + $WD_DIR/wdctl status + ;; + debug|test-module) + + ### Test ipt_mark with iptables + test_ipt_mark () { + IPTABLES_OK=$($IPT -A FORWARD -m mark --mark 2 -j ACCEPT 2>&1 | grep "No chain.target.match") + if [ -z "$IPTABLES_OK" ]; then + $IPT -D FORWARD -m mark --mark 2 -j ACCEPT 2>&1 + echo 1 + else + echo 0 + fi + } + ### Test ipt_mac with iptables + test_ipt_mac () { + IPTABLES_OK=$($IPT -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1 | grep "No chain.target.match") + if [ -z "$IPTABLES_OK" ]; then + $IPT -D INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1 + echo 1 + else + echo 0 + fi + } + + ### Test ipt_REDIRECT with iptables + test_ipt_REDIRECT () { + IPTABLES_OK=$($IPT -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 2060 2>&1 | grep "No chain.target.match") + if [ -z "$IPTABLES_OK" ]; then + $IPT -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 2060 2>&1 + echo 1 + else + echo 0 + fi + } + + ### Find a module on disk + module_exists () { + echo " Looking for a module on disk" + EXIST=$(find /lib/modules/`uname -r` -name $1.*o 2>/dev/null) + if [ -n "$EXIST" ]; then + echo 1 + else + echo 0 + fi + } + + ### Test if a module is in memory + module_in_memory () { + MODULE=$(lsmod | grep $1 | awk '{print $1}') + if [ "$MODULE" = "$1" ]; then + echo 1 + else + echo 0 + fi + } + + echo "Testing for iptables modules" + + echo " Testing ipt_mac" + TEST_IPT_MAC=$(test_ipt_mac) + if [ "$TEST_IPT_MAC" = "0" ]; then + echo " iptables is not working with ipt_mac" + echo " Scanning disk for ipt_mac module" + TEST_IPT_MAC_MODULE_EXISTS=$(module_exists "ipt_mac") + if [ "$TEST_IPT_MAC_MODULE_EXISTS" = "0" ]; then + echo " ipt_mac module is missing, please install it (kernel or module)" + exit + else + echo " ipt_mac module exists, trying to load" + insmod ipt_mac > /dev/null + TEST_IPT_MAC_MODULE_MEMORY=$(module_in_memory "ipt_mac") + if [ "$TEST_IPT_MAC_MODULE_MEMORY" = "0" ]; then + echo " Error: ipt_mac not loaded" + exit + else + echo " ipt_mac loaded sucessfully" + fi + fi + else + echo " ipt_mac module is working" + fi + + echo " Testing ipt_mark" + TEST_IPT_MARK=$(test_ipt_mark) + if [ "$TEST_IPT_MARK" = "0" ]; then + echo " iptables is not working with ipt_mark" + echo " Scanning disk for ipt_mark module" + TEST_IPT_MARK_MODULE_EXISTS=$(module_exists "ipt_mark") + if [ "$TEST_IPT_MARK_MODULE_EXISTS" = "0" ]; then + echo " iptables ipt_mark module missing, please install it (kernel or module)" + exit + else + echo " ipt_mark module exists, trying to load" + insmod ipt_mark + TEST_IPT_MARK_MODULE_MEMORY=$(module_in_memory "ipt_mark") + if [ "$TEST_IPT_MARK_MODULE_MEMORY" = "0" ]; then + echo " Error: ipt_mark not loaded" + exit + else + echo " ipt_mark loaded sucessfully" + fi + fi + else + echo " ipt_mark module is working" + fi + +##TODO: This will not test if required iptables userspace (iptables-mod-nat on Kamikaze) is installed + echo " Testing ipt_REDIRECT" + TEST_IPT_MAC=$(test_ipt_REDIRECT) + if [ "$TEST_IPT_MAC" = "0" ]; then + echo " iptables is not working with ipt_REDIRECT" + echo " Scanning disk for ipt_REDIRECT module" + TEST_IPT_MAC_MODULE_EXISTS=$(module_exists "ipt_REDIRECT") + if [ "$TEST_IPT_MAC_MODULE_EXISTS" = "0" ]; then + echo " ipt_REDIRECT module is missing, please install it (kernel or module)" + exit + else + echo " ipt_REDIRECT module exists, trying to load" + insmod ipt_REDIRECT > /dev/null + TEST_IPT_MAC_MODULE_MEMORY=$(module_in_memory "ipt_REDIRECT") + if [ "$TEST_IPT_MAC_MODULE_MEMORY" = "0" ]; then + echo " Error: ipt_REDIRECT not loaded" + exit + else + echo " ipt_REDIRECT loaded sucessfully" + fi + fi + else + echo " ipt_REDIRECT module is working" + fi + + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|status|test-module}" + exit 1 + ;; +esac + + diff --git a/scripts/white_black_flush.sh b/scripts/white_black_flush.sh new file mode 100644 index 00000000..3794e163 --- /dev/null +++ b/scripts/white_black_flush.sh @@ -0,0 +1,95 @@ +#!/bin/sh +run=`pidof wifidog` +gateway_id=$(uci get wifidog.@wifidog[0].gateway_id) +gateway_interface=$(uci get wifidog.@wifidog[0].gateway_interface) +gateway_eninterface=$(uci get wifidog.@wifidog[0].gateway_eninterface) +gateway_hostname=$(uci get wifidog.@wifidog[0].gateway_hostname) +gateway_httpport=$(uci get wifidog.@wifidog[0].gateway_httpport) +gateway_path=$(uci get wifidog.@wifidog[0].gateway_path) +gateway_connmax=$(uci get wifidog.@wifidog[0].gateway_connmax) +ssl_enable=$(uci get wifidog.@wifidog[0].ssl_enable) +check_interval=$(uci get wifidog.@wifidog[0].check_interval) +client_timeout=$(uci get wifidog.@wifidog[0].client_timeout) +sslport=$(uci get wifidog.@wifidog[0].sslport) +deamo_enable=$(uci get wifidog.@wifidog[0].deamo_enable) +gatewayport=$(uci get wifidog.@wifidog[0].gatewayport) +myz_mac=$(uci get wifidog.@wifidog[0].myz_mac) +tbmd_url=$(uci get wifidog.@wifidog[0].bmd_url) +thmd_url=$(uci get wifidog.@wifidog[0].hmd_url) +bmd_url=`echo $tbmd_url | tr " " ","` +hmd_url=`echo $thmd_url | tr " " ","` +#touch files +mkdir -p /tmp/.white_black_list + +#compare +while [ true ] +do + #detect + iptables -t nat -L WiFiDog_"$gateway_interface"_WhiteList -n --line-numbers|awk '{for(i=6;i> /etc/wifidog.conf +} + +start() { + wifidog_enable=$(uci get wifidog.@wifidog[0].wifidog_enable) + stop; + [ "$wifidog_enable" -eq 0 ] && exit 0 + sleep 1 + config_load + /usr/bin/wifidog-init start + if [ "$white_black_enable" -eq 1 ]; then + sleep 1 + /usr/lm/script/white_black_flush.sh & + fi +} + +stop() { + /usr/bin/wifidog-init stop + sleep 1 + rst=`ps | grep white_black | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi +} + +status() { + /usr/bin/wifidog-init status +} + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 00000000..7fc90f17 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,61 @@ +# +# $Id$ +# + +bin_PROGRAMS = wifidog \ + wdctl + +AM_CPPFLAGS = \ + -I${top_srcdir}/libhttpd/ \ + -DSYSCONFDIR='"$(sysconfdir)"' +wifidog_LDADD = $(top_builddir)/libhttpd/libhttpd.la + +# +#@breif GaomingPan add file: +# get_devinfo.h get_devinfo.c +# shell_command.h +# get_clientinfo.h get_clientinfo.c +# get_remote_shell.h get_remote_shell.c +# +wifidog_SOURCES = commandline.c \ + conf.c \ + debug.c \ + fw_iptables.c \ + firewall.c \ + gateway.c \ + centralserver.c \ + http.c \ + auth.c \ + client_list.c \ + util.c \ + wdctl_thread.c \ + ping_thread.c \ + safe.c \ + httpd_thread.c \ + get_devinfo.c \ + get_clientinfo.c \ + get_remote_shell.c + +noinst_HEADERS = commandline.h \ + common.h \ + conf.h \ + debug.h \ + fw_iptables.h \ + firewall.h \ + gateway.h \ + centralserver.h \ + http.h \ + auth.h \ + client_list.h \ + util.h \ + wdctl_thread.h \ + wdctl.h \ + ping_thread.h \ + safe.h \ + httpd_thread.h \ + shell_command.h \ + get_devinfo.h \ + get_clientinfo.h \ + get_remote_shell.h + +wdctl_SOURCES = wdctl.c diff --git a/src/auth.c b/src/auth.c new file mode 100755 index 00000000..fd78ddb2 --- /dev/null +++ b/src/auth.c @@ -0,0 +1,224 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file auth.c + @brief Authentication handling thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" +#include "http.h" +#include "safe.h" +#include "conf.h" +#include "debug.h" +#include "auth.h" +#include "centralserver.h" +#include "fw_iptables.h" +#include "firewall.h" +#include "client_list.h" +#include "util.h" + +/* Defined in clientlist.c */ +extern pthread_mutex_t client_list_mutex; + +/* Defined in util.c */ +extern long served_this_session; + +/** Launches a thread that periodically checks if any of the connections has timed out +@param arg Must contain a pointer to a string containing the IP adress of the client to check to check +@todo Also pass MAC adress? +@todo This thread loops infinitely, need a watchdog to verify that it is still running? +*/ +void +thread_client_timeout_check(const void *arg) +{ + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + + while (1) { + /* Sleep for config.checkinterval seconds... */ + timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; + timeout.tv_nsec = 0; + + /* Mutex must be locked for pthread_cond_timedwait... */ + pthread_mutex_lock(&cond_mutex); + + /* Thread safe "sleep" */ + pthread_cond_timedwait(&cond, &cond_mutex, &timeout); + + /* No longer needs to be locked */ + pthread_mutex_unlock(&cond_mutex); + + debug(LOG_DEBUG, "Running fw_counter()"); + + fw_sync_with_authserver(); + } +} + +/** Authenticates a single client against the central server and returns when done + * Alters the firewall rules depending on what the auth server says +@param r httpd request struct +*/ +void +authenticate_client(request *r) +{ + t_client *client; + t_authresponse auth_response; + char *mac, + *token; + char *urlFragment = NULL; + s_config *config = NULL; + t_auth_serv *auth_server = NULL; + + LOCK_CLIENT_LIST(); + + client = client_list_find_by_ip(r->clientAddr); + + if (client == NULL) { + debug(LOG_ERR, "authenticate_client(): Could not find client for %s", r->clientAddr); + UNLOCK_CLIENT_LIST(); + return; + } + + mac = safe_strdup(client->mac); + token = safe_strdup(client->token); + + UNLOCK_CLIENT_LIST(); + + /* + * At this point we've released the lock while we do an HTTP request since it could + * take multiple seconds to do and the gateway would effectively be frozen if we + * kept the lock. + */ + auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0); + + LOCK_CLIENT_LIST(); + + /* can't trust the client to still exist after n seconds have passed */ + client = client_list_find(r->clientAddr, mac); + + if (client == NULL) { + debug(LOG_ERR, "authenticate_client(): Could not find client node for %s (%s)", r->clientAddr, mac); + UNLOCK_CLIENT_LIST(); + free(token); + free(mac); + return; + } + + free(token); + free(mac); + + /* Prepare some variables we'll need below */ + config = config_get_config(); + auth_server = get_auth_server(); + + switch(auth_response.authcode) { + + case AUTH_ERROR: + /* Error talking to central server */ + debug(LOG_ERR, "Got %d from central server authenticating token %s from %s at %s", auth_response, client->token, client->ip, client->mac); + send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server"); + break; + + case AUTH_DENIED: + /* Central server said invalid token */ + debug(LOG_INFO, "Got DENIED from central server authenticating token %s from %s at %s - deleting from firewall and redirecting them to denied message", client->token, client->ip, client->mac); + fw_deny(client->ip, client->mac, FW_MARK_KNOWN); + safe_asprintf(&urlFragment, "%smessage=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_DENIED + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message"); + free(urlFragment); + break; + + case AUTH_VALIDATION: + /* They just got validated for X minutes to check their email */ + debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s" + "- adding to firewall and redirecting them to activate message", client->token, + client->ip, client->mac); + client->fw_connection_state = FW_MARK_PROBATION; + fw_allow(client->ip, client->mac, FW_MARK_PROBATION); + safe_asprintf(&urlFragment, "%smessage=%s&gw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_ACTIVATE_ACCOUNT, + config->gw_id, + config->gw_address, + client->mac + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message"); + free(urlFragment); + break; + + case AUTH_ALLOWED: + /* Logged in successfully as a regular account */ + debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - " + "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac); + client->fw_connection_state = FW_MARK_KNOWN; + fw_allow(client->ip, client->mac, FW_MARK_KNOWN); + served_this_session++; + safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_portal_script_path_fragment, + config->gw_id, + config->gw_address, + client->mac + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); + free(urlFragment); + break; + + case AUTH_VALIDATION_FAILED: + /* Client had X minutes to validate account by email and didn't = too late */ + debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s " + "- redirecting them to failed_validation message", client->token, client->ip, client->mac); + safe_asprintf(&urlFragment, "%smessage=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message"); + free(urlFragment); + break; + + default: + debug(LOG_WARNING, "I don't know what the validation code %d means for token %s from %s at %s - sending error message", auth_response.authcode, client->token, client->ip, client->mac); + send_http_page(r, "Internal Error", "We can not validate your request at this time"); + break; + + } + + UNLOCK_CLIENT_LIST(); + return; +} + + diff --git a/src/auth.h b/src/auth.h new file mode 100755 index 00000000..89de88ce --- /dev/null +++ b/src/auth.h @@ -0,0 +1,61 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file auth.h + @brief Authentication handling thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _AUTH_H_ +#define _AUTH_H_ + +#include "httpd.h" + +/** + * @brief Authentication codes returned by auth server. + * + * Authentication result codes returned by auth_server_request() corresponding + * to result code from the central server itself. + */ +typedef enum { + AUTH_ERROR = -1, /**< An error occured during the validation process*/ + AUTH_DENIED = 0, /**< Client was denied by the auth server */ + AUTH_ALLOWED = 1, /**< Client was granted access by the auth server */ + AUTH_VALIDATION = 5, /**< A misnomer. Client is in 15 min probation to validate his new account */ + AUTH_VALIDATION_FAILED = 6, /**< Client had X minutes to validate account by email and didn't = too late */ + AUTH_LOCKED = 254 /**< Account has been locked */ +} t_authcode; + +/** + * @brief This structure contains all the information returned by the authentication server + */ +typedef struct _t_authresponse { + t_authcode authcode; /**< Authentication code returned by the server */ +} t_authresponse; + + +/** @brief Authenticate a single client against the central server */ +void authenticate_client(request *); + +/** @brief Periodically check if connections expired */ +void thread_client_timeout_check(const void *arg); + +#endif diff --git a/src/centralserver.c b/src/centralserver.c new file mode 100755 index 00000000..082460ca --- /dev/null +++ b/src/centralserver.c @@ -0,0 +1,446 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @file centralserver.c + @brief Functions to talk to the central server (auth/send stats/get rules/etc...) + @author Copyright (C) 2004 Philippe April + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" + +#include "common.h" +#include "safe.h" +#include "util.h" +#include "auth.h" +#include "conf.h" +#include "debug.h" +#include "centralserver.h" +#include "firewall.h" +#include "../config.h" + +#include "client_list.h" + +/** + * include my header file. + */ +#include "get_clientinfo.h" +extern pthread_mutex_t client_list_mutex; + +extern pthread_mutex_t config_mutex; + +/** Initiates a transaction with the auth server, either to authenticate or to + * update the traffic counters at the server +@param authresponse Returns the information given by the central server +@param request_type Use the REQUEST_TYPE_* defines in centralserver.h +@param ip IP adress of the client this request is related to +@param mac MAC adress of the client this request is related to +@param token Authentification token of the client +@param incoming Current counter of the client's total incoming traffic, in bytes +@param outgoing Current counter of the client's total outgoing traffic, in bytes +*/ +t_authcode +auth_server_request(t_authresponse *authresponse, const char *request_type, const char *ip, const char *mac, const char *token, unsigned long long int incoming, unsigned long long int outgoing) +{ + int sockfd; + ssize_t numbytes; + size_t totalbytes; + char buf[MAX_BUF]; + char *tmp; + char *safe_token; + int done, nfds; + fd_set readfds; + struct timeval timeout; + t_auth_serv *auth_server = NULL; + auth_server = get_auth_server(); + + /* Blanket default is error. */ + authresponse->authcode = AUTH_ERROR; + + sockfd = connect_auth_server(); + if (sockfd == -1) { + /* Could not connect to any auth server */ + return (AUTH_ERROR); + } + + /** + * TODO: XXX change the PHP so we can harmonize stage as request_type + * everywhere. + */ + memset(buf, 0, sizeof(buf)); + safe_token=httpdUrlEncode(token); + + /** + * here I add some my info about the client. + */ + t_clientinfo *client_info; + long online_time; + + if(0 != collect_client_info()) + { + debug(LOG_ERR,"ERROR: at collect_client_info() failed."); + printf("ERROR: at collect_client_info() failed.\n"); + } + //client_info = get_client_info_by_ip(ip); + client_info = get_client_info_by_mac(mac); + if(NULL == client_info) + { + //debug(LOG_ERR,"ERROR: at get_client_info_by_ip(ip) failed."); + debug(LOG_ERR,"ERROR: at get_client_info_by_mac(mac) failed."); + //printf("ERROR: at get_client_info_by_ip(ip) failed.\n"); + } + + LOCK_CLIENT_LIST(); + online_time = get_online_time(ip,mac); + UNLOCK_CLIENT_LIST(); + + /******************************************/ + + + + if(NULL != client_info) + { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, + safe_token, + incoming, + outgoing, + config_get_config()->gw_id, + + /**************************** + * my new info. + * */ + client_info->host_name, + client_info->go_speed, + client_info->come_speed, + online_time, + get_client_auth_flag(), + /**************************/ + + VERSION, + auth_server->authserv_hostname + ); + } + else + { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, + safe_token, + incoming, + outgoing, + config_get_config()->gw_id, + + + /**************************** + * my new info. + * */ + "null",//client_info->host_name, + -1, //client_info->go_speed, + -1, //client_info->come_speed, + -1, //online_time, + get_client_auth_flag(), + /**************************/ + + VERSION, + auth_server->authserv_hostname + ); + } + + free(safe_token); + + debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf); + send(sockfd, buf, strlen(buf), 0); + + debug(LOG_DEBUG, "Reading response"); + numbytes = totalbytes = 0; + done = 0; + do { + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + timeout.tv_sec = 30; /* XXX magic... 30 second is as good a timeout as any */ + timeout.tv_usec = 0; + nfds = sockfd + 1; + + nfds = select(nfds, &readfds, NULL, NULL, &timeout); + + if (nfds > 0) { + /** We don't have to use FD_ISSET() because there + * was only one fd. */ + numbytes = read(sockfd, buf + totalbytes, MAX_BUF - (totalbytes + 1)); + if (numbytes < 0) { + debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return (AUTH_ERROR); + } + else if (numbytes == 0) { + done = 1; + } + else { + totalbytes += numbytes; + debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes); + } + } + else if (nfds == 0) { + debug(LOG_ERR, "Timed out reading data via select() from auth server"); + /* FIXME */ + close(sockfd); + return (AUTH_ERROR); + } + else if (nfds < 0) { + debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return (AUTH_ERROR); + } + } while (!done); + + close(sockfd); + + buf[totalbytes] = '\0'; + debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf); + + if ((tmp = strstr(buf, "Auth: "))) { + if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) { + debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode); + return(authresponse->authcode); + } else { + debug(LOG_WARNING, "Auth server did not return expected authentication code"); + return(AUTH_ERROR); + } + } + else { + return(AUTH_ERROR); + } + + /* XXX Never reached because of the above if()/else pair. */ + return(AUTH_ERROR); +} + +/* Tries really hard to connect to an auth server. Returns a file descriptor, -1 on error + */ +int connect_auth_server() { + int sockfd; + + LOCK_CONFIG(); + sockfd = _connect_auth_server(0); + UNLOCK_CONFIG(); + + if (sockfd == -1) { + debug(LOG_ERR, "Failed to connect to any of the auth servers"); + mark_auth_offline(); + } + else { + debug(LOG_DEBUG, "Connected to auth server"); + mark_auth_online(); + } + return (sockfd); +} + +/* Helper function called by connect_auth_server() to do the actual work including recursion + * DO NOT CALL DIRECTLY + @param level recursion level indicator must be 0 when not called by _connect_auth_server() + */ +int _connect_auth_server(int level) { + s_config *config = config_get_config(); + t_auth_serv *auth_server = NULL; + struct in_addr *h_addr; + int num_servers = 0; + char * hostname = NULL; + char * popular_servers[] = { + "www.google.com", + "www.yahoo.com", + NULL + }; + char ** popularserver; + char * ip; + struct sockaddr_in their_addr; + int sockfd; + + /* XXX level starts out at 0 and gets incremented by every iterations. */ + level++; + + /* + * Let's calculate the number of servers we have + */ + for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) { + num_servers++; + } + debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers); + + if (level > num_servers) { + /* + * We've called ourselves too many times + * This means we've cycled through all the servers in the server list + * at least once and none are accessible + */ + return (-1); + } + + /* + * Let's resolve the hostname of the top server to an IP address + */ + auth_server = config->auth_servers; + hostname = auth_server->authserv_hostname; + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname); + h_addr = wd_gethostbyname(hostname); + if (!h_addr) { + /* + * DNS resolving it failed + * + * Can we resolve any of the popular servers ? + */ + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname); + + for (popularserver = popular_servers; *popularserver; popularserver++) { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, *popularserver); + h_addr = wd_gethostbyname(*popularserver); + if (h_addr) { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] succeeded = [%s]", level, *popularserver, inet_ntoa(*h_addr)); + break; + } + else { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] failed", level, *popularserver); + } + } + + /* + * If we got any h_addr buffer for one of the popular servers, in other + * words, if one of the popular servers resolved, we'll assume the DNS + * works, otherwise we'll deal with net connection or DNS failure. + */ + if (h_addr) { + free (h_addr); + /* + * Yes + * + * The auth server's DNS server is probably dead. Try the next auth server + */ + debug(LOG_DEBUG, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname); + if (auth_server->last_ip) { + free(auth_server->last_ip); + auth_server->last_ip = NULL; + } + mark_auth_server_bad(auth_server); + return _connect_auth_server(level); + } + else { + /* + * No + * + * It's probably safe to assume that the internet connection is malfunctioning + * and nothing we can do will make it work + */ + mark_offline(); + debug(LOG_DEBUG, "Level %d: Failed to resolve auth server and all popular servers. " + "The internet connection is probably down", level); + return(-1); + } + } + else { + /* + * DNS resolving was successful + */ + ip = safe_strdup(inet_ntoa(*h_addr)); + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip); + + if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) { + /* + * But the IP address is different from the last one we knew + * Update it + */ + debug(LOG_DEBUG, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip); + if (auth_server->last_ip) free(auth_server->last_ip); + auth_server->last_ip = ip; + + /* Update firewall rules */ + fw_clear_authservers(); + fw_set_authservers(); + } + else { + /* + * IP is the same as last time + */ + free(ip); + } + + /* + * Connect to it + */ + debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port); + their_addr.sin_family = AF_INET; + their_addr.sin_port = htons(auth_server->authserv_http_port); + their_addr.sin_addr = *h_addr; + memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero)); + free (h_addr); + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno)); + return(-1); + } + + if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { + /* + * Failed to connect + * Mark the server as bad and try the next one + */ + debug(LOG_DEBUG, "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", level, hostname, auth_server->authserv_http_port, strerror(errno)); + close(sockfd); + mark_auth_server_bad(auth_server); + return _connect_auth_server(level); /* Yay recursion! */ + } + else { + /* + * We have successfully connected + */ + debug(LOG_DEBUG, "Level %d: Successfully connected to auth server %s:%d", level, hostname, auth_server->authserv_http_port); + return sockfd; + } + } +} diff --git a/src/centralserver.h b/src/centralserver.h new file mode 100755 index 00000000..36c9ca65 --- /dev/null +++ b/src/centralserver.h @@ -0,0 +1,63 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file centralserver.h + @brief Functions to talk to the central server (auth/send stats/get rules/etc...) + @author Copyright (C) 2004 Philippe April + */ + +#ifndef _CENTRALSERVER_H_ +#define _CENTRALSERVER_H_ + +#include "auth.h" + +/** @brief Ask the central server to login a client */ +#define REQUEST_TYPE_LOGIN "login" +/** @brief Notify the the central server of a client logout */ +#define REQUEST_TYPE_LOGOUT "logout" +/** @brief Update the central server's traffic counters */ +#define REQUEST_TYPE_COUNTERS "counters" + +/** @brief Sent when the user's token is denied by the central server */ +#define GATEWAY_MESSAGE_DENIED "denied" +/** @brief Sent when the user's token is accepted, but user is on probation */ +#define GATEWAY_MESSAGE_ACTIVATE_ACCOUNT "activate" +/** @brief Sent when the user's token is denied by the central server because the probation period is over */ +#define GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED "failed_validation" +/** @brief Sent after the user performed a manual log-out on the gateway */ +#define GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT "logged-out" + +/** @brief Initiates a transaction with the auth server */ +t_authcode auth_server_request(t_authresponse *authresponse, + const char *request_type, + const char *ip, + const char *mac, + const char *token, + unsigned long long int incoming, + unsigned long long int outgoing); + +/** @brief Tries really hard to connect to an auth server. Returns a connected file descriptor or -1 on error */ +int connect_auth_server(); + +/** @brief Helper function called by connect_auth_server() to do the actual work including recursion - DO NOT CALL DIRECTLY */ +int _connect_auth_server(int level); + +#endif /* _CENTRALSERVER_H_ */ diff --git a/src/client_list.c b/src/client_list.c new file mode 100755 index 00000000..bf895e92 --- /dev/null +++ b/src/client_list.c @@ -0,0 +1,258 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** @file client_list.c + @brief Client List Functions + @author Copyright (C) 2004 Alexandre Carmel-Veillex + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include + +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "client_list.h" + +/** Global mutex to protect access to the client list */ +pthread_mutex_t client_list_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** @internal + * Holds a pointer to the first element of the list + */ +t_client *firstclient = NULL; + +/** Get the first element of the list of connected clients + */ +t_client * +client_get_first_client(void) +{ + return firstclient; +} + +/** + * Initializes the list of connected clients (client) + */ +void +client_list_init(void) +{ + firstclient = NULL; +} + +/** Based on the parameters it receives, this function creates a new entry + * in the connections list. All the memory allocation is done here. + * @param ip IP address + * @param mac MAC address + * @param token Token + * @return Pointer to the client we just created + */ +t_client * +client_list_append(const char *ip, const char *mac, const char *token) +{ + t_client *curclient, *prevclient; + + prevclient = NULL; + curclient = firstclient; + + while (curclient != NULL) { + prevclient = curclient; + curclient = curclient->next; + } + + curclient = safe_malloc(sizeof(t_client)); + memset(curclient, 0, sizeof(t_client)); + + curclient->ip = safe_strdup(ip); + curclient->mac = safe_strdup(mac); + curclient->token = safe_strdup(token); + curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; + curclient->counters.last_updated = time(NULL); + + /*@breif:record the element create time + * GaomingPan + * */ + curclient->record_time = time(NULL); + //printf("New client: mac-->%s\nip-->%s\nrecord_time-->%ld\n\n",mac,ip,curclient->record_time); + + + if (prevclient == NULL) { + firstclient = curclient; + } else { + prevclient->next = curclient; + } + + debug(LOG_INFO, "Added a new client to linked list: IP: %s Token: %s", + ip, token); + + return curclient; +} + +/** Finds a client by its IP and MAC, returns NULL if the client could not + * be found + * @param ip IP we are looking for in the linked list + * @param mac MAC we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find(const char *ip, const char *mac) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->ip, ip) && 0 == strcmp(ptr->mac, mac)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** + * Finds a client by its IP, returns NULL if the client could not + * be found + * @param ip IP we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find_by_ip(const char *ip) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->ip, ip)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** + * Finds a client by its Mac, returns NULL if the client could not + * be found + * @param mac Mac we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find_by_mac(const char *mac) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->mac, mac)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** Finds a client by its token + * @param token Token we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find_by_token(const char *token) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->token, token)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** @internal + * @brief Frees the memory used by a t_client structure + * This function frees the memory used by the t_client structure in the + * proper order. + * @param client Points to the client to be freed + */ +void +_client_list_free_node(t_client * client) +{ + + if (client->mac != NULL) + free(client->mac); + + if (client->ip != NULL) + free(client->ip); + + if (client->token != NULL) + free(client->token); + + free(client); +} + +/** + * @brief Deletes a client from the connections list + * + * Removes the specified client from the connections list and then calls + * the function to free the memory used by the client. + * @param client Points to the client to be deleted + */ +void +client_list_delete(t_client * client) +{ + t_client *ptr; + + ptr = firstclient; + + if (ptr == NULL) { + debug(LOG_ERR, "Node list empty!"); + } else if (ptr == client) { + firstclient = ptr->next; + _client_list_free_node(client); + } else { + /* Loop forward until we reach our point in the list. */ + while (ptr->next != NULL && ptr->next != client) { + ptr = ptr->next; + } + /* If we reach the end before finding out element, complain. */ + if (ptr->next == NULL) { + debug(LOG_ERR, "Node to delete could not be found."); + /* Free element. */ + } else { + ptr->next = client->next; + _client_list_free_node(client); + } + } +} diff --git a/src/client_list.h b/src/client_list.h new file mode 100755 index 00000000..51c9ba0a --- /dev/null +++ b/src/client_list.h @@ -0,0 +1,100 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file client_list.h + @brief Client List functions + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _CLIENT_LIST_H_ +#define _CLIENT_LIST_H_ + +/** Counters struct for a client's bandwidth usage (in bytes) + */ +typedef struct _t_counters { + unsigned long long incoming; /**< @brief Incoming data total*/ + unsigned long long outgoing; /**< @brief Outgoing data total*/ + unsigned long long incoming_history; /**< @brief Incoming data before wifidog restarted*/ + unsigned long long outgoing_history; /**< @brief Outgoing data before wifidog restarted*/ + time_t last_updated; /**< @brief Last update of the counters */ +} t_counters; + +/** Client node for the connected client linked list. + */ +typedef struct _t_client { + struct _t_client *next; /**< @brief Pointer to the next client */ + char *ip; /**< @brief Client Ip address */ + char *mac; /**< @brief Client Mac address */ + char *token; /**< @brief Client token */ + unsigned int fw_connection_state; /**< @brief Connection state in the + firewall */ + int fd; /**< @brief Client HTTP socket (valid only + during login before one of the + _http_* function is called */ + t_counters counters; /**< @brief Counters for input/output of + the client. */ + + /*@breif:record the element create time + * GaomingPan + * */ + time_t record_time; + +} t_client; + +/** @brief Get the first element of the list of connected clients + */ +t_client *client_get_first_client(void); + +/** @brief Initializes the client list */ +void client_list_init(void); + +/** @brief Adds a new client to the connections list */ +t_client *client_list_append(const char *ip, const char *mac, const char *token); + +/** @brief Finds a client by its IP and MAC */ +t_client *client_list_find(const char *ip, const char *mac); + +/** @brief Finds a client only by its IP */ +t_client *client_list_find_by_ip(const char *ip); /* needed by fw_iptables.c, auth.c + * and wdctl_thread.c */ + +/** @brief Finds a client only by its Mac */ +t_client *client_list_find_by_mac(const char *mac); /* needed by wdctl_thread.c */ + +/** @brief Finds a client by its token */ +t_client *client_list_find_by_token(const char *token); + +/** @brief Deletes a client from the connections list */ +void client_list_delete(t_client *client); + +#define LOCK_CLIENT_LIST() do { \ + debug(LOG_DEBUG, "Locking client list"); \ + pthread_mutex_lock(&client_list_mutex); \ + debug(LOG_DEBUG, "Client list locked"); \ +} while (0) + +#define UNLOCK_CLIENT_LIST() do { \ + debug(LOG_DEBUG, "Unlocking client list"); \ + pthread_mutex_unlock(&client_list_mutex); \ + debug(LOG_DEBUG, "Client list unlocked"); \ +} while (0) + +#endif /* _CLIENT_LIST_H_ */ diff --git a/src/commandline.c b/src/commandline.c new file mode 100755 index 00000000..c45ee8e8 --- /dev/null +++ b/src/commandline.c @@ -0,0 +1,180 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file commandline.c + @brief Command line argument handling + @author Copyright (C) 2004 Philippe April +*/ + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "safe.h" +#include "conf.h" + +#include "../config.h" + +/* + * Holds an argv that could be passed to exec*() if we restart ourselves + */ +char ** restartargv = NULL; + +static void usage(void); + +/* + * A flag to denote whether we were restarted via a parent wifidog, or started normally + * 0 means normally, otherwise it will be populated by the PID of the parent + */ +pid_t restart_orig_pid = 0; + +/** @internal + * @brief Print usage + * + * Prints usage, called when wifidog is run with -h or with an unknown option + */ +static void +usage(void) +{ + printf("Usage: wifidog [options]\n"); + printf("\n"); + printf(" -c [filename] Use this config file\n"); + printf(" -f Run in foreground\n"); + printf(" -d Debug level\n"); + printf(" -s Log to syslog\n"); + printf(" -w Wdctl socket path\n"); + printf(" -h Print usage\n"); + printf(" -v Print version information\n"); + printf(" -x pid Used internally by WiFiDog when re-starting itself *DO NOT ISSUE THIS SWITCH MANUAlLY*\n"); + printf(" -i Internal socket path used when re-starting self\n"); + printf("\n"); +} + +/** Uses getopt() to parse the command line and set configuration values + * also populates restartargv + */ +void parse_commandline(int argc, char **argv) { + int c; + int skiponrestart; + int i; + + s_config *config = config_get_config(); + + //MAGIC 3: Our own -x, the pid, and NULL : + restartargv = safe_malloc((argc + 3) * sizeof(char*)); + i=0; + restartargv[i++] = safe_strdup(argv[0]); + + while (-1 != (c = getopt(argc, argv, "c:hfd:sw:vx:i:"))) { + + skiponrestart = 0; + + switch(c) { + + case 'h': + usage(); + exit(1); + break; + + case 'c': + if (optarg) { + strncpy(config->configfile, optarg, sizeof(config->configfile)); + } + break; + + case 'w': + if (optarg) { + free(config->wdctl_sock); + config->wdctl_sock = safe_strdup(optarg); + } + break; + + case 'f': + skiponrestart = 1; + config->daemon = 0; + break; + + case 'd': + if (optarg) { + config->debuglevel = atoi(optarg); + } + break; + + case 's': + config->log_syslog = 1; + break; + + case 'v': + printf("This is WiFiDog version " VERSION "\n"); + exit(1); + break; + + case 'x': + skiponrestart = 1; + if (optarg) { + restart_orig_pid = atoi(optarg); + } + else { + printf("The expected PID to the -x switch was not supplied!"); + exit(1); + } + break; + + case 'i': + if (optarg) { + free(config->internal_sock); + config->internal_sock = safe_strdup(optarg); + } + break; + + default: + usage(); + exit(1); + break; + + } + + if (!skiponrestart) { + /* Add it to restartargv */ + safe_asprintf(&(restartargv[i++]), "-%c", c); + if (optarg) { + restartargv[i++] = safe_strdup(optarg); + } + } + + } + + /* Finally, we should add the -x, pid and NULL to restartargv + * HOWEVER we cannot do it here, since this is called before we fork to background + * so we'll leave this job to gateway.c after forking is completed + * so that the correct PID is assigned + * + * We add 3 nulls, and the first 2 will be overridden later + */ + restartargv[i++] = NULL; + restartargv[i++] = NULL; + restartargv[i++] = NULL; + +} + diff --git a/src/commandline.h b/src/commandline.h new file mode 100755 index 00000000..d87b2342 --- /dev/null +++ b/src/commandline.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file commandline.h + @brief Command line argument handling + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _COMMANDLINE_H_ +#define _COMMANDLINE_H_ + +/** @brief Parses the command line and set the config accordingly */ +void parse_commandline(int, char**); + +#endif /* _COMMANDLINE_H_ */ diff --git a/src/common.h b/src/common.h new file mode 100755 index 00000000..5e25efb8 --- /dev/null +++ b/src/common.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file common.h + @brief Common constants and other bits + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +/** @brief Read buffer for socket read? */ +#define MAX_BUF 4096 + +#endif /* _COMMON_H_ */ diff --git a/src/conf.c b/src/conf.c new file mode 100755 index 00000000..a351d640 --- /dev/null +++ b/src/conf.c @@ -0,0 +1,1044 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @file conf.c + @brief Config file parsing + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2007 Benoit GrĂ©goire, Technologies Coeus inc. + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include + +#include +#include + +#include "common.h" +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "http.h" +#include "auth.h" +#include "firewall.h" + +#include "util.h" + + +/** @internal + * Holds the current configuration of the gateway */ +static s_config config; + +/** + * Mutex for the configuration file, used by the auth_servers related + * functions. */ +pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** @internal + * A flag. If set to 1, there are missing or empty mandatory parameters in the config + */ +static int missing_parms; + +/** @internal + The different configuration options */ +typedef enum { + oBadOption, + oDaemon, + oDebugLevel, + oExternalInterface, + oGatewayID, + oGatewayInterface, + oGatewayAddress, + oGatewayPort, + oAuthServer, + oAuthServHostname, + oAuthServSSLAvailable, + oAuthServSSLPort, + oAuthServHTTPPort, + oAuthServPath, + oAuthServLoginScriptPathFragment, + oAuthServPortalScriptPathFragment, + oAuthServMsgScriptPathFragment, + oAuthServPingScriptPathFragment, + oAuthServAuthScriptPathFragment, + oHTTPDMaxConn, + oHTTPDName, + oHTTPDRealm, + oHTTPDUsername, + oHTTPDPassword, + oClientTimeout, + oCheckInterval, + oWdctlSocket, + oSyslogFacility, + oFirewallRule, + oFirewallRuleSet, + oTrustedMACList, + oUntrustedMACList, /*gaomingpan*/ + oHtmlMessageFile, + oProxyPort, + oWhiteList, /*limeng*/ + oBlackList, +} OpCodes; + +/** @internal + The config file keywords for the different configuration options */ +static const struct { + const char *name; + OpCodes opcode; +} keywords[] = { + { "daemon", oDaemon }, + { "debuglevel", oDebugLevel }, + { "externalinterface", oExternalInterface }, + { "gatewayid", oGatewayID }, + { "gatewayinterface", oGatewayInterface }, + { "gatewayaddress", oGatewayAddress }, + { "gatewayport", oGatewayPort }, + { "authserver", oAuthServer }, + { "httpdmaxconn", oHTTPDMaxConn }, + { "httpdname", oHTTPDName }, + { "httpdrealm", oHTTPDRealm }, + { "httpdusername", oHTTPDUsername }, + { "httpdpassword", oHTTPDPassword }, + { "clienttimeout", oClientTimeout }, + { "checkinterval", oCheckInterval }, + { "syslogfacility", oSyslogFacility }, + { "wdctlsocket", oWdctlSocket }, + { "hostname", oAuthServHostname }, + { "sslavailable", oAuthServSSLAvailable }, + { "sslport", oAuthServSSLPort }, + { "httpport", oAuthServHTTPPort }, + { "path", oAuthServPath }, + { "loginscriptpathfragment", oAuthServLoginScriptPathFragment }, + { "portalscriptpathfragment", oAuthServPortalScriptPathFragment }, + { "msgscriptpathfragment", oAuthServMsgScriptPathFragment }, + { "pingscriptpathfragment", oAuthServPingScriptPathFragment }, + { "authscriptpathfragment", oAuthServAuthScriptPathFragment }, + { "firewallruleset", oFirewallRuleSet }, + { "firewallrule", oFirewallRule }, + { "trustedmaclist", oTrustedMACList }, + { "untrustedMACList", oUntrustedMACList}, /*gaomingpan*/ + { "htmlmessagefile", oHtmlMessageFile }, + { "proxyport", oProxyPort }, + { "whitelist", oWhiteList}, /*limeng*/ + { "blacklist", oBlackList}, + { NULL, oBadOption }, +}; + +static void config_notnull(const void *parm, const char *parmname); +static int parse_boolean_value(char *); +static void parse_auth_server(FILE *, const char *, int *); +static int _parse_firewall_rule(const char *ruleset, char *leftover); +static void parse_firewall_ruleset(const char *, FILE *, const char *, int *); + +static OpCodes config_parse_token(const char *cp, const char *filename, int linenum); + +/** Accessor for the current gateway configuration +@return: A pointer to the current config. The pointer isn't opaque, but should be treated as READ-ONLY + */ +s_config * +config_get_config(void) +{ + return &config; +} + +/** Sets the default config parameters and initialises the configuration system */ +void +config_init(void) +{ + debug(LOG_DEBUG, "Setting default config parameters"); + strncpy(config.configfile, DEFAULT_CONFIGFILE, sizeof(config.configfile)); + config.htmlmsgfile = safe_strdup(DEFAULT_HTMLMSGFILE); + config.debuglevel = DEFAULT_DEBUGLEVEL; + config.httpdmaxconn = DEFAULT_HTTPDMAXCONN; + config.external_interface = NULL; + config.gw_id = DEFAULT_GATEWAYID; + config.gw_interface = NULL; + config.gw_address = NULL; + config.gw_port = DEFAULT_GATEWAYPORT; + config.auth_servers = NULL; + config.httpdname = NULL; + config.httpdrealm = DEFAULT_HTTPDNAME; + config.httpdusername = NULL; + config.httpdpassword = NULL; + config.clienttimeout = DEFAULT_CLIENTTIMEOUT; + config.checkinterval = DEFAULT_CHECKINTERVAL; + config.syslog_facility = DEFAULT_SYSLOG_FACILITY; + config.daemon = -1; + config.log_syslog = DEFAULT_LOG_SYSLOG; + config.wdctl_sock = safe_strdup(DEFAULT_WDCTL_SOCK); + config.internal_sock = safe_strdup(DEFAULT_INTERNAL_SOCK); + config.rulesets = NULL; + config.trustedmaclist = NULL; + config.untrustedmaclist = NULL; /*gaomingpan*/ + config.proxy_port = 0; + config.white_list = NULL; /*limeng*/ + config.black_list = NULL; + +} + +/** + * If the command-line didn't provide a config, use the default. + */ +void +config_init_override(void) +{ + if (config.daemon == -1) config.daemon = DEFAULT_DAEMON; +} + +/** @internal +Parses a single token from the config file +*/ +static OpCodes +config_parse_token(const char *cp, const char *filename, int linenum) +{ + int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + debug(LOG_ERR, "%s: line %d: Bad configuration option: %s", + filename, linenum, cp); + return oBadOption; +} + +/** @internal +Parses auth server information +*/ +static void +parse_auth_server(FILE *file, const char *filename, int *linenum) +{ + char *host = NULL, + *path = NULL, + *loginscriptpathfragment = NULL, + *portalscriptpathfragment = NULL, + *msgscriptpathfragment = NULL, + *pingscriptpathfragment = NULL, + *authscriptpathfragment = NULL, + line[MAX_BUF], + *p1, + *p2; + int http_port, + ssl_port, + ssl_available, + opcode; + t_auth_serv *new, + *tmp; + + /* Defaults */ + path = safe_strdup(DEFAULT_AUTHSERVPATH); + loginscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVLOGINPATHFRAGMENT); + portalscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVPORTALPATHFRAGMENT); + msgscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVMSGPATHFRAGMENT); + pingscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVPINGPATHFRAGMENT); + authscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVAUTHPATHFRAGMENT); + http_port = DEFAULT_AUTHSERVPORT; + ssl_port = DEFAULT_AUTHSERVSSLPORT; + ssl_available = DEFAULT_AUTHSERVSSLAVAILABLE; + + + /* Parsing loop */ + while (memset(line, 0, MAX_BUF) && fgets(line, MAX_BUF - 1, file) && (strchr(line, '}') == NULL)) { + (*linenum)++; /* increment line counter. */ + + /* skip leading blank spaces */ + for (p1 = line; isblank(*p1); p1++); + + /* End at end of line */ + if ((p2 = strchr(p1, '#')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\r')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\n')) != NULL) { + *p2 = '\0'; + } + + /* next, we coopt the parsing of the regular config */ + if (strlen(p1) > 0) { + p2 = p1; + /* keep going until word boundary is found. */ + while ((*p2 != '\0') && (!isblank(*p2))) + p2++; + + /* Terminate first word. */ + *p2 = '\0'; + p2++; + + /* skip all further blanks. */ + while (isblank(*p2)) + p2++; + + /* Get opcode */ + opcode = config_parse_token(p1, filename, *linenum); + + switch (opcode) { + case oAuthServHostname: + host = safe_strdup(p2); + break; + case oAuthServPath: + free(path); + path = safe_strdup(p2); + break; + case oAuthServLoginScriptPathFragment: + free(loginscriptpathfragment); + loginscriptpathfragment = safe_strdup(p2); + break; + case oAuthServPortalScriptPathFragment: + free(portalscriptpathfragment); + portalscriptpathfragment = safe_strdup(p2); + break; + case oAuthServMsgScriptPathFragment: + free(msgscriptpathfragment); + msgscriptpathfragment = safe_strdup(p2); + break; + case oAuthServPingScriptPathFragment: + free(pingscriptpathfragment); + pingscriptpathfragment = safe_strdup(p2); + break; + case oAuthServAuthScriptPathFragment: + free(authscriptpathfragment); + authscriptpathfragment = safe_strdup(p2); + break; + case oAuthServSSLPort: + ssl_port = atoi(p2); + break; + case oAuthServHTTPPort: + http_port = atoi(p2); + break; + case oAuthServSSLAvailable: + ssl_available = parse_boolean_value(p2); + if (ssl_available < 0) + ssl_available = 0; + break; + case oBadOption: + default: + debug(LOG_ERR, "Bad option on line %d " + "in %s.", *linenum, + filename); + debug(LOG_ERR, "Exiting..."); + exit(-1); + break; + } + } + } + + /* only proceed if we have an host and a path */ + if (host == NULL) + return; + + debug(LOG_DEBUG, "Adding %s:%d (SSL: %d) %s to the auth server list", + host, http_port, ssl_port, path); + + /* Allocate memory */ + new = safe_malloc(sizeof(t_auth_serv)); + + /* Fill in struct */ + memset(new, 0, sizeof(t_auth_serv)); /*< Fill all with NULL */ + new->authserv_hostname = host; + new->authserv_use_ssl = ssl_available; + new->authserv_path = path; + new->authserv_login_script_path_fragment = loginscriptpathfragment; + new->authserv_portal_script_path_fragment = portalscriptpathfragment; + new->authserv_msg_script_path_fragment = msgscriptpathfragment; + new->authserv_ping_script_path_fragment = pingscriptpathfragment; + new->authserv_auth_script_path_fragment = authscriptpathfragment; + new->authserv_http_port = http_port; + new->authserv_ssl_port = ssl_port; + + /* If it's the first, add to config, else append to last server */ + if (config.auth_servers == NULL) { + config.auth_servers = new; + } else { + for (tmp = config.auth_servers; tmp->next != NULL; + tmp = tmp->next); + tmp->next = new; + } + + debug(LOG_DEBUG, "Auth server added"); +} + +/** +Advance to the next word +@param s string to parse, this is the next_word pointer, the value of s + when the macro is called is the current word, after the macro + completes, s contains the beginning of the NEXT word, so you + need to save s to something else before doing TO_NEXT_WORD +@param e should be 0 when calling TO_NEXT_WORD(), it'll be changed to 1 + if the end of the string is reached. +*/ +#define TO_NEXT_WORD(s, e) do { \ + while (*s != '\0' && !isblank(*s)) { \ + s++; \ + } \ + if (*s != '\0') { \ + *s = '\0'; \ + s++; \ + while (isblank(*s)) \ + s++; \ + } else { \ + e = 1; \ + } \ +} while (0) + +/** @internal +Parses firewall rule set information +*/ +static void +parse_firewall_ruleset(const char *ruleset, FILE *file, const char *filename, int *linenum) +{ + char line[MAX_BUF], + *p1, + *p2; + int opcode; + + debug(LOG_DEBUG, "Adding Firewall Rule Set %s", ruleset); + + /* Parsing loop */ + while (memset(line, 0, MAX_BUF) && fgets(line, MAX_BUF - 1, file) && (strchr(line, '}') == NULL)) { + (*linenum)++; /* increment line counter. */ + + /* skip leading blank spaces */ + for (p1 = line; isblank(*p1); p1++); + + /* End at end of line */ + if ((p2 = strchr(p1, '#')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\r')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\n')) != NULL) { + *p2 = '\0'; + } + + /* next, we coopt the parsing of the regular config */ + if (strlen(p1) > 0) { + p2 = p1; + /* keep going until word boundary is found. */ + while ((*p2 != '\0') && (!isblank(*p2))) + p2++; + + /* Terminate first word. */ + *p2 = '\0'; + p2++; + + /* skip all further blanks. */ + while (isblank(*p2)) + p2++; + + /* Get opcode */ + opcode = config_parse_token(p1, filename, *linenum); + + debug(LOG_DEBUG, "p1 = [%s]; p2 = [%s]", p1, p2); + + switch (opcode) { + case oFirewallRule: + _parse_firewall_rule(ruleset, p2); + break; + + case oBadOption: + default: + debug(LOG_ERR, "Bad option on line %d " + "in %s.", *linenum, + filename); + debug(LOG_ERR, "Exiting..."); + exit(-1); + break; + } + } + } + + debug(LOG_DEBUG, "Firewall Rule Set %s added.", ruleset); +} + +/** @internal +Helper for parse_firewall_ruleset. Parses a single rule in a ruleset +*/ +static int +_parse_firewall_rule(const char *ruleset, char *leftover) +{ + int i; + t_firewall_target target = TARGET_REJECT; /**< firewall target */ + int all_nums = 1; /**< If 0, port contained non-numerics */ + int finished = 0; /**< reached end of line */ + char *token = NULL; /**< First word */ + char *port = NULL; /**< port to open/block */ + char *protocol = NULL; /**< protocol to block, tcp/udp/icmp */ + char *mask = NULL; /**< Netmask */ + char *other_kw = NULL; /**< other key word */ + t_firewall_ruleset *tmpr; + t_firewall_ruleset *tmpr2; + t_firewall_rule *tmp; + t_firewall_rule *tmp2; + + debug(LOG_DEBUG, "leftover: %s", leftover); + + /* lower case */ + for (i = 0; *(leftover + i) != '\0' + && (*(leftover + i) = tolower((unsigned char)*(leftover + i))); i++); + + token = leftover; + TO_NEXT_WORD(leftover, finished); + + /* Parse token */ + if (!strcasecmp(token, "block") || finished) { + target = TARGET_REJECT; + } else if (!strcasecmp(token, "drop")) { + target = TARGET_DROP; + } else if (!strcasecmp(token, "allow")) { + target = TARGET_ACCEPT; + } else if (!strcasecmp(token, "log")) { + target = TARGET_LOG; + } else if (!strcasecmp(token, "ulog")) { + target = TARGET_ULOG; + } else { + debug(LOG_ERR, "Invalid rule type %s, expecting " + "\"block\",\"drop\",\"allow\",\"log\" or \"ulog\"", token); + return -1; + } + + /* Parse the remainder */ + /* Get the protocol */ + if (strncmp(leftover, "tcp", 3) == 0 + || strncmp(leftover, "udp", 3) == 0 + || strncmp(leftover, "icmp", 4) == 0) { + protocol = leftover; + TO_NEXT_WORD(leftover, finished); + } + + /* should be exactly "port" */ + if (strncmp(leftover, "port", 4) == 0) { + TO_NEXT_WORD(leftover, finished); + /* Get port now */ + port = leftover; + TO_NEXT_WORD(leftover, finished); + for (i = 0; *(port + i) != '\0'; i++) + if (!isdigit((unsigned char)*(port + i))) + all_nums = 0; /*< No longer only digits */ + if (!all_nums) { + debug(LOG_ERR, "Invalid port %s", port); + return -3; /*< Fail */ + } + } + + /* Now, further stuff is optional */ + if (!finished) { + /* should be exactly "to" */ + other_kw = leftover; + TO_NEXT_WORD(leftover, finished); + if (strcmp(other_kw, "to") || finished) { + debug(LOG_ERR, "Invalid or unexpected keyword %s, " + "expecting \"to\"", other_kw); + return -4; /*< Fail */ + } + + /* Get port now */ + mask = leftover; + TO_NEXT_WORD(leftover, finished); + all_nums = 1; + for (i = 0; *(mask + i) != '\0'; i++) + if (!isdigit((unsigned char)*(mask + i)) && (*(mask + i) != '.') + && (*(mask + i) != '/')) + all_nums = 0; /*< No longer only digits */ + if (!all_nums) { + debug(LOG_ERR, "Invalid mask %s", mask); + return -3; /*< Fail */ + } + } + + /* Generate rule record */ + tmp = safe_malloc(sizeof(t_firewall_rule)); + memset((void *)tmp, 0, sizeof(t_firewall_rule)); + tmp->target = target; + if (protocol != NULL) + tmp->protocol = safe_strdup(protocol); + if (port != NULL) + tmp->port = safe_strdup(port); + if (mask == NULL) + tmp->mask = safe_strdup("0.0.0.0/0"); + else + tmp->mask = safe_strdup(mask); + + debug(LOG_DEBUG, "Adding Firewall Rule %s %s port %s to %s", token, tmp->protocol, tmp->port, tmp->mask); + + /* Append the rule record */ + if (config.rulesets == NULL) { + config.rulesets = safe_malloc(sizeof(t_firewall_ruleset)); + memset(config.rulesets, 0, sizeof(t_firewall_ruleset)); + config.rulesets->name = safe_strdup(ruleset); + tmpr = config.rulesets; + } else { + tmpr2 = tmpr = config.rulesets; + while (tmpr != NULL && (strcmp(tmpr->name, ruleset) != 0)) { + tmpr2 = tmpr; + tmpr = tmpr->next; + } + if (tmpr == NULL) { + /* Rule did not exist */ + tmpr = safe_malloc(sizeof(t_firewall_ruleset)); + memset(tmpr, 0, sizeof(t_firewall_ruleset)); + tmpr->name = safe_strdup(ruleset); + tmpr2->next = tmpr; + } + } + + /* At this point, tmpr == current ruleset */ + if (tmpr->rules == NULL) { + /* No rules... */ + tmpr->rules = tmp; + } else { + tmp2 = tmpr->rules; + while (tmp2->next != NULL) + tmp2 = tmp2->next; + tmp2->next = tmp; + } + + return 1; +} + +t_firewall_rule * +get_ruleset(const char *ruleset) +{ + t_firewall_ruleset *tmp; + + for (tmp = config.rulesets; tmp != NULL + && strcmp(tmp->name, ruleset) != 0; tmp = tmp->next); + + if (tmp == NULL) + return NULL; + + return(tmp->rules); +} + +/** +@param filename Full path of the configuration file to be read +*/ +void +config_read(const char *filename) +{ + FILE *fd; + char line[MAX_BUF], *s, *p1, *p2; + int linenum = 0, opcode, value, len; + + debug(LOG_INFO, "Reading configuration file '%s'", filename); + + if (!(fd = fopen(filename, "r"))) { + debug(LOG_ERR, "Could not open configuration file '%s', " + "exiting...", filename); + exit(1); + } + + while (!feof(fd) && fgets(line, MAX_BUF, fd)) { + linenum++; + s = line; + + if (s[strlen(s) - 1] == '\n') + s[strlen(s) - 1] = '\0'; + + if ((p1 = strchr(s, ' '))) { + p1[0] = '\0'; + } else if ((p1 = strchr(s, '\t'))) { + p1[0] = '\0'; + } + + if (p1) { + p1++; + + // Trim leading spaces + len = strlen(p1); + while (*p1 && len) { + if (*p1 == ' ') + p1++; + else + break; + len = strlen(p1); + } + + + if ((p2 = strchr(p1, ' '))) { + p2[0] = '\0'; + } else if ((p2 = strstr(p1, "\r\n"))) { + p2[0] = '\0'; + } else if ((p2 = strchr(p1, '\n'))) { + p2[0] = '\0'; + } + } + + if (p1 && p1[0] != '\0') { + /* Strip trailing spaces */ + + if ((strncmp(s, "#", 1)) != 0) { + debug(LOG_DEBUG, "Parsing token: %s, " + "value: %s", s, p1); + opcode = config_parse_token(s, filename, linenum); + + switch(opcode) { + case oDaemon: + if (config.daemon == -1 && ((value = parse_boolean_value(p1)) != -1)) { + config.daemon = value; + } + break; + case oExternalInterface: + config.external_interface = safe_strdup(p1); + break; + case oGatewayID: + config.gw_id = safe_strdup(p1); + break; + case oGatewayInterface: + config.gw_interface = safe_strdup(p1); + break; + case oGatewayAddress: + config.gw_address = safe_strdup(p1); + break; + case oGatewayPort: + sscanf(p1, "%d", &config.gw_port); + break; + case oAuthServer: + parse_auth_server(fd, filename, + &linenum); + break; + case oFirewallRuleSet: + parse_firewall_ruleset(p1, fd, filename, &linenum); + break; + case oTrustedMACList: + parse_trusted_mac_list(p1); + break; + /*gaomingpan*/ + case oUntrustedMACList: + parse_untrusted_mac_list(p1); + break; + case oHTTPDName: + config.httpdname = safe_strdup(p1); + break; + case oHTTPDMaxConn: + sscanf(p1, "%d", &config.httpdmaxconn); + break; + case oHTTPDRealm: + config.httpdrealm = safe_strdup(p1); + break; + case oHTTPDUsername: + config.httpdusername = safe_strdup(p1); + break; + case oHTTPDPassword: + config.httpdpassword = safe_strdup(p1); + break; + case oBadOption: + debug(LOG_ERR, "Bad option on line %d " + "in %s.", linenum, + filename); + debug(LOG_ERR, "Exiting..."); + exit(-1); + break; + case oCheckInterval: + sscanf(p1, "%d", &config.checkinterval); + break; + case oWdctlSocket: + free(config.wdctl_sock); + config.wdctl_sock = safe_strdup(p1); + break; + case oClientTimeout: + sscanf(p1, "%d", &config.clienttimeout); + break; + case oSyslogFacility: + sscanf(p1, "%d", &config.syslog_facility); + break; + case oHtmlMessageFile: + config.htmlmsgfile = safe_strdup(p1); + break; + case oProxyPort: + sscanf(p1, "%d", &config.proxy_port); + break; + /*limeng*/ + case oWhiteList: + parse_white_list(p1); + break; + case oBlackList: + parse_black_list(p1); + break; + + } + } + } + } + + if (config.httpdusername && !config.httpdpassword) { + debug(LOG_ERR, "HTTPDUserName requires a HTTPDPassword to be set."); + exit(-1); + } + + fclose(fd); +} + +/** @internal +Parses a boolean value from the config file +*/ +static int +parse_boolean_value(char *line) +{ + if (strcasecmp(line, "yes") == 0) { + return 1; + } + if (strcasecmp(line, "no") == 0) { + return 0; + } + if (strcmp(line, "1") == 0) { + return 1; + } + if (strcmp(line, "0") == 0) { + return 0; + } + + return -1; +} + +void parse_trusted_mac_list(const char *ptr) { + char *ptrcopy = NULL; + char *possiblemac = NULL; + char *mac = NULL; + t_trusted_mac *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for trusted MAC addresses", ptr); + + mac = safe_malloc(18); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblemac = strsep(&ptrcopy, ", "))) { + if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { + /* Copy mac to the list */ + + debug(LOG_DEBUG, "Adding MAC address [%s] to trusted list", mac); + + if (config.trustedmaclist == NULL) { + config.trustedmaclist = safe_malloc(sizeof(t_trusted_mac)); + config.trustedmaclist->mac = safe_strdup(mac); + config.trustedmaclist->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.trustedmaclist; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_trusted_mac)); + p = p->next; + p->mac = safe_strdup(mac); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(mac); + +} + +/*gaomingpan*/ +void parse_untrusted_mac_list(const char *ptr) +{ + char *ptrcopy = NULL; + char *possiblemac = NULL; + char *mac = NULL; + t_untrusted_mac *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for untrusted MAC addresses", ptr); + + mac = safe_malloc(18); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblemac = strsep(&ptrcopy, ", "))) { + if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { + /* Copy mac to the list */ + + debug(LOG_DEBUG, "Adding MAC address [%s] to untrusted list", mac); + + if (config.untrustedmaclist == NULL) { + config.untrustedmaclist = safe_malloc(sizeof(t_trusted_mac)); + config.untrustedmaclist->mac = safe_strdup(mac); + config.untrustedmaclist->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.untrustedmaclist; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_untrusted_mac)); + p = p->next; + p->mac = safe_strdup(mac); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(mac); +} + + + +/*limeng*/ +void parse_white_list(const char *ptr) { + char *ptrcopy = NULL; + char *possiblewhitelist = NULL; + char *ip = NULL; + t_white_list *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for white list addresses", ptr); + + ip = safe_malloc(512); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblewhitelist = strsep(&ptrcopy, ", "))) { + if (sscanf(possiblewhitelist, " %s[A-Za-z0-9.]", ip) == 1) { + /* Copy white list to the list */ + + debug(LOG_DEBUG, "Adding ip address [%s] to white list", ip); + + if (config.white_list == NULL) { + config.white_list = safe_malloc(sizeof(t_white_list)); + config.white_list->ip = safe_strdup(ip); + config.white_list->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.white_list; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_white_list)); + p = p->next; + p->ip = safe_strdup(ip); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(ip); + +} + +void parse_black_list(const char *ptr) { + char *ptrcopy = NULL; + char *possibleblacklist = NULL; + char *ip = NULL; + t_black_list *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for black list addresses", ptr); + + ip = safe_malloc(512); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possibleblacklist = strsep(&ptrcopy, ", "))) { + if (sscanf(possibleblacklist, " %s[A-Za-z0-9.]", ip) == 1) { + /* Copy black list to the list */ + + debug(LOG_DEBUG, "Adding ip address [%s] to black list", ip); + + if (config.black_list == NULL) { + config.black_list = safe_malloc(sizeof(t_black_list)); + config.black_list->ip = safe_strdup(ip); + config.black_list->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.black_list; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_black_list)); + p = p->next; + p->ip = safe_strdup(ip); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(ip); + +} + + + +/** Verifies if the configuration is complete and valid. Terminates the program if it isn't */ +void +config_validate(void) +{ + config_notnull(config.gw_interface, "GatewayInterface"); + config_notnull(config.auth_servers, "AuthServer"); + + if (missing_parms) { + debug(LOG_ERR, "Configuration is not complete, exiting..."); + exit(-1); + } +} + +/** @internal + Verifies that a required parameter is not a null pointer +*/ +static void +config_notnull(const void *parm, const char *parmname) +{ + if (parm == NULL) { + debug(LOG_ERR, "%s is not set", parmname); + missing_parms = 1; + } +} + +/** + * This function returns the current (first auth_server) + */ +t_auth_serv * +get_auth_server(void) +{ + + /* This is as good as atomic */ + return config.auth_servers; +} + +/** + * This function marks the current auth_server, if it matches the argument, + * as bad. Basically, the "bad" server becomes the last one on the list. + */ +void +mark_auth_server_bad(t_auth_serv *bad_server) +{ + t_auth_serv *tmp; + + if (config.auth_servers == bad_server && bad_server->next != NULL) { + /* Go to the last */ + for (tmp = config.auth_servers; tmp->next != NULL; tmp = tmp->next); + /* Set bad server as last */ + tmp->next = bad_server; + /* Remove bad server from start of list */ + config.auth_servers = bad_server->next; + /* Set the next pointe to NULL in the last element */ + bad_server->next = NULL; + } + +} diff --git a/src/conf.h b/src/conf.h new file mode 100755 index 00000000..b4c289bd --- /dev/null +++ b/src/conf.h @@ -0,0 +1,244 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file conf.h + @brief Config file parsing + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/*@{*/ +/** Defines */ +/** How many times should we try detecting the interface with the default route + * (in seconds). If set to 0, it will keep retrying forever */ +#define NUM_EXT_INTERFACE_DETECT_RETRY 0 +/** How often should we try to detect the interface with the default route + * if it isn't up yet (interval in seconds) */ +#define EXT_INTERFACE_DETECT_RETRY_INTERVAL 1 + +/** Defaults configuration values */ +#ifndef SYSCONFDIR + #define DEFAULT_CONFIGFILE "/etc/wifidog.conf" + #define DEFAULT_HTMLMSGFILE "/etc/wifidog-msg.html" +#else + #define DEFAULT_CONFIGFILE SYSCONFDIR"/wifidog.conf" + #define DEFAULT_HTMLMSGFILE SYSCONFDIR"/wifidog-msg.html" +#endif +#define DEFAULT_DAEMON 1 +#define DEFAULT_DEBUGLEVEL LOG_INFO +#define DEFAULT_HTTPDMAXCONN 10 +#define DEFAULT_GATEWAYID NULL +#define DEFAULT_GATEWAYPORT 2060 +#define DEFAULT_HTTPDNAME "WiFiDog" +#define DEFAULT_CLIENTTIMEOUT 5 +//#define DEFAULT_CHECKINTERVAL 60 +#define DEFAULT_CHECKINTERVAL 30 +#define DEFAULT_LOG_SYSLOG 1 +#define DEFAULT_SYSLOG_FACILITY LOG_DAEMON +#define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" +#define DEFAULT_INTERNAL_SOCK "/tmp/wifidog.sock" +#define DEFAULT_AUTHSERVPORT 80 +#define DEFAULT_AUTHSERVSSLPORT 443 +/** Note that DEFAULT_AUTHSERVSSLAVAILABLE must be 0 or 1, even if the config file syntax is yes or no */ +#define DEFAULT_AUTHSERVSSLAVAILABLE 0 +/** Note: The path must be prefixed by /, and must be suffixed /. Put / for the server root.*/ +#define DEFAULT_AUTHSERVPATH "/wifidog/" +#define DEFAULT_AUTHSERVLOGINPATHFRAGMENT "login/?" +#define DEFAULT_AUTHSERVPORTALPATHFRAGMENT "portal/?" +#define DEFAULT_AUTHSERVMSGPATHFRAGMENT "gw_message.php?" +#define DEFAULT_AUTHSERVPINGPATHFRAGMENT "ping/?" +#define DEFAULT_AUTHSERVAUTHPATHFRAGMENT "auth/?" +/*@}*/ + +/** + * Information about the authentication server + */ +typedef struct _auth_serv_t { + char *authserv_hostname; /**< @brief Hostname of the central server */ + char *authserv_path; /**< @brief Path where wifidog resides */ + char *authserv_login_script_path_fragment; /**< @brief This is the script the user will be sent to for login. */ + char *authserv_portal_script_path_fragment; /**< @brief This is the script the user will be sent to after a successfull login. */ + char *authserv_msg_script_path_fragment; /**< @brief This is the script the user will be sent to upon error to read a readable message. */ + char *authserv_ping_script_path_fragment; /**< @brief This is the ping heartbeating script. */ + char *authserv_auth_script_path_fragment; /**< @brief This is the script that talks the wifidog gateway protocol. */ + int authserv_http_port; /**< @brief Http port the central server + listens on */ + int authserv_ssl_port; /**< @brief Https port the central server + listens on */ + int authserv_use_ssl; /**< @brief Use SSL or not */ + char *last_ip; /**< @brief Last ip used by authserver */ + struct _auth_serv_t *next; +} t_auth_serv; + +/** + * Firewall targets + */ +typedef enum { + TARGET_DROP, + TARGET_REJECT, + TARGET_ACCEPT, + TARGET_LOG, + TARGET_ULOG +} t_firewall_target; + +/** + * Firewall rules + */ +typedef struct _firewall_rule_t { + t_firewall_target target; /**< @brief t_firewall_target */ + char *protocol; /**< @brief tcp, udp, etc ... */ + char *port; /**< @brief Port to block/allow */ + char *mask; /**< @brief Mask for the rule *destination* */ + struct _firewall_rule_t *next; +} t_firewall_rule; + +/** + * Firewall rulesets + */ +typedef struct _firewall_ruleset_t { + char *name; + t_firewall_rule *rules; + struct _firewall_ruleset_t *next; +} t_firewall_ruleset; + +/** + * Trusted MAC Addresses + */ +typedef struct _trusted_mac_t { + char *mac; + struct _trusted_mac_t *next; +} t_trusted_mac; + +/** + * gaomingpan + * untrusted mac addresses + * */ +typedef struct _untrusted_mac_t { + char *mac; + struct _untrusted_mac_t *next; +} t_untrusted_mac; + +/*limeng*/ +/** + * Trusted White list Addresses + */ +typedef struct _white_list_t { + char *ip; + struct _white_list_t *next; +} t_white_list; + +typedef struct _black_list_t { + char *ip; + struct _black_list_t *next; +} t_black_list; + + +/** + * Configuration structure + */ +typedef struct { + char configfile[255]; /**< @brief name of the config file */ + char *htmlmsgfile; /**< @brief name of the HTML file used for messages */ + char *wdctl_sock; /**< @brief wdctl path to socket */ + char *internal_sock; /**< @brief internal path to socket */ + int daemon; /**< @brief if daemon > 0, use daemon mode */ + int debuglevel; /**< @brief Debug information verbosity */ + char *external_interface; /**< @brief External network interface name for + firewall rules */ + char *gw_id; /**< @brief ID of the Gateway, sent to central + server */ + char *gw_interface; /**< @brief Interface we will accept connections on */ + char *gw_address; /**< @brief Internal IP address for our web + server */ + int gw_port; /**< @brief Port the webserver will run on */ + + t_auth_serv *auth_servers; /**< @brief Auth servers list */ + char *httpdname; /**< @brief Name the web server will return when + replying to a request */ + int httpdmaxconn; /**< @brief Used by libhttpd, not sure what it + does */ + char *httpdrealm; /**< @brief HTTP Authentication realm */ + char *httpdusername; /**< @brief Username for HTTP authentication */ + char *httpdpassword; /**< @brief Password for HTTP authentication */ + int clienttimeout; /**< @brief How many CheckIntervals before a client + must be re-authenticated */ + int checkinterval; /**< @brief Frequency the the client timeout check + thread will run. */ + int log_syslog; /**< @brief boolean, wether to log to syslog */ + int syslog_facility; /**< @brief facility to use when using syslog for + logging */ + int proxy_port; /**< @brief Transparent proxy port (0 to disable) */ + /*limeng*/ + t_white_list *white_list; /**< @brief White list */ + t_black_list *black_list; /**< @brief black list */ + t_firewall_ruleset *rulesets; /**< @brief firewall rules */ + t_trusted_mac *trustedmaclist; /**< @brief list of trusted macs */ + t_untrusted_mac *untrustedmaclist; /**< @brief list of untrusted macs*/ +} s_config; + +/** @brief Get the current gateway configuration */ +s_config *config_get_config(void); + +/** @brief Initialise the conf system */ +void config_init(void); + +/** @brief Initialize the variables we override with the command line*/ +void config_init_override(void); + +/** @brief Reads the configuration file */ +void config_read(const char *filename); + +/** @brief Check that the configuration is valid */ +void config_validate(void); + +/** @brief Get the active auth server */ +t_auth_serv *get_auth_server(void); + +/** @brief Bump server to bottom of the list */ +void mark_auth_server_bad(t_auth_serv *); + +/** @brief Fetch a firewall rule set. */ +t_firewall_rule *get_ruleset(const char *); + +void parse_trusted_mac_list(const char *); + +/*gaomingpan*/ +void parse_untrusted_mac_list(const char *); + +/* limeng */ +void parse_white_list(const char *); +void parse_black_list(const char *) ; + +#define LOCK_CONFIG() do { \ + debug(LOG_DEBUG, "Locking config"); \ + pthread_mutex_lock(&config_mutex); \ + debug(LOG_DEBUG, "Config locked"); \ +} while (0) + +#define UNLOCK_CONFIG() do { \ + debug(LOG_DEBUG, "Unlocking config"); \ + pthread_mutex_unlock(&config_mutex); \ + debug(LOG_DEBUG, "Config unlocked"); \ +} while (0) + +#endif /* _CONFIG_H_ */ diff --git a/src/debug.c b/src/debug.c new file mode 100755 index 00000000..529c4cf4 --- /dev/null +++ b/src/debug.c @@ -0,0 +1,76 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file debug.c + @brief Debug output routines + @author Copyright (C) 2004 Philippe April +*/ + +#include +#include +#include +#include +#include +#include + +#include "conf.h" + +/** @internal +Do not use directly, use the debug macro */ +void +_debug(const char *filename, int line, int level, const char *format, ...) +{ + char buf[28]; + va_list vlist; + s_config *config = config_get_config(); + time_t ts; + + time(&ts); + + if (config->debuglevel >= level) { + + if (level <= LOG_WARNING) { + fprintf(stderr, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), + filename, line); + va_start(vlist, format); + vfprintf(stderr, format, vlist); + va_end(vlist); + fputc('\n', stderr); + } else if (!config->daemon) { + fprintf(stdout, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), + filename, line); + va_start(vlist, format); + vfprintf(stdout, format, vlist); + va_end(vlist); + fputc('\n', stdout); + fflush(stdout); + } + + if (config->log_syslog) { + openlog("wifidog", LOG_PID, config->syslog_facility); + va_start(vlist, format); + vsyslog(level, format, vlist); + va_end(vlist); + closelog(); + } + } +} + diff --git a/src/debug.h b/src/debug.h new file mode 100755 index 00000000..94744fa1 --- /dev/null +++ b/src/debug.h @@ -0,0 +1,38 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file debug.h + @brief Debug output routines + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +/** @brief Used to output messages. + *The messages will include the finlname and line number, and will be sent to syslog if so configured in the config file + */ +#define debug(level, format...) _debug(__FILE__, __LINE__, level, format) + +/** @internal */ +void _debug(const char *filename, int line, int level, const char *format, ...); + +#endif /* _DEBUG_H_ */ diff --git a/src/firewall.c b/src/firewall.c new file mode 100755 index 00000000..a3f20428 --- /dev/null +++ b/src/firewall.c @@ -0,0 +1,424 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** @internal + @file firewall.c + @brief Firewall update functions + @author Copyright (C) 2004 Philippe April + 2006 Benoit GrĂ©goire, Technologies Coeus inc. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#include +#include +#endif + +#if defined(__NetBSD__) +#include +#include +#include +#endif + +#include "httpd.h" +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "firewall.h" +#include "fw_iptables.h" +#include "auth.h" +#include "centralserver.h" +#include "client_list.h" + +#include "get_clientinfo.h" + +extern pthread_mutex_t client_list_mutex; + +/* from commandline.c */ +extern pid_t restart_orig_pid; + + + +/** + * Allow a client access through the firewall by adding a rule in the firewall to MARK the user's packets with the proper + * rule by providing his IP and MAC address + * @param ip IP address to allow + * @param mac MAC address to allow + * @param fw_connection_state fw_connection_state Tag + * @return Return code of the command + */ +int +fw_allow(const char *ip, const char *mac, int fw_connection_state) +{ + debug(LOG_DEBUG, "Allowing %s %s with fw_connection_state %d", ip, mac, fw_connection_state); + + return iptables_fw_access(FW_ACCESS_ALLOW, ip, mac, fw_connection_state); +} + +/** + * @brief Deny a client access through the firewall by removing the rule in the firewall that was fw_connection_stateging the user's traffic + * @param ip IP address to deny + * @param mac MAC address to deny + * @param fw_connection_state fw_connection_state Tag + * @return Return code of the command + */ +int +fw_deny(const char *ip, const char *mac, int fw_connection_state) +{ + debug(LOG_DEBUG, "Denying %s %s with fw_connection_state %d", ip, mac, fw_connection_state); + + return iptables_fw_access(FW_ACCESS_DENY, ip, mac, fw_connection_state); +} + +/* XXX DCY */ +/** + * Get an IP's MAC address from the ARP cache. + * Go through all the entries in /proc/net/arp until we find the requested + * IP address and return the MAC address bound to it. + * @todo Make this function portable (using shell scripts?) + */ +char * +arp_get(const char *req_ip) +{ + FILE *proc; + char ip[16]; + char mac[18]; + char * reply = NULL; + + if (!(proc = fopen("/proc/net/arp", "r"))) { + return NULL; + } + + /* Skip first line */ + while (!feof(proc) && fgetc(proc) != '\n'); + + /* Find ip, copy mac in reply */ + reply = NULL; + while (!feof(proc) && (fscanf(proc, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %*s", ip, mac) == 2)) { + if (strcmp(ip, req_ip) == 0) { + reply = safe_strdup(mac); + break; + } + } + + fclose(proc); + + return reply; +} + +/** Initialize the firewall rules + */ +int +fw_init(void) +{ + int flags, oneopt = 1, zeroopt = 0; + int result = 0; + t_client * client = NULL; + + debug(LOG_INFO, "Creating ICMP socket"); + if ((icmp_fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1 || + (flags = fcntl(icmp_fd, F_GETFL, 0)) == -1 || + fcntl(icmp_fd, F_SETFL, flags | O_NONBLOCK) == -1 || + setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) || + setsockopt(icmp_fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1) { + debug(LOG_ERR, "Cannot create ICMP raw socket."); + return 0; + } + + debug(LOG_INFO, "Initializing Firewall"); + result = iptables_fw_init(); + + if (restart_orig_pid) { + debug(LOG_INFO, "Restoring firewall rules for clients inherited from parent"); + LOCK_CLIENT_LIST(); + client = client_get_first_client(); + while (client) { + fw_allow(client->ip, client->mac, client->fw_connection_state); + client = client->next; + } + UNLOCK_CLIENT_LIST(); + } + + return result; +} + +/** Remove all auth server firewall whitelist rules + */ +void +fw_clear_authservers(void) +{ + debug(LOG_INFO, "Clearing the authservers list"); + iptables_fw_clear_authservers(); +} + +/** Add the necessary firewall rules to whitelist the authservers + */ +void +fw_set_authservers(void) +{ + debug(LOG_INFO, "Setting the authservers list"); + iptables_fw_set_authservers(); +} + +/** Remove the firewall rules + * This is used when we do a clean shutdown of WiFiDog. + * @return Return code of the fw.destroy script + */ +int +fw_destroy(void) +{ + if (icmp_fd != 0) { + debug(LOG_INFO, "Closing ICMP socket"); + close(icmp_fd); + } + + debug(LOG_INFO, "Removing Firewall rules"); + return iptables_fw_destroy(); +} + +/**Probably a misnomer, this function actually refreshes the entire client list's traffic counter, re-authenticates every client with the central server and update's the central servers traffic counters and notifies it if a client has logged-out. + * @todo Make this function smaller and use sub-fonctions + */ +void +fw_sync_with_authserver(void) +{ + t_authresponse authresponse; + char *token, *ip, *mac; + t_client *p1, *p2; + unsigned long long incoming, outgoing; + s_config *config = config_get_config(); + + if (-1 == iptables_fw_counters_update()) { + debug(LOG_ERR, "Could not get counters from firewall!"); + return; + } + set_client_auth_flag(); + LOCK_CLIENT_LIST(); + + for (p1 = p2 = client_get_first_client(); NULL != p1; p1 = p2) { + p2 = p1->next; + + ip = safe_strdup(p1->ip); + token = safe_strdup(p1->token); + mac = safe_strdup(p1->mac); + outgoing = p1->counters.outgoing; + incoming = p1->counters.incoming; + + UNLOCK_CLIENT_LIST(); + /* Ping the client, if he responds it'll keep activity on the link. + * However, if the firewall blocks it, it will not help. The suggested + * way to deal witht his is to keep the DHCP lease time extremely + * short: Shorter than config->checkinterval * config->clienttimeout */ + icmp_ping(ip); + /* Update the counters on the remote server only if we have an auth server */ + if (config->auth_servers != NULL) { + auth_server_request(&authresponse, REQUEST_TYPE_COUNTERS, ip, mac, token, incoming, outgoing); + } + LOCK_CLIENT_LIST(); + + if (!(p1 = client_list_find(ip, mac))) { + debug(LOG_ERR, "Node %s was freed while being re-validated!", ip); + } else { + time_t current_time=time(NULL); + debug(LOG_INFO, "Checking client %s for timeout: Last updated %ld (%ld seconds ago), timeout delay %ld seconds, current time %ld, ", + p1->ip, p1->counters.last_updated, current_time-p1->counters.last_updated, config->checkinterval * config->clienttimeout, current_time); + if (p1->counters.last_updated + + (config->checkinterval * config->clienttimeout) + <= current_time) { + /* Timing out user */ + debug(LOG_INFO, "%s - Inactive for more than %ld seconds, removing client and denying in firewall", + p1->ip, config->checkinterval * config->clienttimeout); + fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + client_list_delete(p1); + + /* Advertise the logout if we have an auth server */ + if (config->auth_servers != NULL) { + UNLOCK_CLIENT_LIST(); + auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token, 0, 0); + LOCK_CLIENT_LIST(); + } + } else { + /* + * This handles any change in + * the status this allows us + * to change the status of a + * user while he's connected + * + * Only run if we have an auth server + * configured! + */ + if (config->auth_servers != NULL) { + switch (authresponse.authcode) { + case AUTH_DENIED: + debug(LOG_NOTICE, "%s - Denied. Removing client and firewall rules", p1->ip); + fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + client_list_delete(p1); + break; + + case AUTH_VALIDATION_FAILED: + debug(LOG_NOTICE, "%s - Validation timeout, now denied. Removing client and firewall rules", p1->ip); + fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + client_list_delete(p1); + break; + + case AUTH_ALLOWED: + if (p1->fw_connection_state != FW_MARK_KNOWN) { + debug(LOG_INFO, "%s - Access has changed to allowed, refreshing firewall and clearing counters", p1->ip); + //WHY did we deny, then allow!?!? benoitg 2007-06-21 + //fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + + if (p1->fw_connection_state != FW_MARK_PROBATION) { + p1->counters.incoming = p1->counters.outgoing = 0; + } + else { + //We don't want to clear counters if the user was in validation, it probably already transmitted data.. + debug(LOG_INFO, "%s - Skipped clearing counters after all, the user was previously in validation", p1->ip); + } + p1->fw_connection_state = FW_MARK_KNOWN; + fw_allow(p1->ip, p1->mac, p1->fw_connection_state); + } + break; + + case AUTH_VALIDATION: + /* + * Do nothing, user + * is in validation + * period + */ + debug(LOG_INFO, "%s - User in validation period", p1->ip); + break; + + case AUTH_ERROR: + debug(LOG_WARNING, "Error communicating with auth server - leaving %s as-is for now", p1->ip); + break; + + default: + debug(LOG_ERR, "I do not know about authentication code %d", authresponse.authcode); + break; + } + } + } + } + + free(token); + free(ip); + free(mac); + } + UNLOCK_CLIENT_LIST(); +} + +void +icmp_ping(const char *host) +{ + struct sockaddr_in saddr; +#if defined(__linux__) || defined(__NetBSD__) + struct { + struct ip ip; + struct icmp icmp; + } packet; +#endif + unsigned int i, j; + int opt = 2000; + unsigned short id = rand16(); + + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + inet_aton(host, &saddr.sin_addr); +#if defined(HAVE_SOCKADDR_SA_LEN) || defined(__NetBSD__) + saddr.sin_len = sizeof(struct sockaddr_in); +#endif + +#if defined(__linux__) || defined(__NetBSD__) + memset(&packet.icmp, 0, sizeof(packet.icmp)); + packet.icmp.icmp_type = ICMP_ECHO; + packet.icmp.icmp_id = id; + + for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++) + j += ((unsigned short *)&packet.icmp)[i]; + + while (j >> 16) + j = (j & 0xffff) + (j >> 16); + + packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j; + + if (setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == -1) + debug(LOG_ERR, "setsockopt(): %s", strerror(errno)); + + if (sendto(icmp_fd, (char *)&packet.icmp, sizeof(struct icmp), 0, + (const struct sockaddr *)&saddr, sizeof(saddr)) == -1) + debug(LOG_ERR, "sendto(): %s", strerror(errno)); + + opt = 1; + if (setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == -1) + debug(LOG_ERR, "setsockopt(): %s", strerror(errno)); +#endif + + return; +} + +unsigned short rand16(void) { + static int been_seeded = 0; + + if (!been_seeded) { + unsigned int seed = 0; + struct timeval now; + + /* not a very good seed but what the heck, it needs to be quickly acquired */ + gettimeofday(&now, NULL); + seed = now.tv_sec ^ now.tv_usec ^ (getpid() << 16); + + srand(seed); + been_seeded = 1; + } + + /* Some rand() implementations have less randomness in low bits + * than in high bits, so we only pay attention to the high ones. + * But most implementations don't touch the high bit, so we + * ignore that one. + **/ + return( (unsigned short) (rand() >> 15) ); +} diff --git a/src/firewall.h b/src/firewall.h new file mode 100755 index 00000000..45235b07 --- /dev/null +++ b/src/firewall.h @@ -0,0 +1,70 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file firewall.h + @brief Firewall update functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _FIREWALL_H_ +#define _FIREWALL_H_ + +int icmp_fd; + +/** Used by fw_iptables.c */ +typedef enum _t_fw_marks { + FW_MARK_PROBATION = 1, /**< @brief The client is in probation period and must be authenticated + @todo: VERIFY THAT THIS IS ACCURATE*/ + FW_MARK_KNOWN = 2, /**< @brief The client is known to the firewall */ + FW_MARK_LOCKED = 254 /**< @brief The client has been locked out */ +} t_fw_marks; + +/** @brief Initialize the firewall */ +int fw_init(void); + +/** @brief Clears the authservers list */ +void fw_clear_authservers(void); + +/** @brief Sets the authservers list */ +void fw_set_authservers(void); + +/** @brief Destroy the firewall */ +int fw_destroy(void); + +/** @brief Allow a user through the firewall*/ +int fw_allow(const char *ip, const char *mac, int profile); + +/** @brief Deny a client access through the firewall*/ +int fw_deny(const char *ip, const char *mac, int profile); + +/** @brief Refreshes the entire client list */ +void fw_sync_with_authserver(void); + +/** @brief Get an IP's MAC address from the ARP cache.*/ +char *arp_get(const char *req_ip); + +/** @brief ICMP Ping an IP */ +void icmp_ping(const char *host); + +/** @brief cheap random */ +unsigned short rand16(void); + +#endif /* _FIREWALL_H_ */ diff --git a/src/fw_iptables.c b/src/fw_iptables.c new file mode 100755 index 00000000..bda82ca3 --- /dev/null +++ b/src/fw_iptables.c @@ -0,0 +1,720 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @internal + @file fw_iptables.c + @brief Firewall iptables functions + @author Copyright (C) 2004 Philippe April + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "safe.h" +#include "conf.h" +#include "fw_iptables.h" +#include "firewall.h" +#include "debug.h" +#include "util.h" +#include "client_list.h" + +/*limeng*/ +#include + +static int iptables_do_command(const char *format, ...); +static char *iptables_compile(const char *, const char *, const t_firewall_rule *); +static void iptables_load_ruleset(const char *, const char *, const char *); + +extern pthread_mutex_t client_list_mutex; +extern pthread_mutex_t config_mutex; + +/** +Used to supress the error output of the firewall during destruction */ +static int fw_quiet = 0; + +/** @internal + * @brief Insert $ID$ with the gateway's id in a string. + * + * This function can replace the input string with a new one. It assumes + * the input string is dynamically allocted and can be free()ed safely. + * + * This function must be called with the CONFIG_LOCK held. + */ +static void +iptables_insert_gateway_id(char **input) +{ + char *token; + const s_config *config; + char *buffer; + + if (strstr(*input, "$ID$")==NULL) + return; + + + while ((token=strstr(*input, "$ID$"))!=NULL) + /* This string may look odd but it's standard POSIX and ISO C */ + memcpy(token, "%1$s", 4); + + config = config_get_config(); + safe_asprintf(&buffer, *input, config->gw_interface); + + free(*input); + *input=buffer; +} + +/** @internal + * */ +static int +iptables_do_command(const char *format, ...) +{ + va_list vlist; + char *fmt_cmd; + char *cmd; + int rc; + + va_start(vlist, format); + safe_vasprintf(&fmt_cmd, format, vlist); + va_end(vlist); + + safe_asprintf(&cmd, "iptables %s", fmt_cmd); + free(fmt_cmd); + + iptables_insert_gateway_id(&cmd); + + debug(LOG_DEBUG, "Executing command: %s", cmd); + + rc = execute(cmd, fw_quiet); + + if (rc!=0) { + // If quiet, do not display the error + if (fw_quiet == 0) + debug(LOG_ERR, "iptables command failed(%d): %s", rc, cmd); + else if (fw_quiet == 1) + debug(LOG_DEBUG, "iptables command failed(%d): %s", rc, cmd); + } + + free(cmd); + + return rc; +} + +/** + * @internal + * Compiles a struct definition of a firewall rule into a valid iptables + * command. + * @arg table Table containing the chain. + * @arg chain Chain that the command will be (-A)ppended to. + * @arg rule Definition of a rule into a struct, from conf.c. + */ + static char * +iptables_compile(const char * table, const char *chain, const t_firewall_rule *rule) +{ + char command[MAX_BUF], + *mode; + + memset(command, 0, MAX_BUF); + + switch (rule->target){ + case TARGET_DROP: + mode = safe_strdup("DROP"); + break; + case TARGET_REJECT: + mode = safe_strdup("REJECT"); + break; + case TARGET_ACCEPT: + mode = safe_strdup("ACCEPT"); + break; + case TARGET_LOG: + mode = safe_strdup("LOG"); + break; + case TARGET_ULOG: + mode = safe_strdup("ULOG"); + break; + } + + snprintf(command, sizeof(command), "-t %s -A %s ",table, chain); + if (rule->mask != NULL) { + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "-d %s ", rule->mask); + } + if (rule->protocol != NULL) { + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "-p %s ", rule->protocol); + } + if (rule->port != NULL) { + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "--dport %s ", rule->port); + } + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "-j %s", mode); + + free(mode); + + /* XXX The buffer command, an automatic variable, will get cleaned + * off of the stack when we return, so we strdup() it. */ + return(safe_strdup(command)); +} + +/** + * @internal + * Load all the rules in a rule set. + * @arg ruleset Name of the ruleset + * @arg table Table containing the chain. + * @arg chain IPTables chain the rules go into + */ + static void +iptables_load_ruleset(const char * table, const char *ruleset, const char *chain) +{ + t_firewall_rule *rule; + char *cmd; + + debug(LOG_DEBUG, "Load ruleset %s into table %s, chain %s", ruleset, table, chain); + + for (rule = get_ruleset(ruleset); rule != NULL; rule = rule->next) { + cmd = iptables_compile(table, chain, rule); + debug(LOG_DEBUG, "Loading rule \"%s\" into table %s, chain %s", cmd, table, chain); + iptables_do_command(cmd); + free(cmd); + } + + debug(LOG_DEBUG, "Ruleset %s loaded into table %s, chain %s", ruleset, table, chain); +} + + void +iptables_fw_clear_authservers(void) +{ + iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); +} + + void +iptables_fw_set_authservers(void) +{ + const s_config *config; + t_auth_serv *auth_server; + + config = config_get_config(); + + for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { + if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) { + iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); + } + } +} + +/** Initialize the firewall rules +*/ + int +iptables_fw_init(void) +{ + const s_config *config; + char * ext_interface = NULL; + int gw_port = 0; + t_trusted_mac *p; + t_white_list *p0; + t_black_list *p1; + t_untrusted_mac *p3; + int proxy_port; + fw_quiet = 0; + + LOCK_CONFIG(); + config = config_get_config(); + gw_port = config->gw_port; + if (config->external_interface) { + ext_interface = safe_strdup(config->external_interface); + } else { + ext_interface = get_ext_iface(); + } + + if (ext_interface == NULL) { + UNLOCK_CONFIG(); + debug(LOG_ERR, "FATAL: no external interface"); + return 0; + } + /* + * + * Everything in the MANGLE table + * + */ + + /* Create new chains */ + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED); + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING); + /* gaomingpan:Untrusted mac chains*/ + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_UNTRUSTED); + /* limeng */ + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_BLACKLIST); + + /* Assign links and rules to these new chains */ + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, config->gw_interface);//this rule will be inserted before the prior one + iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, config->gw_interface); + + for (p = config->trustedmaclist; p != NULL; p = p->next) + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN); + + /*gaomingpan untrusted mac list*/ + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_UNTRUSTED, config->gw_interface); + for (p3 = config->untrustedmaclist; p3 != NULL; p3 = p3->next){ + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s --j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); + debug(LOG_INFO,"Untrusted mac: %s ",p3->mac); + } + /* limeng */ + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_BLACKLIST, config->gw_interface); + for (p1 = config->black_list; p1 != NULL; p1 = p1->next) + { + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); + } + + /* + * + * Everything in the NAT table + * + */ + + /* Create new chains */ + iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS); + /* limeng */ + iptables_do_command("-t nat -N " TABLE_WIFIDOG_WHITELIST); + + /* Assign links and rules to these new chains */ + iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, config->gw_address); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT"); + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET); + + if((proxy_port=config_get_config()->proxy_port) != 0){ + debug(LOG_DEBUG,"Proxy port set, setting proxy rule"); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_KNOWN, proxy_port); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_PROBATION, proxy_port); + } + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port); + /* limeng */ + iptables_do_command("-t nat -I" TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + + /* + * + * Everything in the FILTER table + * + */ + + /* Create new chains */ + iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN); + /* limeng */ + iptables_do_command("-t filter -N " TABLE_WIFIDOG_WHITELIST); + + /* Assign links and rules to these new chains */ + + /* Insert at the beginning */ + iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, config->gw_interface); + + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP"); + + /* XXX: Why this? it means that connections setup after authentication + stay open even after the connection is done... + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/ + + //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23 + //iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface); + + /* TCPMSS rule for PPPoE */ + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS); + iptables_fw_set_authservers(); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED); + iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL); + iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL); + iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION); + iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN); + iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); + iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable"); + + /* limeng */ + iptables_do_command("-t filter -I" TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + + UNLOCK_CONFIG(); + return 1; +} + +void iptables_white_black_list_update(void) +{ + //static time_t timer_old; + //static time_t timer_new; + time_t sec; + struct tm * curTime; + sec = time(NULL); + curTime = localtime(&sec); + static int sec_old = 0; + + t_white_list *p0 = NULL; + t_black_list *p1 = NULL; + const s_config *config; + + if(curTime->tm_sec != sec_old) + { + sec_old = curTime->tm_sec; + + if(curTime->tm_sec == 0 && curTime->tm_min == 0 && curTime->tm_hour == 4) + { + LOCK_CONFIG(); + config = config_get_config(); + + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_BLACKLIST); + for (p1 = config->black_list; p1 != NULL; p1 = p1->next) + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); + + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + + iptables_do_command("-t filter -F " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + } + + UNLOCK_CONFIG(); + } +} + + +/** Remove the firewall rules + * This is used when we do a clean shutdown of WiFiDog and when it starts to make + * sure there are no rules left over + */ + int +iptables_fw_destroy(void) +{ + fw_quiet = 1; + + debug(LOG_DEBUG, "Destroying our iptables entries"); + + /* + * + * Everything in the MANGLE table + * + */ + debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED); + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_UNTRUSTED);/*gaomingpan: untrusted macs*/ + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); + iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING); + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_BLACKLIST); + + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED); + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_UNTRUSTED); /*gaomingpan: untrusted macs*/ + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_BLACKLIST); + + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED); + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_UNTRUSTED); /*gaomingpan: untrusted macs*/ + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_BLACKLIST); + + /* + * + * Everything in the NAT table + * + */ + debug(LOG_DEBUG, "Destroying chains in the NAT table"); + iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WHITELIST); + + iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_WHITELIST); + + /* + * + * Everything in the FILTER table + * + */ + debug(LOG_DEBUG, "Destroying chains in the FILTER table"); + iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_WHITELIST); + + iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_WHITELIST); + + return 1; +} + +/* + * Helper for iptables_fw_destroy + * @param table The table to search + * @param chain The chain in that table to search + * @param mention A word to find and delete in rules in the given table+chain + */ +int +iptables_fw_destroy_mention( + const char * table, + const char * chain, + const char * mention + ) { + FILE *p = NULL; + char *command = NULL; + char *command2 = NULL; + char line[MAX_BUF]; + char rulenum[10]; + char *victim = safe_strdup(mention); + int deleted = 0; + + iptables_insert_gateway_id(&victim); + + debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", victim, table, chain); + + safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain); + iptables_insert_gateway_id(&command); + + if ((p = popen(command, "r"))) { + /* Skip first 2 lines */ + while (!feof(p) && fgetc(p) != '\n'); + while (!feof(p) && fgetc(p) != '\n'); + /* Loop over entries */ + while (fgets(line, sizeof(line), p)) { + /* Look for victim */ + if (strstr(line, victim)) { + /* Found victim - Get the rule number into rulenum*/ + if (sscanf(line, "%9[0-9]", rulenum) == 1) { + /* Delete the rule: */ + debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, victim); + safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); + iptables_do_command(command2); + free(command2); + deleted = 1; + /* Do not keep looping - the captured rulenums will no longer be accurate */ + break; + } + } + } + pclose(p); + } + + free(command); + free(victim); + + if (deleted) { + /* Recurse just in case there are more in the same table+chain */ + iptables_fw_destroy_mention(table, chain, mention); + } + + return (deleted); +} + +/** Set if a specific client has access through the firewall */ + int +iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag) +{ + int rc; + + fw_quiet = 0; + + switch(type) { + case FW_ACCESS_ALLOW: + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); + rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); + break; + case FW_ACCESS_DENY: + iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); + rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); + break; + default: + rc = -1; + break; + } + + return rc; +} + +/** Update the counters of all the clients in the client list */ + int +iptables_fw_counters_update(void) +{ + FILE *output; + char *script, + ip[16], + rc; + unsigned long long int counter; + t_client *p1; + struct in_addr tempaddr; + + /* Look for outgoing traffic */ + safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING); + iptables_insert_gateway_id(&script); + output = popen(script, "r"); + free(script); + if (!output) { + debug(LOG_ERR, "popen(): %s", strerror(errno)); + return -1; + } + + /* skip the first two lines */ + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (output && !(feof(output))) { + rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); + //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); + if (2 == rc && EOF != rc) { + /* Sanity*/ + if (!inet_aton(ip, &tempaddr)) { + debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); + continue; + } + debug(LOG_DEBUG, "Read outgoing traffic for %s: Bytes=%llu", ip, counter); + LOCK_CLIENT_LIST(); + if ((p1 = client_list_find_by_ip(ip))) { + if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { + p1->counters.outgoing = p1->counters.outgoing_history + counter; + p1->counters.last_updated = time(NULL); + debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes. Updated last_updated to %d", ip, counter, p1->counters.last_updated); + } + } else { + debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); + } + UNLOCK_CLIENT_LIST(); + } + } + pclose(output); + + /* Look for incoming traffic */ + safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING); + iptables_insert_gateway_id(&script); + output = popen(script, "r"); + free(script); + if (!output) { + debug(LOG_ERR, "popen(): %s", strerror(errno)); + return -1; + } + + /* skip the first two lines */ + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (output && !(feof(output))) { + rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); + if (2 == rc && EOF != rc) { + /* Sanity*/ + if (!inet_aton(ip, &tempaddr)) { + debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); + continue; + } + debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter); + LOCK_CLIENT_LIST(); + if ((p1 = client_list_find_by_ip(ip))) { + if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { + p1->counters.incoming = p1->counters.incoming_history + counter; + debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); + } + } else { + debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); + } + UNLOCK_CLIENT_LIST(); + } + } + pclose(output); + + return 1; +} diff --git a/src/fw_iptables.h b/src/fw_iptables.h new file mode 100755 index 00000000..2e52ba0a --- /dev/null +++ b/src/fw_iptables.h @@ -0,0 +1,82 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file fw_iptables.h + @brief Firewall iptables functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _FW_IPTABLES_H_ +#define _FW_IPTABLES_H_ + +#include "firewall.h" + +/*@{*/ +/**Iptable table names used by WifiDog */ +#define TABLE_WIFIDOG_OUTGOING "WiFiDog_$ID$_Outgoing" +#define TABLE_WIFIDOG_WIFI_TO_INTERNET "WiFiDog_$ID$_WIFI2Internet" +#define TABLE_WIFIDOG_WIFI_TO_ROUTER "WiFiDog_$ID$_WIFI2Router" +#define TABLE_WIFIDOG_INCOMING "WiFiDog_$ID$_Incoming" +#define TABLE_WIFIDOG_AUTHSERVERS "WiFiDog_$ID$_AuthServers" +#define TABLE_WIFIDOG_GLOBAL "WiFiDog_$ID$_Global" +#define TABLE_WIFIDOG_VALIDATE "WiFiDog_$ID$_Validate" +#define TABLE_WIFIDOG_KNOWN "WiFiDog_$ID$_Known" +#define TABLE_WIFIDOG_UNKNOWN "WiFiDog_$ID$_Unknown" +#define TABLE_WIFIDOG_LOCKED "WiFiDog_$ID$_Locked" +#define TABLE_WIFIDOG_TRUSTED "WiFiDog_$ID$_Trusted" +/*gaomingpan*/ +#define TABLE_WIFIDOG_UNTRUSTED "WiFiDog_$ID$_Untrusted" +/* limeng */ +#define TABLE_WIFIDOG_WHITELIST "WiFiDog_$ID$_WhiteList" +#define TABLE_WIFIDOG_BLACKLIST "WiFiDog_$ID$_BlackList" + +/*@}*/ + +/** Used by iptables_fw_access to select if the client should be granted of denied access */ +typedef enum fw_access_t_ { + FW_ACCESS_ALLOW, + FW_ACCESS_DENY +} fw_access_t; + +/** @brief Initialize the firewall */ +int iptables_fw_init(void); +void iptables_white_black_list_update(void); + + +/** @brief Initializes the authservers table */ +void iptables_fw_set_authservers(void); + +/** @brief Clears the authservers table */ +void iptables_fw_clear_authservers(void); + +/** @brief Destroy the firewall */ +int iptables_fw_destroy(void); + +/** @brief Helper function for iptables_fw_destroy */ +int iptables_fw_destroy_mention( const char * table, const char * chain, const char * mention); + +/** @brief Define the access of a specific client */ +int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag); + +/** @brief All counters in the client list */ +int iptables_fw_counters_update(void); + +#endif /* _IPTABLES_H_ */ diff --git a/src/gateway.c b/src/gateway.c new file mode 100755 index 00000000..5a6e29ed --- /dev/null +++ b/src/gateway.c @@ -0,0 +1,573 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free:Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @internal + @file gateway.c + @brief Main loop + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2004 Alexandre Carmel-Veilleux + */ + +#include +#include +#include +#include +#include +#include +#include + +/* for strerror() */ +#include + +/* for wait() */ +#include + +/* for unix socket communication*/ +#include +#include + +#include "common.h" +#include "httpd.h" +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "gateway.h" +#include "firewall.h" +#include "commandline.h" +#include "auth.h" +#include "http.h" +#include "client_list.h" +#include "wdctl_thread.h" +#include "ping_thread.h" +#include "httpd_thread.h" +#include "util.h" + + +#include "get_remote_shell.h" + +/** XXX Ugly hack + * We need to remember the thread IDs of threads that simulate wait with pthread_cond_timedwait + * so we can explicitly kill them in the termination handler + */ +static pthread_t tid_fw_counter = 0; +static pthread_t tid_ping = 0; + +/* The internal web server */ +httpd * webserver = NULL; + +/* from commandline.c */ +extern char ** restartargv; +extern pid_t restart_orig_pid; +t_client *firstclient; + +/* from client_list.c */ +extern pthread_mutex_t client_list_mutex; + +/* Time when wifidog started */ +time_t started_time = 0; + +/* Appends -x, the current PID, and NULL to restartargv + * see parse_commandline in commandline.c for details + * + * Why is restartargv global? Shouldn't it be at most static to commandline.c + * and this function static there? -Alex @ 8oct2006 + */ +void append_x_restartargv(void) { + int i; + + for (i=0; restartargv[i]; i++); + + restartargv[i++] = safe_strdup("-x"); + safe_asprintf(&(restartargv[i++]), "%d", getpid()); +} + +/* @internal + * @brief During gateway restart, connects to the parent process via the internal socket + * Downloads from it the active client list + */ +void get_clients_from_parent(void) { + int sock; + struct sockaddr_un sa_un; + s_config * config = NULL; + char linebuffer[MAX_BUF]; + int len = 0; + char *running1 = NULL; + char *running2 = NULL; + char *token1 = NULL; + char *token2 = NULL; + char onechar; + char *command = NULL; + char *key = NULL; + char *value = NULL; + t_client * client = NULL; + t_client * lastclient = NULL; + + config = config_get_config(); + + debug(LOG_INFO, "Connecting to parent to download clients"); + + /* Connect to socket */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + memset(&sa_un, 0, sizeof(sa_un)); + sa_un.sun_family = AF_UNIX; + strncpy(sa_un.sun_path, config->internal_sock, (sizeof(sa_un.sun_path) - 1)); + + if (connect(sock, (struct sockaddr *)&sa_un, strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { + debug(LOG_ERR, "Failed to connect to parent (%s) - client list not downloaded", strerror(errno)); + return; + } + + debug(LOG_INFO, "Connected to parent. Downloading clients"); + + LOCK_CLIENT_LIST(); + + command = NULL; + memset(linebuffer, 0, sizeof(linebuffer)); + len = 0; + client = NULL; + /* Get line by line */ + while (read(sock, &onechar, 1) == 1) { + if (onechar == '\n') { + /* End of line */ + onechar = '\0'; + } + linebuffer[len++] = onechar; + + if (!onechar) { + /* We have a complete entry in linebuffer - parse it */ + debug(LOG_DEBUG, "Received from parent: [%s]", linebuffer); + running1 = linebuffer; + while ((token1 = strsep(&running1, "|")) != NULL) { + if (!command) { + /* The first token is the command */ + command = token1; + } + else { + /* Token1 has something like "foo=bar" */ + running2 = token1; + key = value = NULL; + while ((token2 = strsep(&running2, "=")) != NULL) { + if (!key) { + key = token2; + } + else if (!value) { + value = token2; + } + } + } + + if (strcmp(command, "CLIENT") == 0) { + /* This line has info about a client in the client list */ + if (!client) { + /* Create a new client struct */ + client = safe_malloc(sizeof(t_client)); + memset(client, 0, sizeof(t_client)); + } + } + + if (key && value) { + if (strcmp(command, "CLIENT") == 0) { + /* Assign the key into the appropriate slot in the connection structure */ + if (strcmp(key, "ip") == 0) { + client->ip = safe_strdup(value); + } + else if (strcmp(key, "mac") == 0) { + client->mac = safe_strdup(value); + } + else if (strcmp(key, "token") == 0) { + client->token = safe_strdup(value); + } + else if (strcmp(key, "fw_connection_state") == 0) { + client->fw_connection_state = atoi(value); + } + else if (strcmp(key, "fd") == 0) { + client->fd = atoi(value); + } + else if (strcmp(key, "counters_incoming") == 0) { + client->counters.incoming_history = atoll(value); + client->counters.incoming = client->counters.incoming_history; + } + else if (strcmp(key, "counters_outgoing") == 0) { + client->counters.outgoing_history = atoll(value); + client->counters.outgoing = client->counters.outgoing_history; + } + else if (strcmp(key, "counters_last_updated") == 0) { + client->counters.last_updated = atol(value); + } + else { + debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); + } + } + } + } + + /* End of parsing this command */ + if (client) { + /* Add this client to the client list */ + if (!firstclient) { + firstclient = client; + lastclient = firstclient; + } + else { + lastclient->next = client; + lastclient = client; + } + } + + /* Clean up */ + command = NULL; + memset(linebuffer, 0, sizeof(linebuffer)); + len = 0; + client = NULL; + } + } + + UNLOCK_CLIENT_LIST(); + debug(LOG_INFO, "Client list downloaded successfully from parent"); + + close(sock); +} + +/**@internal + * @brief Handles SIGCHLD signals to avoid zombie processes + * + * When a child process exits, it causes a SIGCHLD to be sent to the + * process. This handler catches it and reaps the child process so it + * can exit. Otherwise we'd get zombie processes. + */ +void +sigchld_handler(int s) +{ + int status; + pid_t rc; + + debug(LOG_DEBUG, "Handler for SIGCHLD called. Trying to reap a child"); + + rc = waitpid(-1, &status, WNOHANG); + + debug(LOG_DEBUG, "Handler for SIGCHLD reaped child PID %d", rc); +} + +/** Exits cleanly after cleaning up the firewall. + * Use this function anytime you need to exit after firewall initialization */ +void +termination_handler(int s) +{ + static pthread_mutex_t sigterm_mutex = PTHREAD_MUTEX_INITIALIZER; + + debug(LOG_INFO, "Handler for termination caught signal %d", s); + + /* Makes sure we only call fw_destroy() once. */ + if (pthread_mutex_trylock(&sigterm_mutex)) { + debug(LOG_INFO, "Another thread already began global termination handler. I'm exiting"); + pthread_exit(NULL); + } + else { + debug(LOG_INFO, "Cleaning up and exiting"); + } + + debug(LOG_INFO, "Flushing firewall rules..."); + fw_destroy(); + + /* XXX Hack + * Aparently pthread_cond_timedwait under openwrt prevents signals (and therefore + * termination handler) from happening so we need to explicitly kill the threads + * that use that + */ + if (tid_fw_counter) { + debug(LOG_INFO, "Explicitly killing the fw_counter thread"); + pthread_kill(tid_fw_counter, SIGKILL); + } + if (tid_ping) { + debug(LOG_INFO, "Explicitly killing the ping thread"); + pthread_kill(tid_ping, SIGKILL); + } + + debug(LOG_NOTICE, "Exiting..."); + exit(s == 0 ? 1 : 0); +} + +/** @internal + * Registers all the signal handlers + */ +static void +init_signals(void) +{ + struct sigaction sa; + + debug(LOG_DEBUG, "Initializing signal handlers"); + + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + if (sigaction(SIGCHLD, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + /* Trap SIGPIPE */ + /* This is done so that when libhttpd does a socket operation on + * a disconnected socket (i.e.: Broken Pipes) we catch the signal + * and do nothing. The alternative is to exit. SIGPIPE are harmless + * if not desirable. + */ + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + sa.sa_handler = termination_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + /* Trap SIGTERM */ + if (sigaction(SIGTERM, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + /* Trap SIGQUIT */ + if (sigaction(SIGQUIT, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + /* Trap SIGINT */ + if (sigaction(SIGINT, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } +} + +/**@internal + * Main execution loop + */ +static void +main_loop(void) +{ + int result; + pthread_t tid; + s_config *config = config_get_config(); + request *r; + void **params; + + /* Set the time when wifidog started */ + if (!started_time) { + debug(LOG_INFO, "Setting started_time"); + started_time = time(NULL); + } + else if (started_time < MINIMUM_STARTED_TIME) { + debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); + started_time = time(NULL); + } + + /* If we don't have the Gateway IP address, get it. Can't fail. */ + if (!config->gw_address) { + debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); + if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { + debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); + exit(1); + } + debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); + } + + /* If we don't have the Gateway ID, construct it from the internal MAC address. + * "Can't fail" so exit() if the impossible happens. */ + if (!config->gw_id) { + debug(LOG_DEBUG, "Finding MAC address of %s", config->gw_interface); + if ((config->gw_id = get_iface_mac(config->gw_interface)) == NULL) { + debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); + exit(1); + } + debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_id); + } + + /* Initializes the web server */ + debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); + if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { + debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); + exit(1); + } + + /**** init my post url config *****/ + if(0 != init_post_http_url_config() ) + { + debug(LOG_ERR, "FATAL: Failed to initialize init_post_http_url_config"); + exit(1); + } + /*********************************/ + + debug(LOG_DEBUG, "Assigning callbacks to web server"); + httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog); + httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog); + httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about); + httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status); + httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth); + + httpdAddC404Content(webserver, http_callback_404); + + /* Reset the firewall (if WiFiDog crashed) */ + fw_destroy(); + /* Then initialize it */ + if (!fw_init()) { + debug(LOG_ERR, "FATAL: Failed to initialize firewall"); + exit(1); + } + + /* Start clean up thread */ + result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting"); + termination_handler(0); + } + pthread_detach(tid_fw_counter); + + /* Start control thread */ + result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); + termination_handler(0); + } + pthread_detach(tid); + + /* Start heartbeat thread */ + result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting"); + termination_handler(0); + } + pthread_detach(tid_ping); + + debug(LOG_NOTICE, "Waiting for connections"); + while(1) { + r = httpdGetConnection(webserver, NULL); + + /* We can't convert this to a switch because there might be + * values that are not -1, 0 or 1. */ + if (webserver->lastError == -1) { + /* Interrupted system call */ + continue; /* restart loop */ + } + else if (webserver->lastError < -1) { + /* + * FIXME + * An error occurred - should we abort? + * reboot the device ? + */ + debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); + termination_handler(0); + } + else if (r != NULL) { + /* + * We got a connection + * + * We should create another thread + */ + debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); + /* The void**'s are a simulation of the normal C + * function calling sequence. */ + params = safe_malloc(2 * sizeof(void *)); + *params = webserver; + *(params + 1) = r; + + result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); + termination_handler(0); + } + pthread_detach(tid); + } + else { + /* webserver->lastError should be 2 */ + /* XXX We failed an ACL.... No handling because + * we don't set any... */ + } + + /* limeng */ + iptables_white_black_list_update(); + } + + /* never reached */ +} + +/** Reads the configuration file and then starts the main loop */ +int main(int argc, char **argv) { + + s_config *config = config_get_config(); + config_init(); + + parse_commandline(argc, argv); + + /* Initialize the config */ + config_read(config->configfile); + config_validate(); + + /* Initializes the linked list of connected clients */ + client_list_init(); + + /* Init the signals to catch chld/quit/etc */ + init_signals(); + + + if (restart_orig_pid) { + /* + * We were restarted and our parent is waiting for us to talk to it over the socket + */ + get_clients_from_parent(); + + /* + * At this point the parent will start destroying itself and the firewall. Let it finish it's job before we continue + */ + while (kill(restart_orig_pid, 0) != -1) { + debug(LOG_INFO, "Waiting for parent PID %d to die before continuing loading", restart_orig_pid); + sleep(1); + } + + debug(LOG_INFO, "Parent PID %d seems to be dead. Continuing loading."); + } + + if (config->daemon) { + + debug(LOG_INFO, "Forking into background"); + + switch(safe_fork()) { + case 0: /* child */ + setsid(); + append_x_restartargv(); + main_loop(); + break; + + default: /* parent */ + exit(0); + break; + } + } + else { + append_x_restartargv(); + main_loop(); + } + + return(0); /* never reached */ +} + + + diff --git a/src/gateway.h b/src/gateway.h new file mode 100755 index 00000000..264de2c7 --- /dev/null +++ b/src/gateway.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file gateway.h + @brief Main loop + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _GATEWAY_H_ +#define _GATEWAY_H_ + +/** @brief exits cleanly and clear the firewall rules. */ +void termination_handler(int s); + +#endif /* _GATEWAY_H_ */ diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c new file mode 100644 index 00000000..8c1dcef0 --- /dev/null +++ b/src/get_clientinfo.c @@ -0,0 +1,443 @@ +/* + * get_clientinfo.c + * + * Created on: Jul 13, 2015 + * Author: GaomingPan + */ + + +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "debug.h" +#include "conf.h" +#include "client_list.h" +#include "../config.h" + + +#include "shell_command.h" +#include "get_clientinfo.h" + + +static t_clientinfo *first_client_info = NULL; + +static char client_auth_flag[7]; + +/* @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:void + * @RETURN_VALUE:zero is success,others is error. + * @Note: after this function be called and you got some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int collect_client_info() +{ + FILE *fp, + *fp_shell, + *fp_upspeed, + *fp_downspeed; + + char info_buf[1024], + chain_test[64], + ip[18]; + + int speed; + + char *ptr, + *token; + + t_clientinfo *p1, + *p2, + *p3; + int i = 0; + + memset(info_buf,0,1024); + first_client_info = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == first_client_info) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + printf("ERROR: at collect_client_info(), malloc error.\n"); + return -1; + } + first_client_info->next = NULL; + + p1 = first_client_info; + p2 = p1; + + fp = popen(CMD_GET_CLIENT_LIST,"r"); + + if(NULL == fp) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),popen error."); + printf("ERROR: at collect_client_info(),popen error.\n"); + return -2; + } + + while(NULL != fgets(info_buf,1024,fp)) + { + + if(NULL == p1) + { + p1 = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == p1) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + + printf("ERROR: at collect_client_info(), malloc error.\n"); + pclose(fp); + return -3; + } + p2->next = p1; + p2 = p1; + p1->next = NULL; + + }//if + + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(40); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error.\n"); + printf("ERROR: at collect_client_info(), malloc error.\n"); + pclose(fp); + return -4; + } + strcpy(token,ptr); + if(1 == i) + { + strcpy(p1->client_mac,token); + free(token); + continue; + } + if(2 == i) + { + strcpy(p1->client_ip,token); + free(token); + continue; + } + if(3 == i) + { + strcpy(p1->host_name,token); + free(token); + break; + } + }//for + p1 = p1->next; + i = 0; + memset(info_buf,0,1024); + }//while + + pclose(fp); + + + /* get speed files + * */ + memset(chain_test,0,64); + fp_shell = popen(CMD_MAKE_SPEED_FILE,"r"); + if(NULL == fp_shell) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); + printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); + return -5; + } + fread(chain_test,64,1,fp_shell); + pclose(fp_shell); + + + /* do some clean up,if it needs. + * */ + int ret; + ret = clean_more_chain(); + if(0 != ret) + { + debug(LOG_ERR,"ERROR: clean_more_chain() return value:%d\n",ret); + printf("ERROR: clean_more_chain() return value:%d\n",ret); + } + + + /* get up speed + * */ + fp_upspeed = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp_upspeed) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_upseed error."); + printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); + return -6; + } + memset(info_buf,0,1024); + memset(ip,0,18); + i = 0; + while(NULL != fgets(info_buf,1024,fp_upspeed)) + { + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(20); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + printf("ERROR: at collect_client_info(), malloc error.\n"); + fclose(fp_upspeed); + return -7; + } + strcpy(token,ptr); + if(i == 1) + { + strcpy(ip,token); + free(token); + continue; + } + if(i == 2) + { + speed = atoi(token); + free(token); + p3 = get_client_info_by_ip(ip); + if(NULL != p3) + { + p3->go_speed = speed; + } + memset(ip,0,18); + i = 0; + break; + } + }//for + }//while + fclose(fp_upspeed); + + + /* get the down speed + * */ + fp_downspeed = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp_downspeed) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_downspeed error."); + printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); + return -8; + } + memset(info_buf,0,1024); + memset(ip,0,18); + i = 0; + while(NULL != fgets(info_buf,1024,fp_downspeed)) + { + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(40); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + printf("ERROR: at collect_client_info(), malloc error.\n"); + fclose(fp_downspeed); + return -9; + } + strcpy(token,ptr); + if(i == 1) + { + strcpy(ip,token); + free(token); + continue; + } + if(i == 2) + { + speed = atoi(token); + free(token); + p3 = get_client_info_by_ip(ip); + if(NULL != p3) + { + p3->come_speed = speed; + } + memset(ip,0,18); + i = 0; + break; + } + } + }//while + fclose(fp_downspeed); + + return 0; +} + + +/* @breif After the function collect_client_info() called,should call this function to + * clean up. + * @PARAMETER:void + * @RETURN_VALUE:void + * @Note: function collect_client_info() and this function just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +void clean_client_info() +{ + t_clientinfo *p1, + *p2; + + p1 = first_client_info; + p2 = p1->next; + + while(NULL != p1) + { + free(p1); + p1 = p2; + if(NULL != p2) + p2 = p2->next; + } +} + + + +/* @breif find the element from the client_info list by mac. + * @PARAMETER:[const char *mac],the pointer point to by mac. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_mac(const char *mac) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p) + { + if(strcmp(mac,p->client_mac) == 0) + { + return p; + } + p = p->next; + } + return NULL; +} + + + +/* @breif find the element from the client_info list by ip. + * @PARAMETER:[const char *ip],the pointer point to by ip. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_ip(const char *ip) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p) + { + if(strcmp(ip,p->client_ip) == 0) + { + return p; + } + p = p->next; + } + return NULL; +} + + + +long get_online_time(const char *ip,const char *mac) +{ + t_client *ptr; + long online_time = 0; + + ptr = client_list_find(ip,mac); + + if(NULL!= ptr) + { + online_time = time(NULL) - ptr->record_time; + } + + return online_time; +} + + + +int clean_more_chain() +{ + FILE *fp; + + char chain_test[10]; + + int chain_num = 0, + m = 0, + failed_count = 0; + + + memset(chain_test,0,10); + fp = popen(CMD_GET_CHAIN_NUM,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); + printf("ERROR: at collect_client_info(),popen for fp error.\n"); + return -1; + } + pclose(fp); + + fp = fopen("/tmp/client.speed.chain.num","r"); + if(NULL == fp) + { + debug(LOG_ERR,"ERROR: fopen() /tmp/client.speed.chain.num\n"); + printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); + return -2; + } + while(NULL != fgets(chain_test,10,fp)) + { + m = atoi(chain_test); + + if(m > chain_num) + chain_num = m; + } + fclose(fp); + + while( --chain_num > 0) + { + + fp = popen(CMD_CLEAN_SPEED_CHAIN,"r"); + if(NULL != fp) + { + pclose(fp); + debug(LOG_INFO,"INFO: clean iptables chain"); + printf("INFO: clean iptables chain\n"); + } + else + { + failed_count++; + debug(LOG_ERR,"ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)"); + printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); + } + } + + return failed_count; +} + + + +char *get_client_auth_flag() +{ + return client_auth_flag; +} + + + + +void set_client_auth_flag() +{ + // rand()%(max - min + 1) + min + int i; + for(i = 0;i<6;i++) + client_auth_flag[i] = rand()%(90 - 65 + 1) + 65; + + client_auth_flag[6] = 0; +} + + diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h new file mode 100644 index 00000000..12d592c8 --- /dev/null +++ b/src/get_clientinfo.h @@ -0,0 +1,89 @@ +/* + * get_clientinfo.h + * + * Created on: Jul 13, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_GET_CLIENTINFO_H_ +#define SRC_GET_CLIENTINFO_H_ + + +#define CLIENT_HOST_NAME_LEN 40 +#define CLIENT_MAC_ADDRESS_LEN 18 +#define CLIENT_IP_ADDRESS_LEN 16 + +#define UP_SPEED_FILE "/tmp/client.up.speed" +#define DOWN_SPEED_FILE "/tmp/client.down.speed" + + +/*@breif the sturct for client_info list + * */ +typedef struct _t_clientinfo{ + + char client_mac[CLIENT_MAC_ADDRESS_LEN]; + char client_ip[CLIENT_IP_ADDRESS_LEN]; + char host_name[CLIENT_HOST_NAME_LEN]; + int go_speed; + int come_speed; + struct _t_clientinfo *next; + +} t_clientinfo; + + +/* @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:void + * @RETURN_VALUE:zero is success,others is error. + * @Note: after this function be called and you get some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int collect_client_info(); + + +/* @breif After the function collect_client_info() called,should call this function to + * clean up. + * @PARAMETER:void + * @RETURN_VALUE:void + * @Note: function collect_client_info() and this function just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +void clean_client_info(); + + +/* @breif find the element from the client_info list by mac. + * @PARAMETER:[const char *mac],the pointer point to by mac. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_mac(const char *mac); + + +/* @breif find the element from the client_info list by ip. + * @PARAMETER:[const char *ip],the pointer point to by ip. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_ip(const char *ip); + + +long get_online_time(const char *ip,const char *mac); + + +int clean_more_chain(); + + +char *get_client_auth_flag(); + +void set_client_auth_flag(); + + +#endif /* SRC_GET_CLIENTINFO_H_ */ + + + + diff --git a/src/get_devinfo.c b/src/get_devinfo.c new file mode 100644 index 00000000..d6358f75 --- /dev/null +++ b/src/get_devinfo.c @@ -0,0 +1,459 @@ +/* + * get_devinfo.c + * + * Created on: Jul 9, 2015 + * Author: GaomingPan + */ +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include + + +#include "util.h" +#include "debug.h" +#include "conf.h" +#include "client_list.h" +#include "../config.h" + + +#include "shell_command.h" +#include "get_devinfo.h" + +extern pthread_mutex_t client_list_mutex; + +static t_devinfo devinfo; +static t_cpuuse cpuuse; + +t_devinfo *get_devinfo(void) +{ + + if(get_apmac(devinfo.gw_mac)) + { + debug(LOG_ERR,"MyDEBUG:get get_apmac error!"); + } + + if(get_devssid(devinfo.gw_ssid)) + { + debug(LOG_ERR,"MyDEBUG:get ssid error!"); + } + if(get_dogversion(devinfo.dog_version)) + { + debug(LOG_ERR,"MyDEBUG: get_dogversion error!"); + } + if(get_wanip(devinfo.wan_ip)) + { + debug(LOG_ERR,"MyDEBUG: get_wanip error!\n"); + } + + devinfo.cur_conn = get_curconn(); + devinfo.dev_conn = get_devconn(); + + devinfo.cpu_use = get_cpuuse(CPU_LOAD); + + if(get_wanbps(&devinfo.go_speed,&devinfo.come_speed)) + { + debug(LOG_ERR,"MyDEBUG: get_speed error!"); + } + if(get_trafficCount(&devinfo.outgoing,&devinfo.incoming)) + { + debug(LOG_ERR,"MyDEBUG: get_traffic error!\n"); + } + + return &devinfo; +} + +/* @breif get wireless ssid,based on uci command. + * @PARAMETER: [char *ssid]:the char pointer for save the ssid. + * @RETURN_VALUE: zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_devssid(char *ssid) +{ + FILE *fp; + memset(ssid,0,DEV_SSID_NAME_LEN); + fp = popen(CMD_GET_WIRELESS_SSID,"r"); + if(NULL == fp) + { + debug(LOG_ERR," get_devssid error!"); + sprintf(ssid,"%s","null"); + return -1; + } + fread(ssid,DEV_SSID_NAME_LEN,1,fp); + pclose(fp); + + int i = DEV_SSID_NAME_LEN - 1; + for(;i > 0;i--) + { + if(0x0a == ssid[i]) + { + ssid[i] = 0; + break; + } + } + return 0; +} + + +/* @breif get wifidog version + * @PARAMETER:[char *dogversion]:the char pointer for save the version + * @RETURN_VALUE:always return zero + * GaomingPan lonely-test:no + * */ +int get_dogversion(char *dogversion) +{ + memset(dogversion,0,DEV_DOG_VERSION_LEN); + sprintf(dogversion,"%s",VERSION); + return 0; +} + +/* @breif get wan interface ip,based on uci command. + * @PARAMETER:[char *wanip]:the char pointer for save the wan ip + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_wanip(char *wanip) +{ + FILE *fp; + memset(wanip,0,DEV_WAN_IP_LEN); + fp = popen(CMD_GET_WAN_IP,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_wanip error!"); + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(wanip,DEV_WAN_IP_LEN - 1,1,fp); + pclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i > 0;i--) + { + if(0x0a == wanip[i]) + { + wanip[i] = 0; + break; + } + } + + return 0; +} + + + +/* @breif get ap mac address,based on uci command. + * @PARAMETER:[char *apmac]:the char pointer for save the mac + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_apmac(char *apmac) +{ + FILE *fp; + int i; + memset(apmac,0,DEV_MAC_ADDR_LEN); + fp = popen(CMD_GET_AP_MAC,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_apmac() popen error."); + sprintf(apmac,"%s","00-00-00-00-00-00"); + return -1; + } + fread(apmac,DEV_MAC_ADDR_LEN - 1,1,fp); + pclose(fp); + + for(i = 0; i< DEV_MAC_ADDR_LEN; i++) + { + if(':' == apmac[i]) + apmac[i] = '-'; + if(0x0a == apmac[i]) + apmac[i] = 0; + } + + return 0; +} + + +/* @breif get number of client + * @PARAMETER:none + * @RETURN_VALUE:the number of current connected client + * GaomingPan lonely-test:no + * */ +int get_curconn(void) +{ + int count; + t_client *first; + + LOCK_CLIENT_LIST(); + + first = client_get_first_client(); + if (first == NULL) { + count = 0; + } else { + count = 1; + while (first->next != NULL) { + first = first->next; + count++; + } + } + + UNLOCK_CLIENT_LIST(); + + return count; +} + + +/* @breif get number of client who connect to the device + * @PARAMETER:none + * @RETURN_VALUE:the number of connected client + * GaomingPan lonely-test:no + * */ +int get_devconn(void) +{ + FILE *fp; + char buf[10]; + memset(buf,0,10); + fp = popen("awk \'END{print NR}\' $(uci get dhcp.@dnsmasq[0].leasefile)","r"); + if(NULL == fp) + { + debug(LOG_ERR,"ERROR popen error, at get_devconn."); + return -1; + } + if(0 == fread(buf,1,10,fp)) + { + pclose(fp); + return 0; + } + pclose(fp); + return (atoi(buf)); +} + + +/* @breif get cpu use infomation,based on shell command. + * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @RETURN_VALUE:the number of current percent of CPU use. + * GaomingPan lonely-test:yes + * */ +int get_cpuuse(int type) +{ + char num[4]; + int use, + i; + FILE *fp; + + memset(num,0,4); + for(i = 0;i < 15;i++) + memset(cpuuse.use_info[i],0,8); + + fp = popen(CMD_GET_CPU_USE,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_cpuuse error!"); + return -1; + } + fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], + cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], + cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], + cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], + cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] + ); + pclose(fp); + +// for(;i<15;i++) +// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); + + switch(type){ + case CPU_USER: + cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; + use = atoi(cpuuse.use_info[CPU_USER]); + break; + case CPU_SYS: + cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SYS]); + break; + case CPU_NIC: + cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; + use = atoi(cpuuse.use_info[CPU_NIC]); + break; + case CPU_IDLE: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_LOAD: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_IO: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IO]); + break; + case CPU_IRQ: + cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IRQ]); + break; + case CPU_SIRQ: + cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SIRQ]); + break; + default: + use = -1; + break; + } + + return use; +} + + +/* @breif get wan interface traffic,based on shell command. + * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_trafficCount(long *outgo,long *income) +{ + FILE *fp; + char ifname[DEV_IFNAME_LEN]; + memset(ifname,0,DEV_IFNAME_LEN); + + fp = popen(CMD_GET_WAN_IFNAME,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_trafficCount() popen error."); + *outgo = -1L; + *income = -1L; + return -1; + } + fread(ifname,DEV_IFNAME_LEN-1,1,fp); + pclose(fp); + + int j; + for(j = 0;j < DEV_IFNAME_LEN;j++) + { + if(0x0a == ifname[j]) + { + ifname[j] = 0; + break; + } + } + + int nDevLen = strlen(ifname); + if (nDevLen < 1 || nDevLen > DEV_IFNAME_LEN - 1) + { + debug(LOG_ERR,"get_trafficCount(),dev length too long."); + *outgo = -1L; + *income = -1L; + return -2; + } + int fd = open("/proc/net/dev", O_RDONLY | O_EXCL); + if (-1 == fd) + { + debug(LOG_ERR,"get_trafficCount(),open /proc/net/dev failed ,maybe file not exists!"); + *outgo = -1L; + *income = -1L; + return -3; + } + + char buf[1024*2]; + lseek(fd, 0L, SEEK_SET); + int nBytes = read(fd, buf, sizeof(buf)-1); + close(fd); + if (-1 == nBytes) + { + debug(LOG_ERR,"get_trafficCount(),read bytes error."); + *outgo = -1L; + *income = -1L; + return -4; + } + buf[nBytes] = '\0'; + + //è¿”å›ç¬¬ä¸€æ¬¡æŒ‡å‘ifnameä½ç½®ç„指针 + char* pDev = strstr(buf, ifname); + if (NULL == pDev) + { + debug(LOG_ERR,"get_trafficCount(),don't find dev %s", ifname); + *outgo = -1L; + *income = -1L; + return -5; + } + char *p; + char *ifconfig_value; + int i = 0; + long rx2_tx10[2]; + /*å»é™¤ç©ºæ ¼ï¼Œåˆ¶è¡¨ç¬¦ï¼Œæ¢è¡Œç¬¦ç­‰ä¸éœ€è¦ç„字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + ifconfig_value = (char*)malloc(30); + if(NULL == ifconfig_value) + { + debug(LOG_ERR,"get_trafficCount(),malloc error."); + *outgo = -1L; + *income = -1L; + return -6; + } + strcpy(ifconfig_value, p); + /*得到ç„字符串中ç„ç¬¬äºŒä¸ªå­—æ®µæ˜¯æ¥æ”¶æµé‡*/ + if(i == 2) + { + rx2_tx10[0] = atoll(ifconfig_value); + } + /*得到ç„字符串中ç„第å个字段是å‘逿µé‡*/ + if(i == 10) + { + rx2_tx10[1] = atoll(ifconfig_value); + break; + } + free(ifconfig_value); + } + free(ifconfig_value); + + *income = rx2_tx10[0]; + *outgo = rx2_tx10[1]; + + return 0; +} + + +/* @breif get wan interface speed,based on shell command. + * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. + * @RETURN_VALUE:zero is success,others is error. + * @NOTE: this function will take a one second to wait data update,so,it's just waste time. + * GaomingPan lonely-test:yes + * */ +int get_wanbps(int *go,int *come) +{ + unsigned long long outgo = 0, + income = 0; + unsigned long long outgo1 = 0, + income1 = 0; + int ret = 0; + + ret = get_trafficCount(&outgo,&income); + + if(ret) + { + debug(LOG_ERR,"1 at get_wanbps(), get_trafficCount() error return code = %d",ret); + return -1; + } + + sleep(1); + + ret = get_trafficCount(&outgo1,&income1); + if(ret) + { + debug(LOG_ERR,"2 at get_wanbps(), get_trafficCount() error return code = %d",ret); + return -2; + } + + *go = (int)(outgo1 - outgo); + *come = (int)(income1 - income); + + return 0; +} diff --git a/src/get_devinfo.h b/src/get_devinfo.h new file mode 100644 index 00000000..1af715e3 --- /dev/null +++ b/src/get_devinfo.h @@ -0,0 +1,119 @@ +/* + * get_devinfo.h + * + * Created on: Jul 9, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_GET_DEVINFO_H_ +#define SRC_GET_DEVINFO_H_ + +#define DEV_MAC_ADDR_LEN 18 +#define DEV_SSID_NAME_LEN 20 +#define DEV_DOG_VERSION_LEN 20 +#define DEV_WAN_IP_LEN 16 +#define DEV_IFNAME_LEN 11 + + +#define CPU_USER 1 +#define CPU_SYS 3 +#define CPU_NIC 5 +#define CPU_IDLE 7 +#define CPU_IO 9 +#define CPU_IRQ 11 +#define CPU_SIRQ 13 +#define CPU_LOAD 16 + +/*@ breif a struct hold information for ap*/ +typedef struct _t_devinfo{ + char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address + char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid + char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. + char wan_ip[DEV_WAN_IP_LEN]; // ap wan interface ip + int cur_conn; // number of current connection client + int dev_conn; // number of connection in the device,maybe some has no authentication. + int cpu_use; // percent of use CPU + int go_speed; // wan interface go out speed + int come_speed; // wan interface come in speed + long incoming; // + long outgoing; // +}t_devinfo; + + + +typedef struct _t_cpuuse{ + char use_info[15][8]; +}t_cpuuse; + + +t_devinfo *get_devinfo(void); + +/* @breif get wireless ssid,based on uci command. + * @PARAMETER: [char *ssid]:the char pointer for save the ssid. + * @RETURN_VALUE: zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_devssid(char *ssid); + +/* @breif get wifidog version + * @PARAMETER:[char *dogversion]:the char pointer for save the version + * @RETURN_VALUE:always return zero + * GaomingPan lonely-test:no + * */ +int get_dogversion(char *dogversion); + + +/* @breif get wan interface ip,based on uci command. + * @PARAMETER:[char *wanip]:the char pointer for save the wan ip + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_wanip(char *wanip); + +/* @breif get ap mac address,based on uci command. + * @PARAMETER:[char *apmac]:the char pointer for save the mac + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_apmac(char *apmac); + +/* @breif get number of client + * @PARAMETER:none + * @RETURN_VALUE:the number of current connected client + * GaomingPan lonely-test:no + * */ +int get_curconn(void); + + +/* @breif get number of client who connect to the device + * @PARAMETER:none + * @RETURN_VALUE:the number of connected client + * GaomingPan lonely-test:no + * */ +int get_devconn(void); + +/* @breif get cpu use infomation,based on shell command + * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @RETURN_VALUE:the number of current percent of CPU use. + * GaomingPan lonely-test:yes + * */ +int get_cpuuse(int type); + + +/* @breif get wan interface speed,based on shell command. + * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_wanbps(int *go,int *come); + + +/* @breif get wan interface traffic,based on shell command. + * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_trafficCount(long *outgo,long *income); + + +#endif /* SRC_GET_DEVINFO_H_ */ diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c new file mode 100644 index 00000000..ea79b27d --- /dev/null +++ b/src/get_remote_shell.c @@ -0,0 +1,212 @@ +/* + * get_remote_shell.c + * + * Created on: Jul 14, 2015 + * Author: GaomingPan + */ + + +#include +#include +#include +#include + +#include "debug.h" + +#include "get_remote_shell.h" + + + +static char remote_shell_cmd[ REMOTE_SHELL_COMMAND_LEN ]; + +static char info_http_url[128], + info_rmflag[20], + normal_http_url[128], + normal_rmflag[20]; + + +int init_post_http_url_config(void) +{ + memset(info_http_url,0,128); + memset(info_rmflag,0,20); + memset(normal_http_url,0,128); + memset(normal_rmflag,0,20); + + char buf[128]; + FILE *fp; + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.info_url","r"); + if(NULL == fp) + { + return -1; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(info_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.normal_url","r"); + if(NULL == fp) + { + return -2; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(normal_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.info_rmflag","r"); + if(NULL == fp) + { + return -3; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(info_rmflag,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.normal_rmflag","r"); + if(NULL == fp) + { + return -4; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(normal_rmflag,"%s",buf); + + printf("\ninit result:\n\t%s\n\t%s\n\t%s\n\t%\n\n", \ + info_http_url,info_rmflag, \ + normal_http_url,normal_rmflag + ); + + return 0; +} + + + + +int post_get_info_execut_output(char *cmd_output_path) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); + printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); + fp = popen(output,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); + printf("ERROR: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); + return -1; + } + pclose(fp); + return 0; +} + + + +int post_normal_execut_output(char *gw_id, char *cmd_id) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + + sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ + gw_id,cmd_id,BUILE_NORMAL_CMD_RESULT_SHELL,normal_http_url,normal_rmflag); + debug(LOG_INFO,"output_normal:--> %s",output); + fp = popen(output,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); + printf("ERROR: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); + return -1; + } + pclose(fp); + return 0; +} + + + + + + +char *get_shell_command(char *cmdptr) +{ + + if(NULL == cmdptr) + { + printf("REMOTE shell: remote shell command is null.\n"); + return NULL; + } + memset(remote_shell_cmd,0,REMOTE_SHELL_COMMAND_LEN); + sprintf(remote_shell_cmd,"%s",cmdptr); + + return remote_shell_cmd; +} + + + + +int excute_shell_command(char *gw_id,char *shellcmd) +{ + char cmd_id[20], + get_info_cmd[30], + normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; + char *pos_id, + *pos_cmd; + int is_get_info = 0; + FILE *fp; + char cmdresult[1024]; + + memset(cmdresult,0,1024); + memset(cmd_id,0,20); + memset(get_info_cmd,0,30); + + pos_id = shellcmd; + pos_cmd = strstr(shellcmd,"|"); + + snprintf(cmd_id,++pos_cmd - pos_id - 1,"%s",++pos_id); + + pos_cmd = ++pos_cmd; + + snprintf(get_info_cmd,30,"%s",pos_cmd); + + is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); + + printf("\ncmd_id:%s\nget_inf_cmd:%s\nis_get_info:%d\n\n",cmd_id,get_info_cmd,is_get_info); + + if(0 == is_get_info) + { + sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id); + fp = popen(get_info_cmd,"r"); + } + else + { + sprintf(normal_cmd,"echo \"\" > "NORMAL_CMD_RESULT_FILE"RESULT=\"$(%s)\";echo \"$RESULT\" >> "NORMAL_CMD_RESULT_FILE,pos_cmd); + fp = popen(normal_cmd,"r"); + } + + printf("\npos_cmd:\n\t%s\n\n",pos_cmd); + + if(NULL == fp) + { + printf("excute_shell_command popen error....\n"); + return -1; + } + //fread(cmdresult,1024,1,fp); + pclose(fp); + //printf("\n\ncmd result:\n %s\n\n",cmdresult); + + if(0 == is_get_info) + { + post_get_info_execut_output(SETTINGS_INFO_FILE); + + }else{ + + post_normal_execut_output(gw_id,cmd_id); + } + return 0; +} + + diff --git a/src/get_remote_shell.h b/src/get_remote_shell.h new file mode 100644 index 00000000..7c2f4dc9 --- /dev/null +++ b/src/get_remote_shell.h @@ -0,0 +1,35 @@ +/* + * get_remote_shell.h + * + * Created on: Jul 14, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_GET_REMOTE_SHELL_H_ +#define SRC_GET_REMOTE_SHELL_H_ + +#define GET_SETTINGS_INFO_CMD "GET_settings" + +#define SETTINGS_INFO_FILE "/tmp/routersettings" + +#define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" + +#define BUILE_NORMAL_CMD_RESULT_SHELL "result=\"\";while read line;do result=\"\\\"$result$line\\\",\";done < "NORMAL_CMD_RESULT_FILE";result=${result%,};echo $result" + + +#define REMOTE_SHELL_COMMAND_LEN 1024 +#define MAX_CMD_EXECUT_OUT_LEN 4096 + +char *get_shell_command(char *cmdptr); + +int excute_shell_command(char *gw_id,char *shellcmd); + +int post_get_info_execut_output(char *cmd_output_path); + +int post_normal_execut_output(char *gw_id, char *cmd_id); + +int init_post_http_url_config(void); + +#endif /* SRC_GET_REMOTE_SHELL_H_ */ + + diff --git a/src/http.c b/src/http.c new file mode 100755 index 00000000..21214c15 --- /dev/null +++ b/src/http.c @@ -0,0 +1,331 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @file http.c + @brief HTTP IO functions + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2007 Benoit GrĂ©goire + @author Copyright (C) 2007 David Bird + + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" + +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "auth.h" +#include "firewall.h" +#include "http.h" +#include "httpd.h" +#include "client_list.h" +#include "common.h" +#include "centralserver.h" + +#include "util.h" + +#include "../config.h" + +extern pthread_mutex_t client_list_mutex; + +/** The 404 handler is also responsible for redirecting to the auth server */ +void +http_callback_404(httpd *webserver, request *r) +{ + char tmp_url[MAX_BUF], + *url, + *mac; + s_config *config = config_get_config(); + t_auth_serv *auth_server = get_auth_server(); + + memset(tmp_url, 0, sizeof(tmp_url)); + /* + * XXX Note the code below assumes that the client's request is a plain + * http request to a standard port. At any rate, this handler is called only + * if the internet/auth server is down so it's not a huge loss, but still. + */ + snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s", + r->request.host, + r->request.path, + r->request.query[0] ? "?" : "", + r->request.query); + url = httpdUrlEncode(tmp_url); + + if (!is_online()) { + /* The internet connection is down at the moment - apologize and do not redirect anywhere */ + char * buf; + safe_asprintf(&buf, + "

We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.

" + "

If at all possible, please notify the owners of this hotspot that the internet connection is out of service.

" + "

The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.

" + "

In a while please click here to try your request again.

", tmp_url); + + send_http_page(r, "Uh oh! Internet access unavailable!", buf); + free(buf); + debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr); + } + else if (!is_auth_online()) { + /* The auth server is down at the moment - apologize and do not redirect anywhere */ + char * buf; + safe_asprintf(&buf, + "

We apologize, but it seems that we are currently unable to re-direct you to the login screen.

" + "

The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.

" + "

In a couple of minutes please click here to try your request again.

", tmp_url); + + send_http_page(r, "Uh oh! Login screen unavailable!", buf); + free(buf); + debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr); + } + else { + /* Re-direct them to auth server */ + char *urlFragment; + + if (!(mac = arp_get(r->clientAddr))) { + /* We could not get their MAC address */ + debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request", r->clientAddr); + safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s", + auth_server->authserv_login_script_path_fragment, + config->gw_address, + config->gw_port, + config->gw_id, + url); + } else { + debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac); + safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s", + auth_server->authserv_login_script_path_fragment, + config->gw_address, + config->gw_port, + config->gw_id, + mac, + url); + } + + debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url); + http_send_redirect_to_auth(r, urlFragment, "Redirect to login page"); + free(urlFragment); + } + free(url); +} + +void +http_callback_wifidog(httpd *webserver, request *r) +{ + send_http_page(r, "WiFiDog", "Please use the menu to navigate the features of this WiFiDog installation."); +} + +void +http_callback_about(httpd *webserver, request *r) +{ + send_http_page(r, "About WiFiDog", "This is WiFiDog version " VERSION ""); +} + +void +http_callback_status(httpd *webserver, request *r) +{ + const s_config *config = config_get_config(); + char * status = NULL; + char *buf; + + if (config->httpdusername && + (strcmp(config->httpdusername, r->request.authUser) || + strcmp(config->httpdpassword, r->request.authPassword))) { + debug(LOG_INFO, "Status page requested, forcing authentication"); + httpdForceAuthenticate(r, config->httpdrealm); + return; + } + + status = get_status_text(); + safe_asprintf(&buf, "
%s
", status); + send_http_page(r, "WiFiDog Status", buf); + free(buf); + free(status); +} +/** @brief Convenience function to redirect the web browser to the auth server + * @param r The request + * @param urlFragment The end of the auth server URL to redirect to (the part after path) + * @param text The text to include in the redirect header ant the mnual redirect title */ +void http_send_redirect_to_auth(request *r, const char *urlFragment, const char *text) +{ + char *protocol = NULL; + int port = 80; + t_auth_serv *auth_server = get_auth_server(); + + if (auth_server->authserv_use_ssl) { + protocol = "https"; + port = auth_server->authserv_ssl_port; + } else { + protocol = "http"; + port = auth_server->authserv_http_port; + } + + char *url = NULL; + safe_asprintf(&url, "%s://%s:%d%s%s", + protocol, + auth_server->authserv_hostname, + port, + auth_server->authserv_path, + urlFragment + ); + http_send_redirect(r, url, text); + free(url); +} + +/** @brief Sends a redirect to the web browser + * @param r The request + * @param url The url to redirect to + * @param text The text to include in the redirect header and the manual redirect link title. NULL is acceptable */ +void http_send_redirect(request *r, const char *url, const char *text) +{ + char *message = NULL; + char *header = NULL; + char *response = NULL; + /* Re-direct them to auth server */ + debug(LOG_DEBUG, "Redirecting client browser to %s", url); + safe_asprintf(&header, "Location: %s", url); + safe_asprintf(&response, "302 %s\n", text ? text : "Redirecting"); + httpdSetResponse(r, response); + httpdAddHeader(r, header); + free(response); + free(header); + safe_asprintf(&message, "Please click here.", url); + send_http_page(r, text ? text : "Redirection to message", message); + free(message); +} + +void +http_callback_auth(httpd *webserver, request *r) +{ + t_client *client; + httpVar * token; + char *mac; + httpVar *logout = httpdGetVariableByName(r, "logout"); + if ((token = httpdGetVariableByName(r, "token"))) { + /* They supplied variable "token" */ + if (!(mac = arp_get(r->clientAddr))) { + /* We could not get their MAC address */ + debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr); + send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address"); + } else { + /* We have their MAC address */ + + LOCK_CLIENT_LIST(); + + if ((client = client_list_find(r->clientAddr, mac)) == NULL) { + debug(LOG_DEBUG, "New client for %s", r->clientAddr); + client_list_append(r->clientAddr, mac, token->value); + } else if (logout) { + t_authresponse authresponse; + s_config *config = config_get_config(); + unsigned long long incoming = client->counters.incoming; + unsigned long long outgoing = client->counters.outgoing; + char *ip = safe_strdup(client->ip); + char *urlFragment = NULL; + t_auth_serv *auth_server = get_auth_server(); + + fw_deny(client->ip, client->mac, client->fw_connection_state); + client_list_delete(client); + debug(LOG_DEBUG, "Got logout from %s", client->ip); + + /* Advertise the logout if we have an auth server */ + if (config->auth_servers != NULL) { + UNLOCK_CLIENT_LIST(); + auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token->value, + incoming, outgoing); + LOCK_CLIENT_LIST(); + + /* Re-direct them to auth server */ + debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s" + "- redirecting them to logout message", client->ip, client->mac, client->token); + safe_asprintf(&urlFragment, "%smessage=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to logout message"); + free(urlFragment); + } + free(ip); + } + else { + debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip); + } + UNLOCK_CLIENT_LIST(); + if (!logout) { + authenticate_client(r); + } + free(mac); + } + } else { + /* They did not supply variable "token" */ + send_http_page(r, "WiFiDog error", "Invalid token"); + } +} + +void send_http_page(request *r, const char *title, const char* message) +{ + s_config *config = config_get_config(); + char *buffer; + struct stat stat_info; + int fd; + ssize_t written; + + fd=open(config->htmlmsgfile, O_RDONLY); + if (fd==-1) { + debug(LOG_CRIT, "Failed to open HTML message file %s: %s", config->htmlmsgfile, strerror(errno)); + return; + } + + if (fstat(fd, &stat_info)==-1) { + debug(LOG_CRIT, "Failed to stat HTML message file: %s", strerror(errno)); + close(fd); + return; + } + + buffer=(char*)safe_malloc(stat_info.st_size+1); + written=read(fd, buffer, stat_info.st_size); + if (written==-1) { + debug(LOG_CRIT, "Failed to read HTML message file: %s", strerror(errno)); + free(buffer); + close(fd); + return; + } + close(fd); + + buffer[written]=0; + httpdAddVariable(r, "title", title); + httpdAddVariable(r, "message", message); + httpdAddVariable(r, "nodeID", config->gw_id); + httpdOutput(r, buffer); + free(buffer); +} + diff --git a/src/http.h b/src/http.h new file mode 100755 index 00000000..54ca8777 --- /dev/null +++ b/src/http.h @@ -0,0 +1,50 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file http.h + @brief HTTP IO functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _HTTP_H_ +#define _HTTP_H_ + +#include "httpd.h" + +/**@brief Callback for libhttpd, main entry point for captive portal */ +void http_callback_404(httpd *webserver, request *r); +/**@brief Callback for libhttpd */ +void http_callback_wifidog(httpd *webserver, request *r); +/**@brief Callback for libhttpd */ +void http_callback_about(httpd *webserver, request *r); +/**@brief Callback for libhttpd */ +void http_callback_status(httpd *webserver, request *r); +/**@brief Callback for libhttpd, main entry point post login for auth confirmation */ +void http_callback_auth(httpd *webserver, request *r); + +/** @brief Sends a HTML page to web browser */ +void send_http_page(request *r, const char *title, const char* message); + +/** @brief Sends a redirect to the web browser */ +void http_send_redirect(request *r, const char *url, const char *text); +/** @brief Convenience function to redirect the web browser to the authe server */ +void http_send_redirect_to_auth(request *r, const char *urlFragment, const char *text); +#endif /* _HTTP_H_ */ diff --git a/src/httpd_thread.c b/src/httpd_thread.c new file mode 100755 index 00000000..d9a933f4 --- /dev/null +++ b/src/httpd_thread.c @@ -0,0 +1,75 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ + +/** @file httpd_thread.c + @brief Handles on web request. + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" + +#include "../config.h" +#include "common.h" +#include "debug.h" +#include "httpd_thread.h" + +/** Main request handling thread. +@param args Two item array of void-cast pointers to the httpd and request struct +*/ +void +thread_httpd(void *args) +{ + void **params; + httpd *webserver; + request *r; + + params = (void **)args; + webserver = *params; + r = *(params + 1); + free(params); /* XXX We must release this ourselves. */ + + if (httpdReadRequest(webserver, r) == 0) { + /* + * We read the request fine + */ + debug(LOG_DEBUG, "Processing request from %s", r->clientAddr); + debug(LOG_DEBUG, "Calling httpdProcessRequest() for %s", r->clientAddr); + httpdProcessRequest(webserver, r); + debug(LOG_DEBUG, "Returned from httpdProcessRequest() for %s", r->clientAddr); + } + else { + debug(LOG_DEBUG, "No valid request received from %s", r->clientAddr); + } + debug(LOG_DEBUG, "Closing connection with %s", r->clientAddr); + httpdEndRequest(r); +} diff --git a/src/httpd_thread.h b/src/httpd_thread.h new file mode 100755 index 00000000..a4f125df --- /dev/null +++ b/src/httpd_thread.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file httpd_thread.h + @brief WiFiDog httpd worker thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _HTTPD_THREAD_H_ +#define _HTTPD_THREAD_H_ + +/** @brief Handle a web request */ +void thread_httpd(void *args); + +#endif diff --git a/src/ping_thread.c b/src/ping_thread.c new file mode 100755 index 00000000..36616190 --- /dev/null +++ b/src/ping_thread.c @@ -0,0 +1,284 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file ping_thread.c + @brief Periodically checks in with the central auth server so the auth + server knows the gateway is still up. Note that this is NOT how the gateway + detects that the central server is still up. + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../config.h" +#include "safe.h" +#include "common.h" +#include "conf.h" +#include "debug.h" +#include "ping_thread.h" +#include "util.h" +#include "centralserver.h" + +/*@breif get device info. + * GaomingPan*/ +#include "get_devinfo.h" + +#include "get_remote_shell.h" + +static void ping(void); + +extern time_t started_time; + +/** Launches a thread that periodically checks in with the wifidog auth server to perform heartbeat function. +@param arg NULL +@todo This thread loops infinitely, need a watchdog to verify that it is still running? +*/ +void +thread_ping(void *arg) +{ + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + + while (1) { + /* Make sure we check the servers at the very begining */ + debug(LOG_DEBUG, "Running ping()"); + ping(); + + /* Sleep for config.checkinterval seconds... */ + timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; + timeout.tv_nsec = 0; + + /* Mutex must be locked for pthread_cond_timedwait... */ + pthread_mutex_lock(&cond_mutex); + + /* Thread safe "sleep" */ + pthread_cond_timedwait(&cond, &cond_mutex, &timeout); + + /* No longer needs to be locked */ + pthread_mutex_unlock(&cond_mutex); + } +} + +/** @internal + * This function does the actual request. + */ +static void +ping(void) +{ + /*@breif device info struct + * GaomingPan + * */ + t_devinfo *infoptr; + char *cmdptr; + + ssize_t numbytes; + size_t totalbytes; + int sockfd, nfds, done; + char request[MAX_BUF]; + fd_set readfds; + struct timeval timeout; + FILE * fh; + unsigned long int sys_uptime = 0; + unsigned int sys_memfree = 0; + float sys_load = 0; + t_auth_serv *auth_server = NULL; + auth_server = get_auth_server(); + + debug(LOG_DEBUG, "Entering ping()"); + + /* + * The ping thread does not really try to see if the auth server is actually + * working. Merely that there is a web server listening at the port. And that + * is done by connect_auth_server() internally. + */ + sockfd = connect_auth_server(); + if (sockfd == -1) { + /* + * No auth servers for me to talk to + */ + return; + } + + /* + * Populate uptime, memfree and load + */ + if ((fh = fopen("/proc/uptime", "r"))) { + if(fscanf(fh, "%lu", &sys_uptime) != 1) + debug(LOG_CRIT, "Failed to read uptime"); + + fclose(fh); + } + if ((fh = fopen("/proc/meminfo", "r"))) { + while (!feof(fh)) { + if (fscanf(fh, "MemFree: %u", &sys_memfree) == 0) { + /* Not on this line */ + while (!feof(fh) && fgetc(fh) != '\n'); + } + else { + /* Found it */ + break; + } + } + fclose(fh); + } + if ((fh = fopen("/proc/loadavg", "r"))) { + if(fscanf(fh, "%f", &sys_load) != 1) + debug(LOG_CRIT, "Failed to read loadavg"); + + fclose(fh); + } + + /* get device info ptr */ + /* GaomingPan */ + infoptr = get_devinfo(); + + /* + * Prep & send request + */ + snprintf(request, sizeof(request) - 1, + "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%d&come_speed=%d&incoming=%ld&outgoing=%ld HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_ping_script_path_fragment, + config_get_config()->gw_id, + sys_uptime, + sys_memfree, + sys_load, + (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time), + + /* new parameter */ + infoptr->gw_mac, + infoptr->gw_ssid, + infoptr->cur_conn, + infoptr->dev_conn, + infoptr->cpu_use, + infoptr->dog_version, + infoptr->wan_ip, + infoptr->go_speed, + infoptr->come_speed, + infoptr->incoming, + infoptr->outgoing, + + /* ************ */ + VERSION, + auth_server->authserv_hostname); + + debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); + + send(sockfd, request, strlen(request), 0); + + debug(LOG_DEBUG, "Reading response"); + + numbytes = totalbytes = 0; + done = 0; + do { + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + timeout.tv_sec = 30; /* XXX magic... 30 second */ + timeout.tv_usec = 0; + nfds = sockfd + 1; + + nfds = select(nfds, &readfds, NULL, NULL, &timeout); + + if (nfds > 0) { + /** We don't have to use FD_ISSET() because there + * was only one fd. */ + numbytes = read(sockfd, request + totalbytes, MAX_BUF - (totalbytes + 1)); + if (numbytes < 0) { + debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return; + } + else if (numbytes == 0) { + done = 1; + } + else { + totalbytes += numbytes; + debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes); + } + } + else if (nfds == 0) { + debug(LOG_ERR, "Timed out reading data via select() from auth server"); + /* FIXME */ + close(sockfd); + return; + } + else if (nfds < 0) { + debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return; + } + } while (!done); + close(sockfd); + + debug(LOG_DEBUG, "Done reading reply, total %d bytes", totalbytes); + + request[totalbytes] = '\0'; + + debug(LOG_DEBUG, "HTTP Response from Server: [%s]", request); + + if (strstr(request, "Pong") == 0) { + debug(LOG_WARNING, "Auth server did NOT say pong!"); + /* FIXME */ + } + else { + debug(LOG_DEBUG, "Auth Server Says: Pong"); + + /****************/ + cmdptr = strstr(request,"|"); + if(NULL == cmdptr) + { + printf("NO remote cmd.\n"); + } + else + { + cmdptr = get_shell_command(++cmdptr); + if(cmdptr) + { + excute_shell_command(config_get_config()->gw_id,cmdptr); + } + } + + /****************/ + } + + return; +} diff --git a/src/ping_thread.h b/src/ping_thread.h new file mode 100755 index 00000000..6b7a47bb --- /dev/null +++ b/src/ping_thread.h @@ -0,0 +1,35 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file ping_thread.h + @brief WiFiDog heartbeat thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _PING_THREAD_H_ +#define _PING_THREAD_H_ + +#define MINIMUM_STARTED_TIME 1041379200 /* 2003-01-01 */ + +/** @brief Periodically checks on the auth server to see if it's alive. */ +void thread_ping(void *arg); + +#endif diff --git a/src/safe.c b/src/safe.c new file mode 100755 index 00000000..e7bad78a --- /dev/null +++ b/src/safe.c @@ -0,0 +1,110 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** + @file safe.c + @brief Safe versions of stdlib/string functions that error out and exit if memory allocation fails + @author Copyright (C) 2005 Mina Naguib + */ + + +#include +#include +#include +#include +#include + +#include "httpd.h" +#include "safe.h" +#include "debug.h" +#include + +/* From gateway.c */ +extern httpd * webserver; + +void * safe_malloc (size_t size) { + void * retval = NULL; + retval = malloc(size); + if (!retval) { + debug(LOG_CRIT, "Failed to malloc %d bytes of memory: %s. Bailing out", size, strerror(errno)); + exit(1); + } + return (retval); +} + +char * safe_strdup(const char *s) { + char * retval = NULL; + if (!s) { + debug(LOG_CRIT, "safe_strdup called with NULL which would have crashed strdup. Bailing out"); + exit(1); + } + retval = strdup(s); + if (!retval) { + debug(LOG_CRIT, "Failed to duplicate a string: %s. Bailing out", strerror(errno)); + exit(1); + } + return (retval); +} + +int safe_asprintf(char **strp, const char *fmt, ...) { + va_list ap; + int retval; + + va_start(ap, fmt); + retval = safe_vasprintf(strp, fmt, ap); + va_end(ap); + + return (retval); +} + +int safe_vasprintf(char **strp, const char *fmt, va_list ap) { + int retval; + + retval = vasprintf(strp, fmt, ap); + + if (retval == -1) { + debug(LOG_CRIT, "Failed to vasprintf: %s. Bailing out", strerror(errno)); + exit (1); + } + return (retval); +} + +pid_t safe_fork(void) { + pid_t result; + result = fork(); + + if (result == -1) { + debug(LOG_CRIT, "Failed to fork: %s. Bailing out", strerror(errno)); + exit (1); + } + else if (result == 0) { + /* I'm the child - do some cleanup */ + if (webserver) { + close(webserver->serverSock); + webserver = NULL; + } + } + + return result; +} + diff --git a/src/safe.h b/src/safe.h new file mode 100755 index 00000000..900320c2 --- /dev/null +++ b/src/safe.h @@ -0,0 +1,56 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file safe.h + @brief Safe versions of stdlib/string functions that error out and exit if memory allocation fails + @author Copyright (C) 2005 Mina Naguib +*/ + +#ifndef _SAFE_H_ +#define _SAFE_H_ + +#include /* For va_list */ +#include /* For fork */ +#include /* For fork */ + +/** @brief Safe version of malloc + */ +void * safe_malloc (size_t size); + +/* @brief Safe version of strdup + */ +char * safe_strdup(const char *s); + +/* @brief Safe version of asprintf + */ +int safe_asprintf(char **strp, const char *fmt, ...); + +/* @brief Safe version of vasprintf + */ +int safe_vasprintf(char **strp, const char *fmt, va_list ap); + +/* @brief Safe version of fork + */ + +pid_t safe_fork(void); + +#endif /* _SAFE_H_ */ + diff --git a/src/shell_command.h b/src/shell_command.h new file mode 100644 index 00000000..17b1ec25 --- /dev/null +++ b/src/shell_command.h @@ -0,0 +1,53 @@ +/* + * shell_command.h + * + * Created on: Jul 9, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_SHELL_COMMAND_H_ +#define SRC_SHELL_COMMAND_H_ + +/* @breif get ap wireless ssid shell, depends on uci command. + * */ +#define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" +#define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" +#define CMD_GET_CPU_USE "top -n 1 | grep id" +#define CMD_GET_AP_MAC "uci get network.lan.macaddr" +#define CMD_GET_WAN_IFNAME "uci get network.wan.ifname" + +//#define CMD_GET_CLIENT_LIST "cat /var/dhcp.leases | awk \'{print $2,$3,$4}\'" +#define CMD_GET_CLIENT_LIST "cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk \'{print $2,$3,$4}\'" + +#define CMD_MAKE_SPEED_FILE "UP_SPEED=\"/tmp/client.up.speed\"\n" \ + "DOWN_SPEED=\"/tmp/client.down.speed\"\n" \ + "MAC_IP=\"/tmp/mac-ip.client\"\n" \ + "LAN_IPS=`uci get network.lan.ipaddr | awk -F '.' '{print $1}'` \n" \ + "cat /proc/net/arp | grep : | grep ^$LAN_IPS | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP \n" \ + "iptables -N UPLOAD \n" \ + "iptables -N DOWNLOAD \n" \ + "while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP \n" \ + "while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP \n" \ + "sleep 1 \n" \ + "iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED \n" \ + "iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED \n" \ + "while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP \n" \ + "while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP \n" \ + "iptables -X UPLOAD \n" \ + "iptables -X DOWNLOAD \n" + + +#define CMD_GET_CHAIN_NUM "TARGET=/tmp/client.up.speed\n" \ + "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET " \ + "> /tmp/client.speed.chain.num" + + +#define CMD_CLEAN_SPEED_CHAIN "MAC_IP=\"/tmp/mac-ip.client\"\n" \ + "while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP \n" \ + "while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP \n" \ + "iptables -X UPLOAD \n " \ + "iptables -X DOWNLOAD " + + + +#endif /* SRC_SHELL_COMMAND_H_ */ diff --git a/src/util.c b/src/util.c new file mode 100755 index 00000000..d5ede623 --- /dev/null +++ b/src/util.c @@ -0,0 +1,544 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** + @file util.c + @brief Misc utility functions + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2006 Benoit Grégoire + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include + +#if defined(__NetBSD__) +#include +#include +#include +#include +#include +#endif + +#ifdef __linux__ +#include +#include +#endif + +#include +#include +#include + +#include "common.h" +#include "client_list.h" +#include "safe.h" +#include "util.h" +#include "conf.h" +#include "debug.h" + +#include "../config.h" + +static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Defined in ping_thread.c */ +extern time_t started_time; + +/* Defined in clientlist.c */ +extern pthread_mutex_t client_list_mutex; +extern pthread_mutex_t config_mutex; + +/* Defined in commandline.c */ +extern pid_t restart_orig_pid; + +/* XXX Do these need to be locked ? */ +static time_t last_online_time = 0; +static time_t last_offline_time = 0; +static time_t last_auth_online_time = 0; +static time_t last_auth_offline_time = 0; + +long served_this_session = 0; + + +/** Fork a child and execute a shell command, the parent + * process waits for the child to return and returns the child's exit() + * value. + * @return Return code of the command + */ +int +execute(const char *cmd_line, int quiet) +{ + int pid, + status, + rc; + + const char *new_argv[4]; + new_argv[0] = "/bin/sh"; + new_argv[1] = "-c"; + new_argv[2] = cmd_line; + new_argv[3] = NULL; + + pid = safe_fork(); + if (pid == 0) { /* for the child process: */ + /* We don't want to see any errors if quiet flag is on */ + if (quiet) close(2); + if (execvp("/bin/sh", (char *const *)new_argv) == -1) { /* execute the command */ + debug(LOG_ERR, "execvp(): %s", strerror(errno)); + } else { + debug(LOG_ERR, "execvp() failed"); + } + exit(1); + } + + /* for the parent: */ + debug(LOG_DEBUG, "Waiting for PID %d to exit", pid); + rc = waitpid(pid, &status, 0); + debug(LOG_DEBUG, "Process PID %d exited", rc); + + return (WEXITSTATUS(status)); +} + + struct in_addr * +wd_gethostbyname(const char *name) +{ + struct hostent *he; + struct in_addr *h_addr, *in_addr_temp; + + /* XXX Calling function is reponsible for free() */ + + h_addr = safe_malloc(sizeof(struct in_addr)); + + LOCK_GHBN(); + + he = gethostbyname(name); + + if (he == NULL) { + free(h_addr); + UNLOCK_GHBN(); + return NULL; + } + + mark_online(); + + in_addr_temp = (struct in_addr *)he->h_addr_list[0]; + h_addr->s_addr = in_addr_temp->s_addr; + + UNLOCK_GHBN(); + + return h_addr; +} + + char * +get_iface_ip(const char *ifname) +{ +#if defined(__linux__) + struct ifreq if_data; + struct in_addr in; + char *ip_str; + int sockd; + u_int32_t ip; + + /* Create a socket */ + if ((sockd = socket (AF_INET, SOCK_PACKET, htons(0x8086))) < 0) { + debug(LOG_ERR, "socket(): %s", strerror(errno)); + return NULL; + } + + /* Get IP of internal interface */ + strcpy (if_data.ifr_name, ifname); + + /* Get the IP address */ + if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) { + debug(LOG_ERR, "ioctl(): SIOCGIFADDR %s", strerror(errno)); + return NULL; + } + memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4); + in.s_addr = ip; + + ip_str = inet_ntoa(in); + close(sockd); + return safe_strdup(ip_str); +#elif defined(__NetBSD__) + struct ifaddrs *ifa, *ifap; + char *str = NULL; + + if (getifaddrs(&ifap) == -1) { + debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); + return NULL; + } + /* XXX arbitrarily pick the first IPv4 address */ + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, ifname) == 0 && + ifa->ifa_addr->sa_family == AF_INET) + break; + } + if (ifa == NULL) { + debug(LOG_ERR, "%s: no IPv4 address assigned"); + goto out; + } + str = safe_strdup(inet_ntoa( + ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr)); +out: + freeifaddrs(ifap); + return str; +#else + return safe_strdup("0.0.0.0"); +#endif +} + + char * +get_iface_mac(const char *ifname) +{ +#if defined(__linux__) + int r, s; + struct ifreq ifr; + char *hwaddr, mac[13]; + + strcpy(ifr.ifr_name, ifname); + + s = socket(PF_INET, SOCK_DGRAM, 0); + if (-1 == s) { + debug(LOG_ERR, "get_iface_mac socket: %s", strerror(errno)); + return NULL; + } + + r = ioctl(s, SIOCGIFHWADDR, &ifr); + if (r == -1) { + debug(LOG_ERR, "get_iface_mac ioctl(SIOCGIFHWADDR): %s", strerror(errno)); + close(s); + return NULL; + } + + hwaddr = ifr.ifr_hwaddr.sa_data; + close(s); + snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", + hwaddr[0] & 0xFF, + hwaddr[1] & 0xFF, + hwaddr[2] & 0xFF, + hwaddr[3] & 0xFF, + hwaddr[4] & 0xFF, + hwaddr[5] & 0xFF + ); + + return safe_strdup(mac); +#elif defined(__NetBSD__) + struct ifaddrs *ifa, *ifap; + const char *hwaddr; + char mac[13], *str = NULL; + struct sockaddr_dl *sdl; + + if (getifaddrs(&ifap) == -1) { + debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); + return NULL; + } + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, ifname) == 0 && + ifa->ifa_addr->sa_family == AF_LINK) + break; + } + if (ifa == NULL) { + debug(LOG_ERR, "%s: no link-layer address assigned"); + goto out; + } + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + hwaddr = LLADDR(sdl); + snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", + hwaddr[0] & 0xFF, hwaddr[1] & 0xFF, + hwaddr[2] & 0xFF, hwaddr[3] & 0xFF, + hwaddr[4] & 0xFF, hwaddr[5] & 0xFF); + + str = safe_strdup(mac); +out: + freeifaddrs(ifap); + return str; +#else + return NULL; +#endif +} + + char * +get_ext_iface(void) +{ +#ifdef __linux__ + FILE *input; + char *device, *gw; + int i = 1; + int keep_detecting = 1; + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + device = (char *)malloc(16); + gw = (char *)malloc(16); + debug(LOG_DEBUG, "get_ext_iface(): Autodectecting the external interface from routing table"); + while(keep_detecting) { + input = fopen("/proc/net/route", "r"); + while (!feof(input)) { + /* XXX scanf(3) is unsafe, risks overrun */ + if ((fscanf(input, "%s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n", device, gw) == 2) && strcmp(gw, "00000000") == 0) { + free(gw); + debug(LOG_INFO, "get_ext_iface(): Detected %s as the default interface after try %d", device, i); + return device; + } + } + fclose(input); + debug(LOG_ERR, "get_ext_iface(): Failed to detect the external interface after try %d (maybe the interface is not up yet?). Retry limit: %d", i, NUM_EXT_INTERFACE_DETECT_RETRY); + /* Sleep for EXT_INTERFACE_DETECT_RETRY_INTERVAL seconds */ + timeout.tv_sec = time(NULL) + EXT_INTERFACE_DETECT_RETRY_INTERVAL; + timeout.tv_nsec = 0; + /* Mutex must be locked for pthread_cond_timedwait... */ + pthread_mutex_lock(&cond_mutex); + /* Thread safe "sleep" */ + pthread_cond_timedwait(&cond, &cond_mutex, &timeout); + /* No longer needs to be locked */ + pthread_mutex_unlock(&cond_mutex); + //for (i=1; i<=NUM_EXT_INTERFACE_DETECT_RETRY; i++) { + if (NUM_EXT_INTERFACE_DETECT_RETRY != 0 && i>NUM_EXT_INTERFACE_DETECT_RETRY) { + keep_detecting = 0; + } + i++; + } + debug(LOG_ERR, "get_ext_iface(): Failed to detect the external interface after %d tries, aborting", i); + exit(1); + free(device); + free(gw); +#endif + return NULL; + } + + void mark_online() { + int before; + int after; + + before = is_online(); + time(&last_online_time); + after = is_online(); + + if (before != after) { + debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF")); + } + + } + + void mark_offline() { + int before; + int after; + + before = is_online(); + time(&last_offline_time); + after = is_online(); + + if (before != after) { + debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF")); + } + + /* If we're offline it definately means the auth server is offline */ + mark_auth_offline(); + + } + + int is_online() { + if (last_online_time == 0 || (last_offline_time - last_online_time) >= (config_get_config()->checkinterval * 2) ) { + /* We're probably offline */ + return (0); + } + else { + /* We're probably online */ + return (1); + } + } + + void mark_auth_online() { + int before; + int after; + + before = is_auth_online(); + time(&last_auth_online_time); + after = is_auth_online(); + + if (before != after) { + debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF")); + } + + /* If auth server is online it means we're definately online */ + mark_online(); + + } + + void mark_auth_offline() { + int before; + int after; + + before = is_auth_online(); + time(&last_auth_offline_time); + after = is_auth_online(); + + if (before != after) { + debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF")); + } + + } + + int is_auth_online() { + if (!is_online()) { + /* If we're not online auth is definately not online :) */ + return (0); + } + else if (last_auth_online_time == 0 || (last_auth_offline_time - last_auth_online_time) >= (config_get_config()->checkinterval * 2) ) { + /* Auth is probably offline */ + return (0); + } + else { + /* Auth is probably online */ + return (1); + } + } + + /* + * @return A string containing human-readable status text. MUST BE free()d by caller + */ + char * get_status_text() { + char buffer[STATUS_BUF_SIZ]; + ssize_t len; + s_config *config; + t_auth_serv *auth_server; + t_client *first; + int count; + unsigned long int uptime = 0; + unsigned int days = 0, hours = 0, minutes = 0, seconds = 0; + t_trusted_mac *p; + + len = 0; + snprintf(buffer, (sizeof(buffer) - len), "WiFiDog status\n\n"); + len = strlen(buffer); + + uptime = time(NULL) - started_time; + days = uptime / (24 * 60 * 60); + uptime -= days * (24 * 60 * 60); + hours = uptime / (60 * 60); + uptime -= hours * (60 * 60); + minutes = uptime / 60; + uptime -= minutes * 60; + seconds = uptime; + + snprintf((buffer + len), (sizeof(buffer) - len), "Version: " VERSION "\n"); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Has been restarted: "); + len = strlen(buffer); + if (restart_orig_pid) { + snprintf((buffer + len), (sizeof(buffer) - len), "yes (from PID %d)\n", restart_orig_pid); + len = strlen(buffer); + } + else { + snprintf((buffer + len), (sizeof(buffer) - len), "no\n"); + len = strlen(buffer); + } + + snprintf((buffer + len), (sizeof(buffer) - len), "Internet Connectivity: %s\n", (is_online() ? "yes" : "no")); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Auth server reachable: %s\n", (is_auth_online() ? "yes" : "no")); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Clients served this session: %lu\n\n", served_this_session); + len = strlen(buffer); + + LOCK_CLIENT_LIST(); + + first = client_get_first_client(); + + if (first == NULL) { + count = 0; + } else { + count = 1; + while (first->next != NULL) { + first = first->next; + count++; + } + } + + snprintf((buffer + len), (sizeof(buffer) - len), "%d clients " + "connected.\n", count); + len = strlen(buffer); + + first = client_get_first_client(); + + count = 0; + while (first != NULL) { + snprintf((buffer + len), (sizeof(buffer) - len), "\nClient %d\n", count); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), " IP: %s MAC: %s\n", first->ip, first->mac); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), " Token: %s\n", first->token); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), " Downloaded: %llu\n Uploaded: %llu\n" , first->counters.incoming, first->counters.outgoing); + len = strlen(buffer); + + count++; + first = first->next; + } + + UNLOCK_CLIENT_LIST(); + + config = config_get_config(); + + if (config->trustedmaclist != NULL) { + snprintf((buffer + len), (sizeof(buffer) - len), "\nTrusted MAC addresses:\n"); + len = strlen(buffer); + + for (p = config->trustedmaclist; p != NULL; p = p->next) { + snprintf((buffer + len), (sizeof(buffer) - len), " %s\n", p->mac); + len = strlen(buffer); + } + } + + snprintf((buffer + len), (sizeof(buffer) - len), "\nAuthentication servers:\n"); + len = strlen(buffer); + + LOCK_CONFIG(); + + for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { + snprintf((buffer + len), (sizeof(buffer) - len), " Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip); + len = strlen(buffer); + } + + UNLOCK_CONFIG(); + + return safe_strdup(buffer); + } diff --git a/src/util.h b/src/util.h new file mode 100755 index 00000000..7802853f --- /dev/null +++ b/src/util.h @@ -0,0 +1,79 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file util.h + @brief Misc utility functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#define STATUS_BUF_SIZ 16384 + + +/** @brief Execute a shell command + */ +int execute(const char *cmd_line, int quiet); +struct in_addr *wd_gethostbyname(const char *name); + +/* @brief Get IP address of an interface */ +char *get_iface_ip(const char *ifname); + +/* @brief Get MAC address of an interface */ +char *get_iface_mac(const char *ifname); + +/* @brief Get interface name of default gateway */ +char *get_ext_iface (void); + +/* @brief Sets hint that an online action (dns/connect/etc using WAN) succeeded */ +void mark_online(); +/* @brief Sets hint that an online action (dns/connect/etc using WAN) failed */ +void mark_offline(); +/* @brief Returns a guess (true or false) on whether we're online or not based on previous calls to mark_online and mark_offline */ +int is_online(); + +/* @brief Sets hint that an auth server online action succeeded */ +void mark_auth_online(); +/* @brief Sets hint that an auth server online action failed */ +void mark_auth_offline(); +/* @brief Returns a guess (true or false) on whether we're an auth server is online or not based on previous calls to mark_auth_online and mark_auth_offline */ +int is_auth_online(); + +/* + * @brief Creates a human-readable paragraph of the status of wifidog + */ +char * get_status_text(); + +#define LOCK_GHBN() do { \ + debug(LOG_DEBUG, "Locking wd_gethostbyname()"); \ + pthread_mutex_lock(&ghbn_mutex); \ + debug(LOG_DEBUG, "wd_gethostbyname() locked"); \ +} while (0) + +#define UNLOCK_GHBN() do { \ + debug(LOG_DEBUG, "Unlocking wd_gethostbyname()"); \ + pthread_mutex_unlock(&ghbn_mutex); \ + debug(LOG_DEBUG, "wd_gethostbyname() unlocked"); \ +} while (0) + +#endif /* _UTIL_H_ */ + diff --git a/src/wdctl.c b/src/wdctl.c new file mode 100755 index 00000000..c6f6fea0 --- /dev/null +++ b/src/wdctl.c @@ -0,0 +1,327 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl.c + @brief Monitoring and control of wifidog, client part + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wdctl.h" + +s_config config; + +static void usage(void); +static void init_config(void); +static void parse_commandline(int, char **); +static int connect_to_server(const char *); +static size_t send_request(int, const char *); +static void wdctl_status(void); +static void wdctl_stop(void); +static void wdctl_reset(void); +static void wdctl_restart(void); + +/** @internal + * @brief Print usage + * + * Prints usage, called when wdctl is run with -h or with an unknown option + */ +static void +usage(void) +{ + printf("Usage: wdctl [options] command [arguments]\n"); + printf("\n"); + printf("options:\n"); + printf(" -s Path to the socket\n"); + printf(" -h Print usage\n"); + printf("\n"); + printf("commands:\n"); + printf(" reset [mac|ip] Reset the specified mac or ip connection\n"); + printf(" status Obtain the status of wifidog\n"); + printf(" stop Stop the running wifidog\n"); + printf(" restart Re-start the running wifidog (without disconnecting active users!)\n"); + printf("\n"); +} + +/** @internal + * + * Init default values in config struct + */ +static void +init_config(void) +{ + + config.socket = strdup(DEFAULT_SOCK); + config.command = WDCTL_UNDEF; +} + +/** @internal + * + * Uses getopt() to parse the command line and set configuration values + */ +void +parse_commandline(int argc, char **argv) +{ + extern int optind; + int c; + + while (-1 != (c = getopt(argc, argv, "s:h"))) { + switch(c) { + case 'h': + usage(); + exit(1); + break; + + case 's': + if (optarg) { + free(config.socket); + config.socket = strdup(optarg); + } + break; + + default: + usage(); + exit(1); + break; + } + } + + if ((argc - optind) <= 0) { + usage(); + exit(1); + } + + if (strcmp(*(argv + optind), "status") == 0) { + config.command = WDCTL_STATUS; + } else if (strcmp(*(argv + optind), "stop") == 0) { + config.command = WDCTL_STOP; + } else if (strcmp(*(argv + optind), "reset") == 0) { + config.command = WDCTL_KILL; + if ((argc - (optind + 1)) <= 0) { + fprintf(stderr, "wdctl: Error: You must specify an IP " + "or a Mac address to reset\n"); + usage(); + exit(1); + } + config.param = strdup(*(argv + optind + 1)); + } else if (strcmp(*(argv + optind), "restart") == 0) { + config.command = WDCTL_RESTART; + } + else { + fprintf(stderr, "wdctl: Error: Invalid command \"%s\"\n", *(argv + optind)); + usage(); + exit(1); + } +} + +static int +connect_to_server(const char *sock_name) +{ + int sock; + struct sockaddr_un sa_un; + + /* Connect to socket */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + memset(&sa_un, 0, sizeof(sa_un)); + sa_un.sun_family = AF_UNIX; + strncpy(sa_un.sun_path, sock_name, (sizeof(sa_un.sun_path) - 1)); + + if (connect(sock, (struct sockaddr *)&sa_un, + strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { + fprintf(stderr, "wdctl: wifidog probably not started (Error: %s)\n", strerror(errno)); + exit(1); + } + + return sock; +} + +static size_t +send_request(int sock, const char *request) +{ + size_t len; + ssize_t written; + + len = 0; + while (len != strlen(request)) { + written = write(sock, (request + len), strlen(request) - len); + if (written == -1) { + fprintf(stderr, "Write to wifidog failed: %s\n", + strerror(errno)); + exit(1); + } + len += written; + } + + return len; +} + +static void +wdctl_status(void) +{ + int sock; + char buffer[4096]; + char request[16]; + int len; + + sock = connect_to_server(config.socket); + + strncpy(request, "status\r\n\r\n", 15); + + len = send_request(sock, request); + + while ((len = read(sock, buffer, sizeof(buffer))) > 0) { + buffer[len] = '\0'; + printf("%s", buffer); + } + + shutdown(sock, 2); + close(sock); +} + +static void +wdctl_stop(void) +{ + int sock; + char buffer[4096]; + char request[16]; + int len; + + sock = connect_to_server(config.socket); + + strncpy(request, "stop\r\n\r\n", 15); + + len = send_request(sock, request); + + while ((len = read(sock, buffer, sizeof(buffer))) > 0) { + buffer[len] = '\0'; + printf("%s", buffer); + } + + shutdown(sock, 2); + close(sock); +} + +void +wdctl_reset(void) +{ + int sock; + char buffer[4096]; + char request[64]; + size_t len; + int rlen; + + sock = connect_to_server(config.socket); + + strncpy(request, "reset ", 64); + strncat(request, config.param, (64 - strlen(request))); + strncat(request, "\r\n\r\n", (64 - strlen(request))); + + len = send_request(sock, request); + + len = 0; + memset(buffer, 0, sizeof(buffer)); + while ((len < sizeof(buffer)) && ((rlen = read(sock, (buffer + len), + (sizeof(buffer) - len))) > 0)){ + len += rlen; + } + + if (strcmp(buffer, "Yes") == 0) { + printf("Connection %s successfully reset.\n", config.param); + } else if (strcmp(buffer, "No") == 0) { + printf("Connection %s was not active.\n", config.param); + } else { + fprintf(stderr, "wdctl: Error: WiFiDog sent an abnormal " + "reply.\n"); + } + + shutdown(sock, 2); + close(sock); +} + +static void +wdctl_restart(void) +{ + int sock; + char buffer[4096]; + char request[16]; + int len; + + sock = connect_to_server(config.socket); + + strncpy(request, "restart\r\n\r\n", 15); + + len = send_request(sock, request); + + while ((len = read(sock, buffer, sizeof(buffer))) > 0) { + buffer[len] = '\0'; + printf("%s", buffer); + } + + shutdown(sock, 2); + close(sock); +} + +int +main(int argc, char **argv) +{ + + /* Init configuration */ + init_config(); + parse_commandline(argc, argv); + + switch(config.command) { + case WDCTL_STATUS: + wdctl_status(); + break; + + case WDCTL_STOP: + wdctl_stop(); + break; + + case WDCTL_KILL: + wdctl_reset(); + break; + + case WDCTL_RESTART: + wdctl_restart(); + break; + + default: + /* XXX NEVER REACHED */ + fprintf(stderr, "Oops\n"); + exit(1); + break; + } + exit(0); +} diff --git a/src/wdctl.h b/src/wdctl.h new file mode 100755 index 00000000..d559e327 --- /dev/null +++ b/src/wdctl.h @@ -0,0 +1,43 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl.h + @brief WiFiDog monitoring client + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _WDCTL_H_ +#define _WDCTL_H_ + +#define DEFAULT_SOCK "/tmp/wdctl.sock" + +#define WDCTL_UNDEF 0 +#define WDCTL_STATUS 1 +#define WDCTL_STOP 2 +#define WDCTL_KILL 3 +#define WDCTL_RESTART 4 + +typedef struct { + char *socket; + int command; + char *param; +} s_config; +#endif diff --git a/src/wdctl_thread.c b/src/wdctl_thread.c new file mode 100755 index 00000000..4ec786b0 --- /dev/null +++ b/src/wdctl_thread.c @@ -0,0 +1,401 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl_thread.c + @brief Monitoring and control of wifidog, server part + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "httpd.h" +#include "util.h" +#include "conf.h" +#include "debug.h" +#include "auth.h" +#include "centralserver.h" +#include "fw_iptables.h" +#include "firewall.h" +#include "client_list.h" +#include "wdctl_thread.h" +#include "gateway.h" +#include "safe.h" + +/* Defined in clientlist.c */ +extern pthread_mutex_t client_list_mutex; +extern pthread_mutex_t config_mutex; + +/* From commandline.c: */ +extern char ** restartargv; +static void *thread_wdctl_handler(void *); +static void wdctl_status(int); +static void wdctl_stop(int); +static void wdctl_reset(int, const char *); +static void wdctl_restart(int); + +/** Launches a thread that monitors the control socket for request +@param arg Must contain a pointer to a string containing the Unix domain socket to open +@todo This thread loops infinitely, need a watchdog to verify that it is still running? +*/ +void +thread_wdctl(void *arg) +{ + int *fd; + char *sock_name; + struct sockaddr_un sa_un; + int result; + pthread_t tid; + socklen_t len; + + debug(LOG_DEBUG, "Starting wdctl."); + + memset(&sa_un, 0, sizeof(sa_un)); + sock_name = (char *)arg; + debug(LOG_DEBUG, "Socket name: %s", sock_name); + + if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { + /* TODO: Die handler with logging.... */ + debug(LOG_ERR, "WDCTL socket name too long"); + exit(1); + } + + + debug(LOG_DEBUG, "Creating socket"); + wdctl_socket_server = socket(PF_UNIX, SOCK_STREAM, 0); + + debug(LOG_DEBUG, "Got server socket %d", wdctl_socket_server); + + /* If it exists, delete... Not the cleanest way to deal. */ + unlink(sock_name); + + debug(LOG_DEBUG, "Filling sockaddr_un"); + strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we + * check a few lines before. */ + sa_un.sun_family = AF_UNIX; + + debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, + strlen(sock_name)); + + /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ + if (bind(wdctl_socket_server, (struct sockaddr *)&sa_un, strlen(sock_name) + + sizeof(sa_un.sun_family))) { + debug(LOG_ERR, "Could not bind control socket: %s", + strerror(errno)); + pthread_exit(NULL); + } + + if (listen(wdctl_socket_server, 5)) { + debug(LOG_ERR, "Could not listen on control socket: %s", + strerror(errno)); + pthread_exit(NULL); + } + + while (1) { + len = sizeof(sa_un); + memset(&sa_un, 0, len); + fd = (int *) safe_malloc(sizeof(int)); + if ((*fd = accept(wdctl_socket_server, (struct sockaddr *)&sa_un, &len)) == -1){ + debug(LOG_ERR, "Accept failed on control socket: %s", + strerror(errno)); + free(fd); + } else { + debug(LOG_DEBUG, "Accepted connection on wdctl socket %d (%s)", fd, sa_un.sun_path); + result = pthread_create(&tid, NULL, &thread_wdctl_handler, (void *)fd); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl handler) - exiting"); + free(fd); + termination_handler(0); + } + pthread_detach(tid); + } + } +} + + +static void * +thread_wdctl_handler(void *arg) +{ + int fd, + done, + i; + char request[MAX_BUF]; + ssize_t read_bytes, + len; + + debug(LOG_DEBUG, "Entering thread_wdctl_handler...."); + + fd = *((int *) arg); + free(arg); + debug(LOG_DEBUG, "Read bytes and stuff from %d", fd); + + /* Init variables */ + read_bytes = 0; + done = 0; + memset(request, 0, sizeof(request)); + + /* Read.... */ + while (!done && read_bytes < (sizeof(request) - 1)) { + len = read(fd, request + read_bytes, + sizeof(request) - read_bytes); + + /* Have we gotten a command yet? */ + for (i = read_bytes; i < (read_bytes + len); i++) { + if (request[i] == '\r' || request[i] == '\n') { + request[i] = '\0'; + done = 1; + } + } + + /* Increment position */ + read_bytes += len; + } + + if (strncmp(request, "status", 6) == 0) { + wdctl_status(fd); + } else if (strncmp(request, "stop", 4) == 0) { + wdctl_stop(fd); + } else if (strncmp(request, "reset", 5) == 0) { + wdctl_reset(fd, (request + 6)); + } else if (strncmp(request, "restart", 7) == 0) { + wdctl_restart(fd); + } + + if (!done) { + debug(LOG_ERR, "Invalid wdctl request."); + shutdown(fd, 2); + close(fd); + pthread_exit(NULL); + } + + debug(LOG_DEBUG, "Request received: [%s]", request); + + shutdown(fd, 2); + close(fd); + debug(LOG_DEBUG, "Exiting thread_wdctl_handler...."); + + return NULL; +} + +static void +wdctl_status(int fd) +{ + char * status = NULL; + int len = 0; + + status = get_status_text(); + len = strlen(status); + + if(write(fd, status, len) == -1) + debug(LOG_CRIT, "Write error: %s", strerror(errno)); + + free(status); +} + +/** A bit of an hack, self kills.... */ +static void +wdctl_stop(int fd) +{ + pid_t pid; + + pid = getpid(); + kill(pid, SIGINT); +} + +static void +wdctl_restart(int afd) +{ + int sock, + fd; + char *sock_name; + struct sockaddr_un sa_un; + s_config * conf = NULL; + t_client * client = NULL; + char * tempstring = NULL; + pid_t pid; + ssize_t written; + socklen_t len; + + conf = config_get_config(); + + debug(LOG_NOTICE, "Will restart myself"); + + /* + * First, prepare the internal socket + */ + memset(&sa_un, 0, sizeof(sa_un)); + sock_name = conf->internal_sock; + debug(LOG_DEBUG, "Socket name: %s", sock_name); + + if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { + /* TODO: Die handler with logging.... */ + debug(LOG_ERR, "INTERNAL socket name too long"); + return; + } + + debug(LOG_DEBUG, "Creating socket"); + sock = socket(PF_UNIX, SOCK_STREAM, 0); + + debug(LOG_DEBUG, "Got internal socket %d", sock); + + /* If it exists, delete... Not the cleanest way to deal. */ + unlink(sock_name); + + debug(LOG_DEBUG, "Filling sockaddr_un"); + strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we check a few lines before. */ + sa_un.sun_family = AF_UNIX; + + debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, strlen(sock_name)); + + /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ + if (bind(sock, (struct sockaddr *)&sa_un, strlen(sock_name) + sizeof(sa_un.sun_family))) { + debug(LOG_ERR, "Could not bind internal socket: %s", strerror(errno)); + return; + } + + if (listen(sock, 5)) { + debug(LOG_ERR, "Could not listen on internal socket: %s", strerror(errno)); + return; + } + + /* + * The internal socket is ready, fork and exec ourselves + */ + debug(LOG_DEBUG, "Forking in preparation for exec()..."); + pid = safe_fork(); + if (pid > 0) { + /* Parent */ + + /* Wait for the child to connect to our socket :*/ + debug(LOG_DEBUG, "Waiting for child to connect on internal socket"); + len = sizeof(sa_un); + if ((fd = accept(sock, (struct sockaddr *)&sa_un, &len)) == -1){ + debug(LOG_ERR, "Accept failed on internal socket: %s", strerror(errno)); + close(sock); + return; + } + + close(sock); + + debug(LOG_DEBUG, "Received connection from child. Sending them all existing clients"); + + /* The child is connected. Send them over the socket the existing clients */ + LOCK_CLIENT_LIST(); + client = client_get_first_client(); + while (client) { + /* Send this client */ + safe_asprintf(&tempstring, "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu\n", client->ip, client->mac, client->token, client->fw_connection_state, client->fd, client->counters.incoming, client->counters.outgoing, client->counters.last_updated); + debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); + len = 0; + while (len != strlen(tempstring)) { + written = write(fd, (tempstring + len), strlen(tempstring) - len); + if (written == -1) { + debug(LOG_ERR, "Failed to write client data to child: %s", strerror(errno)); + free(tempstring); + break; + } + else { + len += written; + } + } + free(tempstring); + client = client->next; + } + UNLOCK_CLIENT_LIST(); + + close(fd); + + debug(LOG_INFO, "Sent all existing clients to child. Committing suicide!"); + + shutdown(afd, 2); + close(afd); + + /* Our job in life is done. Commit suicide! */ + wdctl_stop(afd); + } + else { + /* Child */ + close(wdctl_socket_server); + close(icmp_fd); + close(sock); + shutdown(afd, 2); + close(afd); + debug(LOG_NOTICE, "Re-executing myself (%s)", restartargv[0]); + setsid(); + execvp(restartargv[0], restartargv); + /* If we've reached here the exec() failed - die quickly and silently */ + debug(LOG_ERR, "I failed to re-execute myself: %s", strerror(errno)); + debug(LOG_ERR, "Exiting without cleanup"); + exit(1); + } + +} + +static void +wdctl_reset(int fd, const char *arg) +{ + t_client *node; + + debug(LOG_DEBUG, "Entering wdctl_reset..."); + + LOCK_CLIENT_LIST(); + debug(LOG_DEBUG, "Argument: %s (@%x)", arg, arg); + + /* We get the node or return... */ + if ((node = client_list_find_by_ip(arg)) != NULL); + else if ((node = client_list_find_by_mac(arg)) != NULL); + else { + debug(LOG_DEBUG, "Client not found."); + UNLOCK_CLIENT_LIST(); + if(write(fd, "No", 2) == -1) + debug(LOG_CRIT, "Unable to write No: %s", strerror(errno)); + + return; + } + + debug(LOG_DEBUG, "Got node %x.", node); + + /* deny.... */ + /* TODO: maybe just deleting the connection is not best... But this + * is a manual command, I don't anticipate it'll be that useful. */ + fw_deny(node->ip, node->mac, node->fw_connection_state); + client_list_delete(node); + + UNLOCK_CLIENT_LIST(); + + if(write(fd, "Yes", 3) == -1) + debug(LOG_CRIT, "Unable to write Yes: %s", strerror(errno)); + + debug(LOG_DEBUG, "Exiting wdctl_reset..."); +} diff --git a/src/wdctl_thread.h b/src/wdctl_thread.h new file mode 100755 index 00000000..0956bf96 --- /dev/null +++ b/src/wdctl_thread.h @@ -0,0 +1,37 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl_thread.h + @brief WiFiDog monitoring thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _WDCTL_THREAD_H_ +#define _WDCTL_THREAD_H_ + +#define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" + +int wdctl_socket_server; + +/** @brief Listen for WiFiDog control messages on a unix domain socket */ +void thread_wdctl(void *arg); + +#endif diff --git a/wifidog-msg.html.in b/wifidog-msg.html.in new file mode 100755 index 00000000..df903774 --- /dev/null +++ b/wifidog-msg.html.in @@ -0,0 +1,107 @@ + + +$title + + + + + + + + + + + + +
+

$message

+
+ + + + + + + diff --git a/wifidog.conf b/wifidog.conf new file mode 100755 index 00000000..fa6ec558 --- /dev/null +++ b/wifidog.conf @@ -0,0 +1,281 @@ +# $Id$ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + + +# Parameter: WhiteList +# Default: none +# Optional +# Comma separated list of url who are allowed to pass +# through router +#WhiteList www.baidu.com,www.taobao.com + +# Parameter: BlackList +# Default: none +# Optional +# Comma separated list of url who are not allowed to pass +# through router +#BlackList www.av123.com,www.av456.com + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + + # FirewallRule syntax: + # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X]] [to IP/CIDR] + + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/wifidog.spec.in b/wifidog.spec.in new file mode 100755 index 00000000..fb9f410f --- /dev/null +++ b/wifidog.spec.in @@ -0,0 +1,69 @@ +# $Id$ + +%define name wifidog +%define lib_name libhttpd +%define version @VERSION@ +%define release 1mdk + +Summary: The WiFi Guard Dog project is a complete and embeedable captive portal solution for wireless community groups or individuals who wish to open a free HotSpot while still preventing abuse of their Internet connection. +Name: %{name} +Version: %{version} +Release: %{release} +Source: http://download.sourceforge.net/wifidog/%{name}-%{version}.tar.gz +Group: Applications/System +License: GPL +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Prereq: /sbin/ldconfig + +%description +The WiFi Guard Dog project is a complete and embeedable captive portal solution for wireless community groups or individuals who wish to open a free HotSpot while still preventing abuse of their Internet connection. + +%prep +%setup -q + +%build +%configure +%make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT%{_prefix} + + +# Will this overide previous config file? +mkdir -p $RPM_BUILD_ROOT/etc +cp wifidog.conf $RPM_BUILD_ROOT/etc +mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d +cp scripts/init.d/wifidog $RPM_BUILD_ROOT/etc/rc.d/init.d +chmod +x $RPM_BUILD_ROOT/etc/rc.d/init.d/wifidog + +%makeinstall + +%post +/sbin/ldconfig +%_post_service wifidog + +%postun +/sbin/ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,0755) +%doc AUTHORS COPYING ChangeLog INSTALL NEWS README FAQ doc/html +%config /etc/wifidog.conf +%config /etc/rc.d/init.d/wifidog +%{_bindir}/* +%{_libdir}/*.a +%{_libdir}/*.la +%{_libdir}/*.so* +%{_includedir}/* + +%changelog +* Sun Aug 29 2004 Guillaume Beaudoin +- Littles fixes and libofx leftover. +- Prefix changed to /usr to match init.d script (define removed). +* Sat Mar 8 2004 Benoit Grégoire +- Created spec file From bf366882a4083be70811a01e7071052025353922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=20=E9=AB=98=E6=98=8E?= Date: Mon, 10 Aug 2015 11:08:01 +0800 Subject: [PATCH 02/33] fix after restart the record time is not set --- scripts/Copy of white_black_flush.sh | 76 +++++++++++++--------------- src/gateway.c | 3 ++ src/wdctl_thread.c | 3 +- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/scripts/Copy of white_black_flush.sh b/scripts/Copy of white_black_flush.sh index aa0faa3e..c5e54467 100644 --- a/scripts/Copy of white_black_flush.sh +++ b/scripts/Copy of white_black_flush.sh @@ -1,45 +1,39 @@ #!/bin/sh -run=`pidof wifidog` -gateway_id=$(uci get wifidog_conf.single.gatewayId | awk '{print $NF}') -gateway_interface=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $NF}') -gateway_eninterface=$(uci get wifidog_conf.single.externalInterface | awk '{printf $NF}') -gateway_hostname=$(uci get wifidog_conf.authServer.hostname | awk '{print $NF}') -gateway_httpport=$(uci get wifidog_conf.authServer.httpPort | awk '{print $NF}') -gateway_path=$(uci get wifidog_conf.authServer.path | awk '{print $NF}') -gateway_connmax=$(uci get get wifidog_conf.single) -ssl_enable=$(uci get wifidog.@wifidog[0].ssl_enable) -check_interval=$(uci get wifidog.@wifidog[0].check_interval) -client_timeout=$(uci get wifidog.@wifidog[0].client_timeout) -sslport=$(uci get wifidog.@wifidog[0].sslport) -deamo_enable=$(uci get wifidog.@wifidog[0].deamo_enable) -gatewayport=$(uci get wifidog.@wifidog[0].gatewayport) -myz_mac=$(uci get wifidog.@wifidog[0].myz_mac) -whiteList=$(uci get wifidog.@wifidog[0].bmd_url) -blackList=$(uci get wifidog.@wifidog[0].hmd_url) -whiteList=`echo $tbmd_url | tr " " ","` -blackList=`echo $thmd_url | tr " " ","` -#touch files -mkdir -p /tmp/.white_black_list - -#compare -while [ true ] -do - #detect - iptables -t nat -L WiFiDog_"$gateway_interface"_WhiteList -n --line-numbers|awk '{for(i=6;icounters.last_updated = atol(value); + }/*record_time from parents*/ + else if (strcmp(key, "record_time") == 0) { + client->record_time = atol(value); } else { debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); diff --git a/src/wdctl_thread.c b/src/wdctl_thread.c index 4ec786b0..3e6bd5b7 100755 --- a/src/wdctl_thread.c +++ b/src/wdctl_thread.c @@ -315,7 +315,8 @@ wdctl_restart(int afd) client = client_get_first_client(); while (client) { /* Send this client */ - safe_asprintf(&tempstring, "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu\n", client->ip, client->mac, client->token, client->fw_connection_state, client->fd, client->counters.incoming, client->counters.outgoing, client->counters.last_updated); + safe_asprintf(&tempstring, "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu|record_time=%ld\n", \ + client->ip, client->mac, client->token, client->fw_connection_state, client->fd, client->counters.incoming, client->counters.outgoing, client->counters.last_updated, client->record_time); debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); len = 0; while (len != strlen(tempstring)) { From db9bd7e63f0dbcf612d38cb9783a04affc46afd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=20=E9=AB=98=E6=98=8E?= Date: Mon, 10 Aug 2015 16:50:54 +0800 Subject: [PATCH 03/33] fix result json formate --- scripts/Copy of white_black_flush.sh | 89 ------------------------- scripts/Copy of white_black_flush.sh~ | 95 --------------------------- scripts/GET_settings | 2 +- scripts/GET_settings~ | 48 -------------- scripts/conf/dog_post_conf | 8 +-- scripts/conf/wifidog_conf | 2 +- scripts/white_black_flush.sh | 95 --------------------------- scripts/white_black_flush.sh~ | 95 --------------------------- scripts/wifidog | 21 ------ src/gateway.c | 2 +- src/get_remote_shell.c | 5 +- 11 files changed, 10 insertions(+), 452 deletions(-) delete mode 100644 scripts/Copy of white_black_flush.sh delete mode 100644 scripts/Copy of white_black_flush.sh~ delete mode 100755 scripts/GET_settings~ delete mode 100644 scripts/white_black_flush.sh delete mode 100644 scripts/white_black_flush.sh~ delete mode 100644 scripts/wifidog diff --git a/scripts/Copy of white_black_flush.sh b/scripts/Copy of white_black_flush.sh deleted file mode 100644 index c5e54467..00000000 --- a/scripts/Copy of white_black_flush.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/sh -RUN_WIFIDOG_PID=`pidof wifidog` -GATEWAY_ID=$(uci get wifidog_conf.single.gatewayId | awk '{print $NF}') -GATEWAY_INTERFACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $NF}') - -TRUSTED_MAC_LIST=$(uci get wifidog_conf.trustedMACList.TrustedMACList) -UNTRUSTED_MAC_LIST=$(uci get wifidog_conf.untrustedMACList.UntrustedMACList) - -WHITE_LIST=$(uci get wifidog_conf.whiteBlackList.WhiteList) -BLACK_LIST=$(uci get wifidog_conf.whiteBlackList.BlackList) - -#WHITE_LIST=`echo $WHITE_LIST | tr " " ","` -#BLACK_LIST=`echo $BLACK_LIST | tr " " ","` -#touch files -mkdir -p /tmp/.white_black_list - -#compare -while [ true ] -do - #detect - iptables -t nat -L WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -n --line-numbers|awk '{for(i=6;i $RESULT_FILE -RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",")" +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" uci show wireless > $TMP while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP diff --git a/scripts/GET_settings~ b/scripts/GET_settings~ deleted file mode 100755 index 0ddaf4ba..00000000 --- a/scripts/GET_settings~ +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh -# -# description: get the settings of wireless, -# lan,wan,reboot_info and dhcp. -# use in OpenWrt router,based on uci. -# Version: 1.0.0 -# Author: GaomingPan -# 2015-07-29 -# -# Pram: $1 gw_id -# $2 cmd_id -# -TMP=/tmp/.tmpfile -STMP=/tmp/.stmpfile -RESULT_FILE=/tmp/routersettings -RESULT="" -echo "" > $RESULT_FILE -RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",")" -RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" -uci show wireless > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"lan\":{" -uci show network.lan > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"wan\":{" -uci show network.wan > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"dhcp\":{" -uci show dhcp > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," -RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}]}} - -rm $TMP $STMP -echo $RESULT > $RESULT_FILE - - diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf index 1bacbebe..46c165ba 100644 --- a/scripts/conf/dog_post_conf +++ b/scripts/conf/dog_post_conf @@ -1,9 +1,9 @@ config dog_post 'url' - option 'info_url' 'http://118.118.118.180:8080/wifidog/TestWge' - option 'normal_url' 'http://118.118.118.180:8080/wifidog/TestWge' + option 'info_url' 'http://118.118.118.8:8080/WiFiAuth/wifidog/result' + option 'normal_url' 'http://118.118.118.8:8080/WiFiAuth/wifidog/result' config dog_post 'rmflag' - option 'info_rmflag' 'TestWget' - option 'normal_rmflag' 'TestWget' + option 'info_rmflag' 'result' + option 'normal_rmflag' 'result' diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index 0bc58b3d..66c74800 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -14,7 +14,7 @@ config 'wifidog_conf' 'single' option httpdRealm '# HTTPDRealm WiFiDog' option httpdUserName '# HTTPDUserName admin' option httpdPassword '# HTTPDPassword secret' - option checkInterval '# CheckInterval 60' + option checkInterval 'CheckInterval 30' option clientTimeout 'ClientTimeout 5' diff --git a/scripts/white_black_flush.sh b/scripts/white_black_flush.sh deleted file mode 100644 index 3794e163..00000000 --- a/scripts/white_black_flush.sh +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/sh -run=`pidof wifidog` -gateway_id=$(uci get wifidog.@wifidog[0].gateway_id) -gateway_interface=$(uci get wifidog.@wifidog[0].gateway_interface) -gateway_eninterface=$(uci get wifidog.@wifidog[0].gateway_eninterface) -gateway_hostname=$(uci get wifidog.@wifidog[0].gateway_hostname) -gateway_httpport=$(uci get wifidog.@wifidog[0].gateway_httpport) -gateway_path=$(uci get wifidog.@wifidog[0].gateway_path) -gateway_connmax=$(uci get wifidog.@wifidog[0].gateway_connmax) -ssl_enable=$(uci get wifidog.@wifidog[0].ssl_enable) -check_interval=$(uci get wifidog.@wifidog[0].check_interval) -client_timeout=$(uci get wifidog.@wifidog[0].client_timeout) -sslport=$(uci get wifidog.@wifidog[0].sslport) -deamo_enable=$(uci get wifidog.@wifidog[0].deamo_enable) -gatewayport=$(uci get wifidog.@wifidog[0].gatewayport) -myz_mac=$(uci get wifidog.@wifidog[0].myz_mac) -tbmd_url=$(uci get wifidog.@wifidog[0].bmd_url) -thmd_url=$(uci get wifidog.@wifidog[0].hmd_url) -bmd_url=`echo $tbmd_url | tr " " ","` -hmd_url=`echo $thmd_url | tr " " ","` -#touch files -mkdir -p /tmp/.white_black_list - -#compare -while [ true ] -do - #detect - iptables -t nat -L WiFiDog_"$gateway_interface"_WhiteList -n --line-numbers|awk '{for(i=6;icounters.last_updated = atol(value); - }/*record_time from parents*/ + }/*get record_time from parents*/ else if (strcmp(key, "record_time") == 0) { client->record_time = atol(value); } diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c index ea79b27d..07036234 100644 --- a/src/get_remote_shell.c +++ b/src/get_remote_shell.c @@ -112,7 +112,7 @@ int post_normal_execut_output(char *gw_id, char *cmd_id) char output[MAX_CMD_EXECUT_OUT_LEN]; FILE *fp; - sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ + sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"type\\\":\\\"default\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ gw_id,cmd_id,BUILE_NORMAL_CMD_RESULT_SHELL,normal_http_url,normal_rmflag); debug(LOG_INFO,"output_normal:--> %s",output); fp = popen(output,"r"); @@ -183,7 +183,7 @@ int excute_shell_command(char *gw_id,char *shellcmd) } else { - sprintf(normal_cmd,"echo \"\" > "NORMAL_CMD_RESULT_FILE"RESULT=\"$(%s)\";echo \"$RESULT\" >> "NORMAL_CMD_RESULT_FILE,pos_cmd); + sprintf(normal_cmd,"RESULT=\"$(%s)\";echo \"$RESULT\" > "NORMAL_CMD_RESULT_FILE,pos_cmd); fp = popen(normal_cmd,"r"); } @@ -191,6 +191,7 @@ int excute_shell_command(char *gw_id,char *shellcmd) if(NULL == fp) { + debug(LOG_ERR,"excute_shell_command popen error...."); printf("excute_shell_command popen error....\n"); return -1; } From 8c2c1c6c9c59c39dba9f04e48b1c9fe22834c487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=20=E9=AB=98=E6=98=8E?= Date: Wed, 12 Aug 2015 10:53:21 +0800 Subject: [PATCH 04/33] add white-black url flush deamo --- contrib/airos/wifidog/Makefile | 70 ----- contrib/airos/wifidog/files.patch | 87 ------ contrib/airos/wifidog/files/wifidog.conf | 253 ------------------ contrib/airos/wifidog/files/wifidog.init | 27 -- .../wifidog/patches/100-counter_outoing.patch | 24 -- contrib/airos/wifidog/readme.txt | 43 --- contrib/build-deb/changelog | 14 - contrib/build-deb/control | 15 -- contrib/build-deb/rules | 74 ----- .../wifidog/Makefile | 62 ----- .../wifidog/files/wifidog.init | 18 -- .../wifidog/files/wifidog.conf | 246 ----------------- .../wifidog/files/wifidog.init | 17 -- .../wifidog/Config.in | 16 -- .../wifidog/Makefile | 65 ----- .../wifidog/files/wifidog.conf | 246 ----------------- .../wifidog/files/wifidog.init | 15 -- .../wifidog/ipkg/wifidog.conffiles | 1 - .../wifidog/ipkg/wifidog.control | 8 - .../wifidog/Makefile | 31 ++- .../wifidog/files/wifidog.conf | 43 ++- contrib/wifidog/files/wifidog.init | 32 +++ scripts/{GET_settings => GET_settings.sh} | 0 scripts/auth.sh | 25 ++ scripts/conf/dog_post_conf | 4 +- scripts/conf/wifidog_conf | 7 +- scripts/white_black_flush.sh | 86 ++++++ scripts/wifidog.init | 104 ------- 28 files changed, 206 insertions(+), 1427 deletions(-) delete mode 100755 contrib/airos/wifidog/Makefile delete mode 100755 contrib/airos/wifidog/files.patch delete mode 100755 contrib/airos/wifidog/files/wifidog.conf delete mode 100755 contrib/airos/wifidog/files/wifidog.init delete mode 100755 contrib/airos/wifidog/patches/100-counter_outoing.patch delete mode 100755 contrib/airos/wifidog/readme.txt delete mode 100755 contrib/build-deb/changelog delete mode 100755 contrib/build-deb/control delete mode 100755 contrib/build-deb/rules delete mode 100755 contrib/build-openwrt-kamikazeipk/wifidog/Makefile delete mode 100755 contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init delete mode 100755 contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf delete mode 100755 contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init delete mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/Config.in delete mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/Makefile delete mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf delete mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init delete mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles delete mode 100755 contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control rename contrib/{build-openwrt-kamikazeipk8.09up => }/wifidog/Makefile (59%) mode change 100755 => 100644 rename contrib/{build-openwrt-kamikazeipk => }/wifidog/files/wifidog.conf (88%) mode change 100755 => 100644 create mode 100644 contrib/wifidog/files/wifidog.init rename scripts/{GET_settings => GET_settings.sh} (100%) create mode 100755 scripts/auth.sh create mode 100755 scripts/white_black_flush.sh delete mode 100644 scripts/wifidog.init diff --git a/contrib/airos/wifidog/Makefile b/contrib/airos/wifidog/Makefile deleted file mode 100755 index 4195dbf1..00000000 --- a/contrib/airos/wifidog/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2006,2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_MD5SUM:= - -PKG_FIXUP = libtool - -include $(INCLUDE_DIR)/package.mk - -define Package/wifidog - SUBMENU:=Captive Portals - SECTION:=net - CATEGORY:=Network - DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +iptables-mod-nat +iptables-mod-nat-extra +libpthread - TITLE:=A wireless captive portal solution - URL:=http://www.wifidog.org -endef - -define Package/wifidog/description - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. -endef - -define Package/wifidog/conffiles - /usr/etc/wifidog.conf -endef - -MAKE_FLAGS += \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - -define Package/wifidog/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/usr/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/usr/etc/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/usr/etc/ - $(INSTALL_DIR) $(1)/usr/etc/init.d - $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/usr/etc/init.d/wifidog -endef - -define Package/wifidog/postinst -#!/bin/sh - -# # check if the wifidog is already running, if so restart it -if /etc/init.d/wifidog status | grep 'Authentication servers' > /dev/null; then - # create copies of passwd and group, if we use squashfs - /etc/init.d/wifidog restart -fi -endef - -$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/airos/wifidog/files.patch b/contrib/airos/wifidog/files.patch deleted file mode 100755 index a877a64b..00000000 --- a/contrib/airos/wifidog/files.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- SDK.UBNT.v5.2.clean/openwrt/package/ubnt-base-files/files/init 2010-05-14 06:11:06.000000000 -0400 -+++ SDK.UBNT.v5.2/openwrt/package/ubnt-base-files/files/init 2010-07-27 12:52:36.087267563 -0400 -@@ -64,7 +64,7 @@ echo "...filesystem init done" - # making sure that critical files are in place - mkdir -p /etc/rc.d /etc/init.d - # forced update --for f in inittab rc.d/rc.sysinit rc.d/rc rc.d/rc.stop ppp; do -+for f in inittab rc.d/rc.sysinit rc.d/rc rc.d/rc.stop ppp wifidog.conf wifidog-msg.html ; do - cp -f -r /usr/etc/$f /etc/$f - done - echo "...base ok" -@@ -139,6 +139,14 @@ if [ -e /sbin/ubntconf ]; then - /sbin/ubntconf - fi - -+#adding wifidog to startup programs -+if [ -f /usr/etc/init.d/wifidog ]; then -+ cp -f /usr/etc/init.d/wifidog /etc/sysinit/wifidog.conf -+ echo "null::respawn:/usr/bin/wifidog -f" >> /etc/inittab -+ echo "wifidog" >> /etc/startup.list -+fi -+ -+ - echo "...running /sbin/init" - exec /sbin/init - ---- SDK.UBNT.v5.2.clean/openwrt/package/ubnt-base-files/files/usr/etc/rc.d/rc.softrestart 2010-05-14 06:11:06.000000000 -0400 -+++ SDK.UBNT.v5.2/openwrt/package/ubnt-base-files/files/usr/etc/rc.d/rc.softrestart 2010-07-27 12:03:15.604767622 -0400 -@@ -80,3 +80,10 @@ if [ $# -gt 0 ]; then - -p /etc/ 2>/dev/null & - fi - fi -+ -+#adding wifidog to startup programs -+if [ -f /usr/etc/init.d/wifidog ]; then -+ cp -f /usr/etc/init.d/wifidog /etc/sysinit/wifidog.conf -+ echo "null::respawn:/usr/bin/wifidog -f" >> /etc/inittab -+ echo "wifidog" >> /etc/startup.list -+fi - ---- SDK.UBNT.v5.2.clean/openwrt/.config 2010-05-18 05:03:40.000000000 -0400 -+++ SDK.UBNT.v5.2/openwrt/.config 2010-07-26 14:59:08.131750309 -0400 -@@ -888,7 +888,7 @@ CONFIG_PACKAGE_hotplug2=y - CONFIG_PACKAGE_iptables=y - CONFIG_PACKAGE_iptables-mod-conntrack=y - CONFIG_PACKAGE_iptables-mod-conntrack-extra=y --# CONFIG_PACKAGE_iptables-mod-extra is not set -+CONFIG_PACKAGE_iptables-mod-extra=y - CONFIG_PACKAGE_iptables-mod-filter=y - # CONFIG_PACKAGE_iptables-mod-imq is not set - CONFIG_PACKAGE_iptables-mod-ipopt=y -@@ -896,7 +896,7 @@ CONFIG_PACKAGE_iptables-mod-ipopt=y - # CONFIG_PACKAGE_iptables-mod-ipsec is not set - # CONFIG_PACKAGE_iptables-mod-ipset is not set - CONFIG_PACKAGE_iptables-mod-nat=y --# CONFIG_PACKAGE_iptables-mod-nat-extra is not set -+CONFIG_PACKAGE_iptables-mod-nat-extra=y - # CONFIG_PACKAGE_iptables-mod-ulog is not set - # CONFIG_PACKAGE_iptables-utils is not set - # CONFIG_PACKAGE_ldconfig is not set -@@ -963,6 +963,7 @@ CONFIG_PACKAGE_php2=y - # - # Network - # -+CONFIG_PACKAGE_wifidog=y - - # - # Monitoring -@@ -1149,7 +1150,7 @@ CONFIG_PACKAGE_kmod-ebtables=y - CONFIG_PACKAGE_kmod-ipt-core=y - CONFIG_PACKAGE_kmod-ipt-conntrack=y - CONFIG_PACKAGE_kmod-ipt-conntrack-extra=y --# CONFIG_PACKAGE_kmod-ipt-extra is not set -+CONFIG_PACKAGE_kmod-ipt-extra=y - CONFIG_PACKAGE_kmod-ipt-filter=y - # CONFIG_PACKAGE_kmod-ipt-imq is not set - CONFIG_PACKAGE_kmod-ipt-ipopt=y -@@ -1157,7 +1158,7 @@ CONFIG_PACKAGE_kmod-ipt-ipopt=y - # CONFIG_PACKAGE_kmod-ipt-ipsec is not set - # CONFIG_PACKAGE_kmod-ipt-ipset is not set - CONFIG_PACKAGE_kmod-ipt-nat=y --# CONFIG_PACKAGE_kmod-ipt-nat-extra is not set -+CONFIG_PACKAGE_kmod-ipt-nat-extra=y - CONFIG_PACKAGE_kmod-ipt-nathelper=y - # CONFIG_PACKAGE_kmod-ipt-nathelper-extra is not set - # CONFIG_PACKAGE_kmod-ipt-queue is not set - diff --git a/contrib/airos/wifidog/files/wifidog.conf b/contrib/airos/wifidog/files/wifidog.conf deleted file mode 100755 index 32e9ea90..00000000 --- a/contrib/airos/wifidog/files/wifidog.conf +++ /dev/null @@ -1,253 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface eth0 - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: auth-is-down -# -# Used when auth server is down -FirewallRuleSet auth-is-down { -# FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/airos/wifidog/files/wifidog.init b/contrib/airos/wifidog/files/wifidog.init deleted file mode 100755 index 2c6857e9..00000000 --- a/contrib/airos/wifidog/files/wifidog.init +++ /dev/null @@ -1,27 +0,0 @@ -plugin_start() { - echo "Inserting kernel modules: " - insmod ip_conntrack - insmod ip_nat - insmod ip_tables - insmod ipt_MARK - insmod ipt_mark - insmod ipt_mac - insmod ipt_REDIRECT - insmod ipt_MASQUERADE - insmod ipt_state - insmod iptable_mangle - insmod iptable_nat - insmod iptable_filter - - # echo "Starting wifidog: " - - #/usr/bin/wifidog-init start - echo - true -} -plugin_stop() { - killall wifidog - #/usr/bin/wifidog-init stop - true -} - diff --git a/contrib/airos/wifidog/patches/100-counter_outoing.patch b/contrib/airos/wifidog/patches/100-counter_outoing.patch deleted file mode 100755 index 3fa8a1ad..00000000 --- a/contrib/airos/wifidog/patches/100-counter_outoing.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/src/fw_iptables.c 2009-09-18 19:01:57.000000000 -0400 -+++ b/src/fw_iptables.c 2010-08-21 19:37:28.975094088 -0400 -@@ -513,6 +513,7 @@ iptables_fw_counters_update(void) - char *script, - ip[16], - rc; -+ char mystring[250]; - unsigned long long int counter; - t_client *p1; - struct in_addr tempaddr; -@@ -533,8 +534,11 @@ iptables_fw_counters_update(void) - while (('\n' != fgetc(output)) && !feof(output)) - ; - while (output && !(feof(output))) { -- rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); -+ rc = fgets(mystring,250,output); -+ rc = sscanf(mystring, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); -+ //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); - //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); -+ - if (2 == rc && EOF != rc) { - /* Sanity*/ - if (!inet_aton(ip, &tempaddr)) { - diff --git a/contrib/airos/wifidog/readme.txt b/contrib/airos/wifidog/readme.txt deleted file mode 100755 index 38e28aa3..00000000 --- a/contrib/airos/wifidog/readme.txt +++ /dev/null @@ -1,43 +0,0 @@ --- Compiling airos with the wifidog package running at boot - -Because airos doesn't have a package manager like opkf and has a (mostly) read-only file system, we need to build the the firmware with wifidog in it to have wifidog running on airos - -1- Get the latest wifidog source code tarball from sourceforge (http://sourceforge.net/projects/wifidog/files/) and copy it to the ~/dev/wifidog directory - -2- Get the wifidog airos package directory - -cd ~/dev/wifidog -wget http://dev.wifidog.org/wiki/doc/install/airos/wifidog_airos.tar.gz -tar xvzf wifidog_airos.tar.gz - -If compiling from source, this directory is located in wifidog/contrib/airos - -3- Download the airos SDK from http://www.ubnt.com/support/downloads and copy it to the ~/dev/airos directory - -4- Untar the SDK and prepare the files - -cd ~/dev/airos -tar xvjf SDK.UBNT.v5.2.tar.bz2 -cd SDK.UBNT.v5.2 - -cd openwrt/package -ln -s ~/dev/wifidog/airos/wifidog/ -cd ../dl -ln -s ~/dev/wifidog/wifidog-20090925.tar.gz - -cd ../.. -patch -p1 < openwrt/package/wifidog/files.patch - -5- Prepare the wifidog.conf file for your network, since airos is readonly, changes to the config files cannot be done in the router - -cd ~/dev/airos/SDK.UBNT.v5.2/openwrt -mkdir -p files/usr/etc -cp package/wifidog/files/wifidog.conf files/usr/etc/wifidog.conf - -6- Edit the files/usr/etc/wifidog.conf file for your authentication server settings. Also the GatewayInterface may need to be changed if you are not using a SOHO router configuration (eth0 for SOHO router, ath0 for router) - -7- Make the os - -make world V=99 - -8- Your new image should be available in the openwrt/bin directory as XM.v5.2....bin diff --git a/contrib/build-deb/changelog b/contrib/build-deb/changelog deleted file mode 100755 index d0274250..00000000 --- a/contrib/build-deb/changelog +++ /dev/null @@ -1,14 +0,0 @@ -wifidog (1.0.0-1) stable; urgency=low - - * New init.d file. - * Inclu - * debian/rules: Configuration and init.d file added. - * Bump version in anticipation for release - - -- Guillaume Beaudoin Sun, 29 Aug 2004 23:14:12 -0400 - -wifidog (0.2.0-1) stable; urgency=low - - * Initial Package - - -- Philippe April Wed, 21 Jul 2004 15:22:50 -0500 diff --git a/contrib/build-deb/control b/contrib/build-deb/control deleted file mode 100755 index 330f63af..00000000 --- a/contrib/build-deb/control +++ /dev/null @@ -1,15 +0,0 @@ -Source: wifidog -Section: net -Priority: optional -Maintainer: Philippe April - -Package: wifidog -Architecture: any -Depends: iptables, modutils, grep, mawk | awk -Provides: libhttpd -Description: The WiFi Guard Dog client - The WiFi Gaurd Dog project is a complete and embeddable captive portal - solution for wireless community groups or individuals who wish to open - a free HotSpot while still preventing abuse of their Internet connection. - . - This package contains only the client part. diff --git a/contrib/build-deb/rules b/contrib/build-deb/rules deleted file mode 100755 index 45291ed2..00000000 --- a/contrib/build-deb/rules +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/make -f - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -build: build-stamp -build-stamp: - dh_testdir - - ./configure --prefix=/usr - $(MAKE) - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - - -$(MAKE) clean - -$(MAKE) distclean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install - mkdir -p $(CURDIR)/debian/tmp/etc - cp wifidog.conf $(CURDIR)/debian/tmp/etc - cp scripts/init.d/wifidog debian/wifidog.init - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs -# dh_installexamples -# dh_install -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installcatalogs -# dh_installpam -# dh_installmime - dh_installinit -# dh_installcron -# dh_installinfo -# dh_undocumented - dh_installman - dh_link - dh_strip - dh_compress - dh_fixperms -# dh_perl -# dh_python - dh_makeshlibs - dh_installdeb -# dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/Makefile b/contrib/build-openwrt-kamikazeipk/wifidog/Makefile deleted file mode 100755 index adec69eb..00000000 --- a/contrib/build-openwrt-kamikazeipk/wifidog/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright (C) 2006,2008 OpenWrt.org -# Copyright (C) 2008 Technologies Coeus inc. -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -# $Id$ - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_MD5SUM:= - -PKG_FIXUP = libtool - -include $(INCLUDE_DIR)/package.mk - -define Package/wifidog - SUBMENU:=Captive Portals - SECTION:=net - CATEGORY:=Network - DEPENDS:=+kmod-ipt-extra +iptables-mod-extra +kmod-ipt-ipopt +iptables-mod-ipopt +kmod-ipt-nat +iptables-mod-nat +libpthread - TITLE:=A wireless captive portal solution - URL:=http://www.wifidog.org -endef - -define Package/wifidog/description - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. -endef - -define Package/wifidog/conffiles -/etc/wifidog.conf -endef - -MAKE_FLAGS += \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - -define Package/wifidog/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog -endef - -$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init deleted file mode 100755 index 68d4eea6..00000000 --- a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org -START=65 -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Print the status of the service" - - -start() { - /usr/bin/wifidog-init start -} - -stop() { - /usr/bin/wifidog-init stop -} - -status() { - /usr/bin/wifidog-init status -} \ No newline at end of file diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf deleted file mode 100755 index c905f04c..00000000 --- a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf +++ /dev/null @@ -1,246 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface br-lan - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init deleted file mode 100755 index 1cbbafda..00000000 --- a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org -START=65 -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Print the status of the service" - -start() { - /usr/bin/wifidog-init start -} - -stop() { - /usr/bin/wifidog-init stop -} - -status() { - /usr/bin/wifidog-init status -} diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/Config.in b/contrib/build-openwrt-whiterussianipk/wifidog/Config.in deleted file mode 100755 index 7b67874b..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/Config.in +++ /dev/null @@ -1,16 +0,0 @@ -config BR2_PACKAGE_WIFIDOG - prompt "wifidog........................... A wireless captive portal solution" - tristate - default m if CONFIG_DEVEL - select BR2_PACKAGE_LIBPTHREAD - select BR2_PACKAGE_IPTABLES - select BR2_PACKAGE_IPTABLES_MOD_NAT - select BR2_PACKAGE_IPTABLES-MOD_IPOPT - help - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. - - http://dev.wifidog.org/ - diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/Makefile b/contrib/build-openwrt-whiterussianipk/wifidog/Makefile deleted file mode 100755 index 42df3f22..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# $Id: $ -ifndef TOPDIR - ERR := $(Please set TOPDIR to OpenWRT SDK's buildroot) -endif - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 -PKG_MD5SUM:= - -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_CAT:=zcat -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) -PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install -include $(TOPDIR)/package/rules.mk -$(eval $(call PKG_template,WIFIDOG,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH))) -$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared - (cd $(PKG_BUILD_DIR); \ - $(TARGET_CONFIGURE_OPTS) \ - CFLAGS="$(TARGET_CFLAGS)" \ - CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \ - LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \ - ./configure \ - --target=$(GNU_TARGET_NAME) \ - --host=$(GNU_TARGET_NAME) \ - --build=$(GNU_HOST_NAME) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --without-libiconv-prefix \ - --without-libintl-prefix \ - --disable-nls \ - ); - ## Add software specific configurable options above - ## See : ./configure --help - touch $@ - -$(PKG_BUILD_DIR)/.built: - $(MAKE) -C $(PKG_BUILD_DIR) \ - $(TARGET_CONFIGURE_OPTS) - mkdir -p $(PKG_INSTALL_DIR) - $(MAKE) -C $(PKG_BUILD_DIR) \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - touch $@ - -$(IPKG_WIFIDOG): - install -m0755 -d $(IDIR_WIFIDOG)/etc/init.d - install -m0755 ./files/$(PKG_NAME).init $(IDIR_WIFIDOG)/etc/init.d/S65wifidog - install -m0644 ./files/wifidog.conf $(IDIR_WIFIDOG)/etc/ - install -m0644 $(PKG_BUILD_DIR)/wifidog-msg.html $(IDIR_WIFIDOG)/etc/ - install -m0755 -d $(IDIR_WIFIDOG)/usr/bin - install -m0755 -d $(IDIR_WIFIDOG)/usr/lib - install -m0755 $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(IDIR_WIFIDOG)/usr/bin/wifidog-init - $(CP) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(IDIR_WIFIDOG)/usr/bin/ - $(CP) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(IDIR_WIFIDOG)/usr/bin/ - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(IDIR_WIFIDOG)/usr/lib/ - $(RSTRIP) $(IDIR_WIFIDOG) - $(IPKG_BUILD) $(IDIR_WIFIDOG) $(PACKAGE_DIR) -mostlyclean: - make -C $(PKG_BUILD_DIR) clean - rm $(PKG_BUILD_DIR)/.built -all: $(IPKG_WIFIDOG) \ No newline at end of file diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf deleted file mode 100755 index c275b887..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf +++ /dev/null @@ -1,246 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface br0 - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init deleted file mode 100755 index 44a272a6..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org -START=50 - -start() { - /usr/bin/wifidog-init start -} - -stop() { - /usr/bin/wifidog-init stop -} - -status() { - /usr/bin/wifidog-init status -} \ No newline at end of file diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles deleted file mode 100755 index aaa3dd14..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/wifidog.conf diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control deleted file mode 100755 index dcf25e87..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control +++ /dev/null @@ -1,8 +0,0 @@ -Package: wifidog -Priority: optional -Section: net -Depends: libpthread, iptables, iptables-mod-nat, iptables-mod-ipopt -Description: WiFiDog is a complete and embeddable captive portal - solution for wireless community groups or individuals who - wish to open a free Hotspot while still preventing abuse - of their Internet connection. diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile b/contrib/wifidog/Makefile old mode 100755 new mode 100644 similarity index 59% rename from contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile rename to contrib/wifidog/Makefile index 3be5dbbf..e0aa7c2f --- a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -8,22 +8,27 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wifidog -PKG_VERSION:=20090925 +#PKG_VERSION:=gateway +PKG_VERSION:=20140822 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_MD5SUM:= +#PKG_MD5SUM:=b992869cb6607d89362f2fc09a727af9 +PKG_MD5SUM:=7241d86b46bbfeef54fb72e48a56dc8c -PKG_FIXUP = libtool +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 include $(INCLUDE_DIR)/package.mk define Package/wifidog SUBMENU:=Captive Portals - SECTION:=net - CATEGORY:=Network - DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +iptables-mod-nat +iptables-mod-nat-extra +libpthread + SECTION:=wifidog + CATEGORY:=Wifidog +# SECTION:=net +# CATEGORY:=Network + DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +kmod-ipt-nat +iptables-mod-nat-extra +libpthread TITLE:=A wireless captive portal solution URL:=http://www.wifidog.org endef @@ -39,19 +44,21 @@ define Package/wifidog/conffiles /etc/wifidog.conf endef -MAKE_FLAGS += \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - define Package/wifidog/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_settings.sh $(1)/usr/bin/GET_settings + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/dog_conf_generator.sh $(1)/usr/bin/dog_conf_generator + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/white_black_flush.sh $(1)/usr/bin/white_black_flush $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/wifidog.conf.bak + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/conf/* $(1)/etc/config/ $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/ $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf b/contrib/wifidog/files/wifidog.conf old mode 100755 new mode 100644 similarity index 88% rename from contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf rename to contrib/wifidog/files/wifidog.conf index c905f04c..fa6ec558 --- a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf +++ b/contrib/wifidog/files/wifidog.conf @@ -1,4 +1,4 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# $Id$ # WiFiDog Configuration file # Parameter: GatewayID @@ -29,7 +29,7 @@ # Mandatory # # Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) # and eth1, wlan0, ath0, etc. otherwise # You can get this interface with the ifconfig command and finding your wifi interface @@ -167,6 +167,37 @@ ClientTimeout 5 # through without authentication #TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + + +# Parameter: WhiteList +# Default: none +# Optional +# Comma separated list of url who are allowed to pass +# through router +#WhiteList www.baidu.com,www.taobao.com + +# Parameter: BlackList +# Default: none +# Optional +# Comma separated list of url who are not allowed to pass +# through router +#BlackList www.av123.com,www.av456.com + # Parameter: FirewallRuleSet # Default: none # Mandatory @@ -182,6 +213,10 @@ ClientTimeout 5 # # Used for rules to be applied to all other rulesets except locked. FirewallRuleSet global { + + # FirewallRule syntax: + # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X]] [to IP/CIDR] + ## To block SMTP out, as it's a tech support nightmare, and a legal liability #FirewallRule block tcp port 25 @@ -197,10 +232,10 @@ FirewallRuleSet global { #FirewallRule allow udp to 69.90.89.192/27 #FirewallRule allow udp to 69.90.85.0/27 #FirewallRule allow tcp port 80 to 69.90.89.205 - + ## Use the following to log or ulog the traffic you want to allow or block. # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). # Note: the log or ulog rule must be passed before, the rule you want to match. # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies # iptables-mod-extra and iptables-mod-ulog diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init new file mode 100644 index 00000000..31a4406a --- /dev/null +++ b/contrib/wifidog/files/wifidog.init @@ -0,0 +1,32 @@ +#!/bin/sh /etc/rc.common +# wifidog start on boot +#2015-08-12 +# + +START=99 + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print the status of the service" + + +start() { + /usr/bin/dog_conf_generator & + sleep 1 + /usr/bin/wifidog-init start + sleep 1 + /usr/bin/white_black_flush & +} + +stop() { + /usr/bin/wifidog-init stop + sleep 1 + rst=`ps | grep white_black | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi +} + +status() { + /usr/bin/wifidog-init status +} + diff --git a/scripts/GET_settings b/scripts/GET_settings.sh similarity index 100% rename from scripts/GET_settings rename to scripts/GET_settings.sh diff --git a/scripts/auth.sh b/scripts/auth.sh new file mode 100755 index 00000000..492a392b --- /dev/null +++ b/scripts/auth.sh @@ -0,0 +1,25 @@ +#!/bin/sh +#live-8 empire.x@qq.com 20150513 + +hostname=`uci get wifidog.wifidog.gateway_hostname` +#DATE=`date +%Y-%m-%d-%H:%M:%S` +sum=0 +#echo --- 开始检查 --- +while [[ $sum -lt 3 ]] +do + if /bin/ping -c 1 $hostname >/dev/null + then +#echo --- æœå¡å™¨å¯è¿æ¥ï¼Œå†åˆ¤æ–­è¿›ç¨‹æ˜¯å¦å­˜åœ¨ï¼Œè¿›å…¥è¿›ç¨‹å®ˆæ¤å·¥ä½œ --- + ps | grep wifidog | grep -v grep | grep wifidog && echo wifidog-Running.... || /etc/init.d/wifidog start + + uci get wifidog.wifidog.wifidog_enable | grep '0' && echo "" > /usr/lm/script/wifidogcron.sh + + exit 0 + fi + sum=$((sum+1)) +# sleep 1 +done + ps | grep wifidog | grep -v grep | grep wifidog && /etc/init.d/wifidog stop + + uci get wifidog.wifidog.wifidog_enable | grep '0' && echo "" > /usr/lm/script/wifidogcron.sh + diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf index 46c165ba..9dd1a3eb 100644 --- a/scripts/conf/dog_post_conf +++ b/scripts/conf/dog_post_conf @@ -1,7 +1,7 @@ config dog_post 'url' - option 'info_url' 'http://118.118.118.8:8080/WiFiAuth/wifidog/result' - option 'normal_url' 'http://118.118.118.8:8080/WiFiAuth/wifidog/result' + option 'info_url' 'http://108.108.108.7:8080/WiFiAuth/wifidog/result' + option 'normal_url' 'http://108.108.108.7:8080/WiFiAuth/wifidog/result' config dog_post 'rmflag' option 'info_rmflag' 'result' diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index 66c74800..f5dd3468 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -1,7 +1,7 @@ package 'wifidog_conf' config 'wifidog_conf' 'single' - option gatewayId 'GatewayID wifiauth_001' + option gatewayId '#GatewayID default is mac addr' option externalInterface '# ExternalInterface eth0' option gatewayInterface 'GatewayInterface br-lan' option gatewayAddress '# GatewayAddress 192.168.1.1' @@ -10,7 +10,7 @@ config 'wifidog_conf' 'single' option gatewayPort '# GatewayPort 2060' option proxyPort '# ProxyPort 0' option httpdName '# HTTPDName WiFiDog' - option httpdMaxConn '# HTTPDMaxConn' + option httpdMaxConn '# HTTPDMaxConn 120' option httpdRealm '# HTTPDRealm WiFiDog' option httpdUserName '# HTTPDUserName admin' option httpdPassword '# HTTPDPassword secret' @@ -19,7 +19,7 @@ config 'wifidog_conf' 'single' config 'wifidog_conf' 'authServer' - option 'hostname' 'Hostname 118.118.118.8' + option 'hostname' 'Hostname 108.108.108.7' option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' option 'sslPort' '# SSLPort (Optional;Default:443)' option 'httpPort' 'HTTPPort 8080' @@ -37,7 +37,6 @@ config 'wifidog_conf' 'trustedMACList' config 'wifidog_conf' 'untrustedMACList' option 'enable' '1' - list 'UntrustedMACList' 'a0:ec:80:ba:90:dc' list 'UntrustedMACList' 'aa:bb:cc:dd:ee:ff' diff --git a/scripts/white_black_flush.sh b/scripts/white_black_flush.sh new file mode 100755 index 00000000..c951267b --- /dev/null +++ b/scripts/white_black_flush.sh @@ -0,0 +1,86 @@ +#!/bin/sh + + +RUN_DOG_PID=`pidof wifidog` +GATEWAY_INTERFACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $NF}') +WHITE_LIST_URL=$(uci get wifidog_conf.whiteBlackList.WhiteList) +BLACK_LIST_URL=$(uci get wifidog_conf.whiteBlackList.BlackList) + +#touch files +mkdir -p /tmp/.white_black_list + +#compare +while [ true ] +do + + WHITE_LIST_URL=$(uci get wifidog_conf.whiteBlackList.WhiteList) + BLACK_LIST_URL=$(uci get wifidog_conf.whiteBlackList.BlackList) + + #detect + iptables -t nat -L WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -n --line-numbers | awk '{for(i=6;i /tmp/.white_black_list/.white_list + iptables -t mangle -L WiFiDog_"$GATEWAY_INTERFACE"_BlackList -n --line-numbers | awk '{for(i=6;i /tmp/.white_black_list/.black_list + + rm /tmp/.white_black_list/.white_list_tmp + for white_list in $WHITE_LIST_URL + do + nslookup $white_list | sed "1d" | sed "1d" | sed "1d" | sed "1d" | awk '{for(i=3;i> /tmp/.white_black_list/.white_list_tmp + done + invalid=`grep -e ".*0\.0\..*" /tmp/.white_black_list/.white_list_tmp -rn|cut -d : -f 1` + [ $invalid ] && sed -r -i "/"$invalid/"d" /tmp/.white_black_list/.white_list_tmp + + rm /tmp/.white_black_list/.black_list_tmp + for black_list in $BLACK_LIST_URL + do + nslookup $black_list |sed "1d"|sed "1d" |sed "1d" |sed "1d"|awk '{for(i=3;i> /tmp/.white_black_list/.black_list_tmp + done + invalid=`grep -e ".*0\.0\..*" /tmp/.white_black_list/.black_list_tmp -rn|cut -d : -f 1` + [ $invalid ] && sed -r -i "/"$invalid/"d" /tmp/.white_black_list/.black_list_tmp + + #white + while read line_new + do + i=0 + + while read line_old + do + if [ "$line_new" != "$line_old" ]; then + i=1 + else + i=0 + break + fi + done < /tmp/.white_black_list/.white_list + + if [ "$i" -eq "1" ]; then + iptables -t nat -A WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -d "$line_new" -j ACCEPT + iptables -t filter -A WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -d "$line_new" -j ACCEPT + #echo "-------------------------------------------------------------------------------limeng white diff -------------------------------------------------------------------------" + fi + done < /tmp/.white_black_list/.white_list_tmp + + sleep 10 + + #black + while read line_new + do + i=0 + + while read line_old + do + if [ "$line_new" != "$line_old" ]; then + i=1 + else + i=0 + break + fi + done < /tmp/.white_black_list/.black_list + + if [ "$i" -eq "1" ]; then + iptables -t mangle -A WiFiDog_"$GATEWAY_INTERFACE"_BlackList -d "$line_new" -j DROP + #echo "-------------------------------------------------------------------------------limeng black diff -------------------------------------------------------------------------" + fi + done < /tmp/.white_black_list/.black_list_tmp + + sleep 10 +done + diff --git a/scripts/wifidog.init b/scripts/wifidog.init deleted file mode 100644 index 3e978c4f..00000000 --- a/scripts/wifidog.init +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/sh /etc/rc.common -#å“微科æ€ï¼ limeng -#2014.08.22 - -START=65 - -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Print the status of the service" - -config_load() -{ - rm -f /etc/wifidog.conf - gateway_id=$(uci get wifidog.@wifidog[0].gateway_id) - gateway_interface=$(uci get wifidog.@wifidog[0].gateway_interface) - gateway_eninterface=$(uci get wifidog.@wifidog[0].gateway_eninterface) - gateway_hostname=$(uci get wifidog.@wifidog[0].gateway_hostname) - gateway_httpport=$(uci get wifidog.@wifidog[0].gateway_httpport) - gateway_path=$(uci get wifidog.@wifidog[0].gateway_path) - gateway_connmax=$(uci get wifidog.@wifidog[0].gateway_connmax) - ssl_enable=$(uci get wifidog.@wifidog[0].ssl_enable) - check_interval=$(uci get wifidog.@wifidog[0].check_interval) - client_timeout=$(uci get wifidog.@wifidog[0].client_timeout) - sslport=$(uci get wifidog.@wifidog[0].sslport) - deamo_enable=$(uci get wifidog.@wifidog[0].deamo_enable) - white_black_enable=$(uci get wifidog.@wifidog[0].white_black_enable) - gatewayport=$(uci get wifidog.@wifidog[0].gatewayport) - myz_mac=$(uci get wifidog.@wifidog[0].myz_mac) - tbmd_url=$(uci get wifidog.@wifidog[0].bmd_url) - thmd_url=$(uci get wifidog.@wifidog[0].hmd_url) - bmd_url=`echo $tbmd_url | tr " " ","` - hmd_url=`echo $thmd_url | tr " " ","` - -echo " -GatewayID $gateway_id -GatewayInterface $gateway_interface -ExternalInterface $gateway_eninterface -AuthServer { - Hostname $gateway_hostname - SSLAvailable $ssl_enable - SSLPort $sslport - HTTPPort $gateway_httpport - Path $gateway_path - } -Daemon $deamo_enable -GatewayPort $gatewayport -CheckInterval $check_interval -ClientTimeout $client_timeout -HTTPDMaxConn $gateway_connmax -TrustedMACList $myz_mac -WhiteList $bmd_url -BlackList $hmd_url - -FirewallRuleSet global { -FirewallRule allow to 61.139.2.69 -FirewallRule allow to 8.8.8.8 -FirewallRule allow to 114.114.114.114 -} -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} -" >> /etc/wifidog.conf -} - -start() { - wifidog_enable=$(uci get wifidog.@wifidog[0].wifidog_enable) - stop; - [ "$wifidog_enable" -eq 0 ] && exit 0 - sleep 1 - config_load - /usr/bin/wifidog-init start - if [ "$white_black_enable" -eq 1 ]; then - sleep 1 - /usr/lm/script/white_black_flush.sh & - fi -} - -stop() { - /usr/bin/wifidog-init stop - sleep 1 - rst=`ps | grep white_black | cut -d "r" -f 1` - if [ -n "$rst" ]; then - kill -9 $rst - fi -} - -status() { - /usr/bin/wifidog-init status -} - From 0079aeddc5a3b41583973b68e0fa539bcc686587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=20=E9=AB=98=E6=98=8E?= Date: Thu, 13 Aug 2015 13:18:42 +0800 Subject: [PATCH 05/33] flag the version number --- configure.in | 2 +- contrib/wifidog/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index cdc818c3..4bf10f46 100755 --- a/configure.in +++ b/configure.in @@ -21,7 +21,7 @@ AC_SUBST(BUILDROOT) WIFIDOG_MAJOR_VERSION=1 WIFIDOG_MINOR_VERSION=1 WIFIDOG_MICRO_VERSION=5 -WIFIDOG_VERSION=20140822 +WIFIDOG_VERSION=20140822-v1.0.0 AC_SUBST(WIFIDOG_MAJOR_VERSION) AC_SUBST(WIFIDOG_MINOR_VERSION) diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile index e0aa7c2f..71742c12 100644 --- a/contrib/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -23,7 +23,7 @@ PKG_INSTALL:=1 include $(INCLUDE_DIR)/package.mk define Package/wifidog - SUBMENU:=Captive Portals +# SUBMENU:=Captive Portals SECTION:=wifidog CATEGORY:=Wifidog # SECTION:=net From 3c8912cd77eebfe0425cb59733966398259d0805 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=20=E9=AB=98=E6=98=8E?= Date: Fri, 14 Aug 2015 14:47:59 +0800 Subject: [PATCH 06/33] add DeviceKey in ping header and auth header. --- contrib/wifidog/Makefile | 2 ++ scripts/etc/devicekey | 6 +++++ src/Makefile.am | 6 +++-- src/centralserver.c | 12 +++++++-- src/device_key.c | 55 ++++++++++++++++++++++++++++++++++++++++ src/device_key.h | 19 ++++++++++++++ src/gateway.c | 10 ++++++-- src/get_remote_shell.c | 16 ++++++------ src/ping_thread.c | 8 ++++-- 9 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 scripts/etc/devicekey create mode 100644 src/device_key.c create mode 100644 src/device_key.h diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile index 71742c12..f420c854 100644 --- a/contrib/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -60,6 +60,8 @@ define Package/wifidog/install $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/conf/* $(1)/etc/config/ $(INSTALL_DIR) $(1)/etc $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/etc/devicekey $(1)etc/.devicekey $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog endef diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey new file mode 100644 index 00000000..5e3369b8 --- /dev/null +++ b/scripts/etc/devicekey @@ -0,0 +1,6 @@ +######################################################## +# +# this file is the device key, do NOT modify it. +# +######################################################## +ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 7fc90f17..ca180b39 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,7 +34,8 @@ wifidog_SOURCES = commandline.c \ httpd_thread.c \ get_devinfo.c \ get_clientinfo.c \ - get_remote_shell.c + get_remote_shell.c \ + device_key.c noinst_HEADERS = commandline.h \ common.h \ @@ -56,6 +57,7 @@ noinst_HEADERS = commandline.h \ shell_command.h \ get_devinfo.h \ get_clientinfo.h \ - get_remote_shell.h + get_remote_shell.h \ + device_key.h wdctl_SOURCES = wdctl.c diff --git a/src/centralserver.c b/src/centralserver.c index 082460ca..31a39b21 100755 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -55,6 +55,8 @@ * include my header file. */ #include "get_clientinfo.h" +#include "device_key.h" + extern pthread_mutex_t client_list_mutex; extern pthread_mutex_t config_mutex; @@ -134,6 +136,7 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" + "DeviceKey: %s\r\n" "\r\n", auth_server->authserv_path, auth_server->authserv_auth_script_path_fragment, @@ -156,7 +159,9 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons /**************************/ VERSION, - auth_server->authserv_hostname + auth_server->authserv_hostname, + /* device key*/ + get_device_key() ); } else @@ -165,6 +170,7 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" + "DeviceKey: %s\r\n" "\r\n", auth_server->authserv_path, auth_server->authserv_auth_script_path_fragment, @@ -188,7 +194,9 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons /**************************/ VERSION, - auth_server->authserv_hostname + auth_server->authserv_hostname, + /* device key*/ + get_device_key() ); } diff --git a/src/device_key.c b/src/device_key.c new file mode 100644 index 00000000..f9ebc668 --- /dev/null +++ b/src/device_key.c @@ -0,0 +1,55 @@ +/* + * device_key.c + * + * Created on: Aug 14, 2015 + * Author: GaomingPan + */ + +#include +#include +#include + +#include "device_key.h" + + +static char device_key[64] = {0}; + + + +char * get_device_key() +{ + return device_key; +} + + + + + +int init_device_key() +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t read_len; + + fp = fopen(DEVICE_KEY_FILE,"r"); + if(NULL == fp) + { + return -1; + } + while((read_len = getline(&line,&len,fp)) != -1) + { + if('#' == line[0] || ' ' == line[0] || '\t' == line[0]) + continue; + else + { + sprintf(device_key,"%s",line); + free(line); + fclose(fp); + return 0; + } + } + free(line); + fclose(fp); + return -2; +} diff --git a/src/device_key.h b/src/device_key.h new file mode 100644 index 00000000..872a4784 --- /dev/null +++ b/src/device_key.h @@ -0,0 +1,19 @@ +/* + * device_key.h + * + * Created on: Aug 14, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_DEVICE_KEY_H_ +#define SRC_DEVICE_KEY_H_ + + +#define DEVICE_KEY_FILE "/etc/.devicekey" + +char * get_device_key(); + + +int init_device_key(); + +#endif /* SRC_DEVICE_KEY_H_ */ diff --git a/src/gateway.c b/src/gateway.c index 978f2bf1..913a9e2b 100755 --- a/src/gateway.c +++ b/src/gateway.c @@ -62,6 +62,7 @@ #include "get_remote_shell.h" +#include "device_key.h" /** XXX Ugly hack * We need to remember the thread IDs of threads that simulate wait with pthread_cond_timedwait @@ -414,8 +415,13 @@ main_loop(void) /**** init my post url config *****/ if(0 != init_post_http_url_config() ) { - debug(LOG_ERR, "FATAL: Failed to initialize init_post_http_url_config"); - exit(1); + debug(LOG_ERR, "ERROR: Failed to initialize init_post_http_url_config"); + //exit(1); + } + /*init device key*/ + if(0 != init_device_key()) + { + debug(LOG_ERR,"ERROR:Failed to initalize device key."); } /*********************************/ diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c index 07036234..5d67787a 100644 --- a/src/get_remote_shell.c +++ b/src/get_remote_shell.c @@ -77,7 +77,7 @@ int init_post_http_url_config(void) pclose(fp); sprintf(normal_rmflag,"%s",buf); - printf("\ninit result:\n\t%s\n\t%s\n\t%s\n\t%\n\n", \ + debug(LOG_INFO,"init result :info_url:%s;info_rmflag:%s;normal_url:%s;normal_rmflag:%s", \ info_http_url,info_rmflag, \ normal_http_url,normal_rmflag ); @@ -93,12 +93,12 @@ int post_get_info_execut_output(char *cmd_output_path) char output[MAX_CMD_EXECUT_OUT_LEN]; FILE *fp; sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); - printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); + //printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); fp = popen(output,"r"); if(NULL == fp) { debug(LOG_ERR,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); - printf("ERROR: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); + //printf("ERROR: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); return -1; } pclose(fp); @@ -119,7 +119,7 @@ int post_normal_execut_output(char *gw_id, char *cmd_id) if(NULL == fp) { debug(LOG_ERR,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); - printf("ERROR: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); + //printf("ERROR: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); return -1; } pclose(fp); @@ -136,7 +136,7 @@ char *get_shell_command(char *cmdptr) if(NULL == cmdptr) { - printf("REMOTE shell: remote shell command is null.\n"); + debug(LOG_ERR,"REMOTE shell: remote shell command is null."); return NULL; } memset(remote_shell_cmd,0,REMOTE_SHELL_COMMAND_LEN); @@ -174,7 +174,7 @@ int excute_shell_command(char *gw_id,char *shellcmd) is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); - printf("\ncmd_id:%s\nget_inf_cmd:%s\nis_get_info:%d\n\n",cmd_id,get_info_cmd,is_get_info); + debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); if(0 == is_get_info) { @@ -187,12 +187,12 @@ int excute_shell_command(char *gw_id,char *shellcmd) fp = popen(normal_cmd,"r"); } - printf("\npos_cmd:\n\t%s\n\n",pos_cmd); + debug(LOG_INFO,"pos_cmd:%s",pos_cmd); if(NULL == fp) { debug(LOG_ERR,"excute_shell_command popen error...."); - printf("excute_shell_command popen error....\n"); + //printf("excute_shell_command popen error....\n"); return -1; } //fread(cmdresult,1024,1,fp); diff --git a/src/ping_thread.c b/src/ping_thread.c index 36616190..9f6b59bb 100755 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -55,8 +55,8 @@ /*@breif get device info. * GaomingPan*/ #include "get_devinfo.h" - #include "get_remote_shell.h" +#include "device_key.h" static void ping(void); @@ -173,6 +173,7 @@ ping(void) "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%d&come_speed=%d&incoming=%ld&outgoing=%ld HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" + "DeviceKey: %s\r\n" "\r\n", auth_server->authserv_path, auth_server->authserv_ping_script_path_fragment, @@ -197,7 +198,10 @@ ping(void) /* ************ */ VERSION, - auth_server->authserv_hostname); + auth_server->authserv_hostname, + /* device key */ + get_device_key() + ); debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); From 44c22317940b3a9be300139e83766c42f7faf935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=20=E9=AB=98=E6=98=8E?= Date: Fri, 14 Aug 2015 16:26:12 +0800 Subject: [PATCH 07/33] seconds init. --- .cproject | 49 ++ .project | 27 + AUTHORS | 6 + COPYING | 280 ++++++ ChangeLog | 898 +++++++++++++++++++ FAQ | 488 +++++++++++ Makefile.am | 53 ++ NEWS | 116 +++ README | 16 + README.openwrt | 96 +++ autogen.sh | 65 ++ configure.in | 105 +++ contrib/dump_fw.sh | 5 + contrib/wifidog/Makefile | 69 ++ contrib/wifidog/files/wifidog.conf | 281 ++++++ contrib/wifidog/files/wifidog.init | 32 + doc/Makefile.am | 52 ++ doc/README.developers.txt | 37 + doc/doxygen.cfg.in | 1294 ++++++++++++++++++++++++++++ doc/wifidog_firewall_diagram.dia | Bin 0 -> 8702 bytes libhttpd/Makefile.am | 19 + libhttpd/README | 23 + libhttpd/api.c | 1067 +++++++++++++++++++++++ libhttpd/httpd.h | 250 ++++++ libhttpd/httpd_priv.h | 83 ++ libhttpd/ip_acl.c | 224 +++++ libhttpd/protocol.c | 791 +++++++++++++++++ libhttpd/version.c | 23 + scripts/GET_settings.sh | 48 ++ scripts/auth.sh | 25 + scripts/conf/dog_post_conf | 9 + scripts/conf/wifidog_conf | 72 ++ scripts/dog_conf_generator.sh | 167 ++++ scripts/etc/devicekey | 6 + scripts/init.d/wifidog | 201 +++++ scripts/white_black_flush.sh | 86 ++ src/Makefile.am | 63 ++ src/auth.c | 224 +++++ src/auth.h | 61 ++ src/centralserver.c | 454 ++++++++++ src/centralserver.h | 63 ++ src/client_list.c | 258 ++++++ src/client_list.h | 100 +++ src/commandline.c | 180 ++++ src/commandline.h | 33 + src/common.h | 33 + src/conf.c | 1044 ++++++++++++++++++++++ src/conf.h | 244 ++++++ src/debug.c | 76 ++ src/debug.h | 38 + src/device_key.c | 55 ++ src/device_key.h | 19 + src/firewall.c | 424 +++++++++ src/firewall.h | 70 ++ src/fw_iptables.c | 720 ++++++++++++++++ src/fw_iptables.h | 82 ++ src/gateway.c | 582 +++++++++++++ src/gateway.h | 33 + src/get_clientinfo.c | 443 ++++++++++ src/get_clientinfo.h | 89 ++ src/get_devinfo.c | 459 ++++++++++ src/get_devinfo.h | 119 +++ src/get_remote_shell.c | 213 +++++ src/get_remote_shell.h | 35 + src/http.c | 331 +++++++ src/http.h | 50 ++ src/httpd_thread.c | 75 ++ src/httpd_thread.h | 33 + src/ping_thread.c | 288 +++++++ src/ping_thread.h | 35 + src/safe.c | 110 +++ src/safe.h | 56 ++ src/shell_command.h | 53 ++ src/util.c | 544 ++++++++++++ src/util.h | 79 ++ src/wdctl.c | 327 +++++++ src/wdctl.h | 43 + src/wdctl_thread.c | 402 +++++++++ src/wdctl_thread.h | 37 + wifidog-msg.html.in | 107 +++ wifidog.conf | 281 ++++++ wifidog.spec.in | 69 ++ 82 files changed, 16197 insertions(+) create mode 100644 .cproject create mode 100644 .project create mode 100755 AUTHORS create mode 100755 COPYING create mode 100755 ChangeLog create mode 100755 FAQ create mode 100755 Makefile.am create mode 100755 NEWS create mode 100755 README create mode 100755 README.openwrt create mode 100755 autogen.sh create mode 100755 configure.in create mode 100755 contrib/dump_fw.sh create mode 100644 contrib/wifidog/Makefile create mode 100644 contrib/wifidog/files/wifidog.conf create mode 100644 contrib/wifidog/files/wifidog.init create mode 100755 doc/Makefile.am create mode 100755 doc/README.developers.txt create mode 100755 doc/doxygen.cfg.in create mode 100755 doc/wifidog_firewall_diagram.dia create mode 100755 libhttpd/Makefile.am create mode 100755 libhttpd/README create mode 100755 libhttpd/api.c create mode 100755 libhttpd/httpd.h create mode 100755 libhttpd/httpd_priv.h create mode 100755 libhttpd/ip_acl.c create mode 100755 libhttpd/protocol.c create mode 100755 libhttpd/version.c create mode 100755 scripts/GET_settings.sh create mode 100755 scripts/auth.sh create mode 100644 scripts/conf/dog_post_conf create mode 100644 scripts/conf/wifidog_conf create mode 100644 scripts/dog_conf_generator.sh create mode 100644 scripts/etc/devicekey create mode 100755 scripts/init.d/wifidog create mode 100755 scripts/white_black_flush.sh create mode 100755 src/Makefile.am create mode 100755 src/auth.c create mode 100755 src/auth.h create mode 100755 src/centralserver.c create mode 100755 src/centralserver.h create mode 100755 src/client_list.c create mode 100755 src/client_list.h create mode 100755 src/commandline.c create mode 100755 src/commandline.h create mode 100755 src/common.h create mode 100755 src/conf.c create mode 100755 src/conf.h create mode 100755 src/debug.c create mode 100755 src/debug.h create mode 100644 src/device_key.c create mode 100644 src/device_key.h create mode 100755 src/firewall.c create mode 100755 src/firewall.h create mode 100755 src/fw_iptables.c create mode 100755 src/fw_iptables.h create mode 100755 src/gateway.c create mode 100755 src/gateway.h create mode 100644 src/get_clientinfo.c create mode 100644 src/get_clientinfo.h create mode 100644 src/get_devinfo.c create mode 100644 src/get_devinfo.h create mode 100644 src/get_remote_shell.c create mode 100644 src/get_remote_shell.h create mode 100755 src/http.c create mode 100755 src/http.h create mode 100755 src/httpd_thread.c create mode 100755 src/httpd_thread.h create mode 100755 src/ping_thread.c create mode 100755 src/ping_thread.h create mode 100755 src/safe.c create mode 100755 src/safe.h create mode 100644 src/shell_command.h create mode 100755 src/util.c create mode 100755 src/util.h create mode 100755 src/wdctl.c create mode 100755 src/wdctl.h create mode 100755 src/wdctl_thread.c create mode 100755 src/wdctl_thread.h create mode 100755 wifidog-msg.html.in create mode 100755 wifidog.conf create mode 100755 wifidog.spec.in diff --git a/.cproject b/.cproject new file mode 100644 index 00000000..e2b2aaa0 --- /dev/null +++ b/.cproject @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 00000000..7785dd6f --- /dev/null +++ b/.project @@ -0,0 +1,27 @@ + + + wifidog-20140822 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 00000000..52177b0c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,6 @@ +$Id$ + +Philippe April +Mina Naguib +Benoit Grégoire +Alexandre Carmel-Veilleux diff --git a/COPYING b/COPYING new file mode 100755 index 00000000..c7aea189 --- /dev/null +++ b/COPYING @@ -0,0 +1,280 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/ChangeLog b/ChangeLog new file mode 100755 index 00000000..31f0cc7f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,898 @@ +# $Id$ +2015-07-13 + * add get_clientinfo.h get_clientinfo.c +2015-07-09 + * add shell_command.h + * add get_devinfo.h get_devinfo.c +2014-05-13 + * libhttpd crash on invalid HTTP headers (second part of the patch) by Benoit GrĂ©goire +2013-08-21 + * add support for DROP target for firewall rules by Champtar +2013-06-14 + * add support for log, ulog target for firewall rules by jean-philippe menil and florida +2013-05-31 + Add transparent proxy support (via iptables REDIRECT) by Champtar (inspired by FFW team) +2012-05-30 + * Add many const by champtar + * Send http 302 instead of 307 by champtar + * Suppress all compilation warnings by champtar + * Add transparent proxy support (via iptables REDIRECT) +2012-08-28 + * Fix #836, buffer overflow on long urls reported by Etienne CHAMPETIER + * Fix #835, segfaults reported by Etienne CHAMPETIER +2009-11-03 + * Fix #625, does not display failure notice when quiet is set to true + * Fix #587, change index and rindex to strchr and strrchr + * Fix #548, trim leading spaces of the config file's options + +2009-09-28 Benoit GrĂ©goire + * Fix #471, patch by wichert + +2009-09-25 Geneviève Bastien + * Release 20090925 + * Update contrib Makefiles + +2009-09-17 Geneviève Bastien + * Documented #537 + * Fixed #472, patch by Jean-Philippe Menil + * Fixed #515, using the gateway interface instead of the gateway id in the iptables chain + +2009-07-02 Benoit GrĂ©goire + * Re-fix #505, #525 and fix #584, sorry about that. + +2009-06-26 Benoit GrĂ©goire + * Fix #518 + +2009-02-27 Benoit GrĂ©goire + * Fix #488 and #493 (arp_get() in firewall.c couldn't parse lowercase mac's from /proc/net/arp) with patch from jch@pps.jussieu.fr. Otherwise wifidog wouldn't work with recent openwrt and Ubuntu. + * Fix #525 + +2008-09-30 Wichert Akkerman + * Add exitcode to iptables failure errors. + * Include the gw_id in auth server updates so the client does not have + to keep track of it in a session. + * Include the gateway id in the firewall table names. Fixes ticket #466 + * URL encode the token before transmitting (it was already decoded). + Fixes ticket #473 + * Clean up compiler warnings. + * Security: strncpy may not NUL-terminate strings, so enforce this + ourselves. Fixes ticket #464 + * Make it possible to protect the status page. Fixes ticket #463. + +2008-07-20 Alexandre Carmel-Veilleux + * src/util.c: Fixed #include bug that caused segfaults on newer Linux + +2008-04-21 Alexandre Carmel-Veilleux + * Integrated patch #452 from Wichert Akkerman : Add const to function arguments in libhttpd to enforce more type checking and prevent certain class of problems. + * Compatiblity fix: Libhttpd assumes that type u_int is defined. Added an #ifndef/#include pair to httpd.h to make sure that assertion is true. + * Integrated patch #453 from Wichert Akkerman : Add configurable html to wifidog error messages. This has been a long-requested feature. + +2008-04-13 Benoit GrĂ©goire + * contrib/build-openwrt-kamikazeipk/wifidog/Makefile: Add iptables userspace dependencies + * Release 1.1.5 + +2008-03-24 Benoit GrĂ©goire + * Integrate with OpenWRT kamikaze build system + +2007-11-01 Benoit GrĂ©goire + * Apply portability patches by David Young . These have been reviewed, but not tested. + +2007-10-18 Benoit GrĂ©goire + * fw_iptables.c: From Philippe April: reverted change made in 1241 so we properly remove the entry from mangle.WiFiDog_Incoming when kicking out users, it was affecting statistics + * Update doxygen.cfg.in for latest version and to fix path ambiguity during make dist. + * Release 1.1.4 + +2007-07-06 Benoit GrĂ©goire + * Makefile.am: Slight change in make ipk tagrget. It seems that sometimes builddir isn't defined. srcdir works just as well in this case. + +2007-06-27 Benoit GrĂ©goire + * util.c: Fix while loop initialisation bug + * conf.h: Forgot to change the value of NUM_EXT_INTERFACE_DETECT_RETRY to actually make it wait forever. + * Remove hardcoded authserver paths. Can now be defined in the config file (auth server section). + * Centralise browser redirect code to simplify code + * Add manual logout URL, based in part on work by David Bird + * Release 1.1.3 final + +2007-06-24 Benoit GrĂ©goire + * Close #321: Make the Gateway retry forever if it cannot find it's interface. You never know when someone may finally replug the network cable or something... + * Close #332: Apply patch from Laurent Marchal. biguphpcgmailcom + * fw_iptables.c: Fix error in iptables_fw_access(). Rules were created as ACCEPT instead of DROP + * firewall.c: Fix bug in fw_sync_with_authserver(). The traffic for the validation period of a user who validated his account while connected wouldn't get counted. + * doc/wifidog_firewall_map.dia: At long last, full documentation of the firewall. We would have avoided a lot of stupid mistakes if we produced that sooner. + * Release 1.1.3_rc1 + +2007-05-24 Benoit GrĂ©goire + * wdctl_thread.c: Fix #324, again. Credit goes to Medea, I misunderstood his instructons. + * From David Bird libhttpd/: Fix #266 - don't process query string parameters and keep them in that request.path. + +2007-05-18 Benoit GrĂ©goire + * wdctl_thread.c: Fix #324 + +2007-04-26 Benoit GrĂ©goire + * wifidog.conf: Improve comments and add examples of blocking access to the upstream LAN. + +2007-04-26 Benoit GrĂ©goire + * conf.h: The DEFAULT_CHECKINTERVAL was 5 instead of 60 (as stated in the config file) which caused huge needless load on the auth servers, and needless ping traffic towards the clients if it wasn't manually set. + +2007-04-09 Benoit GrĂ©goire + * Makefile.am: Slight path fix when using building make ipk. Tell me if you have trouble with this + +2007-01-06 Benoit GrĂ©goire + * contrib/ Add contrib dir to collect the scripts and other code distributed with, but not really part of wifidog. + * Include the scripts used to build a ipkg on Openwrt RC6 and 0.9 + * Modify the build system to finally be able to build wifidog directly from the wifidog directory using the same files + used to make the official .ipk, without having to copy ANYTHNG to the openwrt SDK. + At last, there is now a new target: make ipk make ipk OPENWRTSDK=path_to_openwrt_sdk + * ipk/ Removed the obsolete OpenWRT RC4 scripts + * README.openwrt: Update + * scripts/openwrt/ remove obsolete dir. + * contrib/dump_fw.sh: Convenience script for firewall debugging. + +2007-01-06 Benoit GrĂ©goire + * Documentation update in the code + * Released 1.1.3_beta6 + +2006-10-26 Benoit GrĂ©goire + * src/conf.h: Fix #238 by using $sysconfdir to compute the default config-file location. + +2006-10-08 Alexandre Carmel-Veilleux + * Changed my email in a few files. + * Broken down some printf's on multiple lines. + * Added comments. + +2006-09-14 Benoit GrĂ©goire + * src/util.c, src/conf.h: Fix autodectection of the External interface if not specified in the config file. If the interface (typically pppoe) wasn't yet fully up when wifidog starts, wifidog would stop every connection from going trough. It will now retry every second for up to two minutes, and then exit with a fatal error if it can't successfully detect it. + +2006-02-23 Philippe April + * src/fw_iptables.c: + * Changed order in the filter.FORWARD chain + * Added TCPMSS rule + * Fixed deleting the rules on shutdown + * Fixed wdctl reset problem + * Released 1.1.3_beta4 + +2006-02-06 Benoit GrĂ©goire + * src/fw_iptables.c: Fix deleting the rules on shutdown. + +2006-01-31 Benoit GrĂ©goire + * Release 1.1.3_beta2 + +2006-01-31 Benoit GrĂ©goire + * src/fw_iptables.c: Add the global ruleset to the nat table to fix #65. + Add the table parameter to iptables_load_ruleset() and iptables_compile + * libhttpd/protocol.c: Fix pointer type mismatch + * src/conf.c,h: Remove deprecated option AuthServMaxTries (which was already ignored anyway. + +2006-01-23 Benoit GrĂ©goire + * src/conf.h: Fix the value of DEFAULT_AUTHSERVPATH and completely wrong code comment. Not the default indicated in the config file and the define are in sync. + +2006-01-17 Mina Naguib + * Ingisgnificant cleanup of CVS artifacts after svn migration + +2005-11-24 Philippe April + * Bad idea + +2005-11-01 Max Horvath + * Added .project to .cvsignore + +2005-11-01 Philippe April + * Added OPTIONS section in wifidog-init (example: enable syslog) + +2005-10-09 Philippe April + * Changed html pages, added info to wdctl status + +2005-10-07 Philippe April + * Released 1.1.3_beta1 + +2005-10-03 Philippe April + * libhttpd: Fixed two bugs parsing the GET query string making wifidog segfault + +2005-09-24 Mina Naguib + * New wdctl command "restart" which will get wifidog to restart itself + while preserving the existing clientlist. Perfect for 0-downtime + upgrading! + * safe.c: New safe_fork that croaks if the fork fails, also takes care of + closing some global file descriptors for the child + * debug.c: Now also logs the PID as part of every entry + * gateway.c: Handler for SIGCHLD now waitpid()s with WNOHANG flag to prevent deadlock + when the handler is called and another wait() or waitpid() is used + * util.c: execute() now uses waitpid() instead of wait() to reap only the child + it fork/executed + * Extra debugging entries throughout code + +2005-09-24 Mina Naguib + * conf.c: Pre-emptive bugfix - harsh lockdown of parsing trusted MAC + addresses from config file + +2005-09-24 Philippe April + * (finally) Added {Saul Albert,Jo Walsh,Schuyler}'s patch (thank you!) to send + the GW interface's mac address as the node_id if no node_id is specified. It allows + the use of generic configuration files without the need to hardcode the + node_id in. + * Added TrustedMACList configuration variable which allows specifying + MAC addresses which are allowed to go through without authentication. + * Updated OpenWrt instructions. + +2005-09-08 Philippe April + * Added compile instructions and installation for OpenWrt Whiterussian-rc2 + * Released 1.1.2 + +2005-05-30 Mina Naguib + * New wdctl command "restart" which will get wifidog to restart itself while preserving the existing clientlist. Perfect for 0-downtime upgrading! + * safe.c: New safe_fork that croaks if the fork fails, also takes care of closing some global file descriptors for the child + * debug.c: Now also logs the PID as part of every entry + * gateway.c: Handler for SIGCHLD now waitpid()s with WNOHANG flag to prevent deadlock when the handler is called and another wait() or waitpid() is used + * util.c: execute() now uses waitpid() instead of wait() to reap only the child it fork/executed + * Extra debugging entries throughout code + +2005-05-24 Mina Naguib + * wdctl.c: Minor bugfix pointed out by David Vincelli: When an invalid + command is given to wdctl, the error message showed "Invalid command: + wdctl" instead of the actual command supplied + +2005-05-23 Philippe April + * Released 1.1.2_pre1 + +2005-05-23 Mina Naguib + * fw_uptables.c: When appending call to chain WiFiDog_Outgoing from + nat.prerouting, add it via -A (at end) instead of -I 1 (at beginning) to + allow for existing nat forwarding. + +2005-05-16 Mina Naguib + * centralserver.c: read()s from central server in auth_server_request() are + now timed-out (via select). This is hopefully a bugfix to the + thread-freezing problem. + +2005-05-06 Mina Naguib + * Bugfix non-RFC compliant HTTP requests using \n instead of \r\n as line + terminations as per email from ludocornut@users.sourceforge.net + +2005-04-28 Philippe April + * Released 1.1.2_beta2 + +2005-04-28 Mina Naguib + * wifidog.conf: Make the default ruleset for validating users = allow all + (except sending SMTP) + +2005-04-20 Philippe April + * fw_iptables.c: Insert ourselves at the end of filter.FORWARD instead of + at the beginning since important FW instructions are located there on the + WRT54Gs when used with some DSL providers and we never execute them + otherwise. + * Released 1.1.2_beta1 + +2005-04-03 Philippe April + * Fixed issue with FAQ + * ipkg/rules: If autogen.sh doesn't exist, it's ok. 'configure' will. + +2005-04-01 Philippe April + * Duplicated auth server list in NAT table to fix the issue + of using an auth server on port 80, since port 80 was being systematically + redirected to 2060 otherwise. + * Released 1.1.1 + +2005-03-29 Mina Naguib + * Added FAQ document copied from wiki + +2005-03-22 Philippe April + * Released 1.1.0 + +2005-03-20 Mina Naguib + * More verbose debugging output + +2005-03-12 Mina Naguib + * More debugging output + * Document ugly hack involving tid_fw_thread + * SIGPIPE now ignored (as it's comment said) instead of being sent to the + handler for SIGCHLD + * Bugfix firewall destruction not happening from termination handler - had + to move explicit thread kills after, not before, firewall destruction + +2005-03-11 Mina Naguib + * If external interface was unspecified in the conf file, try to determine + it from the default route + * If external interface is known, specify it in the trigger rule in + nat.PREROUTING to prevent the rule from matching traffic inbound to the + router itself. This should fix the issue raised by Philippe and Pascal on + the mailing list + * Bugfix: UNDO ABOVE 2 ITEMS. Aparently you cannot use the "-o" iptables + option in nat.PREROUTING which makes knowing external_interface useless + * Added new chain in nat.PREROUTING that explicitly allows all traffic to + the router's internal IP from the internal interface, effectively + addressing the same above problem + +2005-03-07 Mina Naguib + * auth.c: Got rid of legacy _http_output and _http_redirect - replaced them + with libhttpd functions and http_wifidog_header/http_wifidog_footer + * auth.c: When re-directing to auth server now respects SSL setting instead + of always http+port 80 + * auth.c: Better debugging output of what it's doing when it acts on auth + server response + * A little bit more care with buffers and their sizes + * Minor whitespace tweaking and a couple of internal doc typo fixes + +2005-03-06 Mina Naguib + * Check return values of pthread_create + * Internal documentation touch-ups + * auth.c: Bugfix invalid http header sent by _http_output + * Bugfix traffic counter read from iptables as long int instead of long + long int + * Minor insignificant code touch-ups: + * Replace pthread_mutex_lock/unlock calls with appropriate + LOCK_FOO/UNLOCK_FOO macros for consistency + * Lock first before using some variables, not after + * Indentation adjustments + +2005-03-04 Mina Naguib + * Bugfix huge uptime pointed out to be by Philippe - was caused when the + date is set (with ntpclient for example) after wifidog starts + * Beautified "Uh oh!" apology screens and redirection screen + +2005-03-02 Alexandre Carmel-Veilleux + * Ifdef'd out the bits that are Linux specific if __linux__ is not + defined. + +2005-03-01 Mina Naguib + * Minor visual tweaks to the web interface + +2005-03-01 Philippe April + * Tagged v1_1_0_beta3 + +2005-02-28 Mina Naguib + * Do not update the last_updated field on incoming traffic - update it on + outgoing traffic only. This should be a much more reliable indication of + client no longer being there + * WifiDog status is now viewable with a web browser at + http://ip:port/wifidog/status + * Added new web hook for http://ip:port/wifidog + * Beautified web interface at http://ip:port/wifidog/* + +2005-02-24 Mina Naguib + * auth_server_request now returns AUTH_ERROR on error instead of AUTH_VALIDATION_FAILED + * centralserver.c: Fix typo (was =+, made it +=) that made the response + from the auth server corrupted in memory if the entire response would not + fit in 1 packet and retrieved with 1 read() call + * Better logging of details and calling of mark_* (auth+online/offline) + +2005-02-22 Philippe April + * Tagged v1_1_0_beta2 + +2005-02-20 Mina Naguib + * New safe.c with safe_malloc, safe_strdup, safe_asprintf and + safe_vasprintf with propper logging and exit when error. Replaced all + instances of original with safe versions in all files + * Fix memory leak in iptables_fw_counters_update + * Partial merge from CaptiveDNS branch: Consolidated much of the networking + calls to the auth servers into a magical function called connect_auth_server() + that's responsible for dns lookup, connecting, marking servers bad, marking + online/auth_online, and refreshing the firewall rules. + * Partial merge from CaptiveDNS branch: Added new functions mark_auth_online(), + mark_auth_offline() and is_auth_online() - similar in nature to is_online() + etc. except tailored to decide on auth servers status - currently being called by + connect_auth_server() + * Partial merge from CaptiveDNS branch: Different apology in 404 handler + depending on whether internet is down or just auth server is down + * Partial merge from CaptiveDNS branch: wdctl status now shows status of + is_online and is_auth_online + * Fixed several inconsistencies regarding the parity and size of + incoming/outgoing counters. Standardized on "unsigned long long int" in + declarations and *printf/*scanf formats + +2005-02-16 Philippe April + * ipkg/rules - When we clean, forgot to delete ipkg-build-stamp + +2005-02-15 Mina Naguib + * Now also reports wifidog_uptime when it pings the server, as well as + shows it in wdctl status + +2005-02-13 Mina Naguib + * Completely re-did the iptables rules. Most of the rules are now in the + filter table instead of the nat table. Also DROPs are now replaced with + REJECTs to help tell the user connection refused instead of endless pauses + * Bugfix: Traffic from client to router was counted twice in the "outgoing" + bytecount since it increased both counters in mangle.* and filter.* - Got + rid of TABLE_WIFIDOG_WIFI_TO_GW completely since it's unneeded + +2005-02-12 Mina Naguib + * Stricter format rules for all *scan* functions hunting for IPs and MAC addresses + * fw_iptables.c: Make sure scanned IP address is a valid IP address + * firewall.c: Fix memory leak in arp_get + * libhttpd/protocol.c: Abort connection if read non-ascii from client. This + is often a telltale sign of a program such as skype using port 80 for + non-http requests - this therefore ends the thread as early as possible + instead of having it lay around for a while trying to get a valid http + request and taking up resources + * ping_thread.c: When pinging auth server now also sends sys_uptime, sys_memfree + and sys_load + * -v commandline option now shows wifidog version + +2005-02-11 Philippe April + * Tagged v1_1_0_beta1 + +2005-02-11 Philippe April + * Fixed a bug in counting the traffic between client and gateway + * Alpha8 + +2005-02-04 Mina Naguib + * Partially bugfix apology when offline + * ipkg/rules: More tweaking to make it build nicely with recent openwrt + buildroots + +2005-02-03 Mina Naguib + * Keep track of last times we successfully & unsuccessfully spoke to the + auth server/used DNS. Then, if we know we're not online, show a little + apology to the user instead of re-directing them to the auth server. + * ipkg/rules: Added some extra version detection to auto-detect versions + of kernel, iptables and ipkg-utils instead of having them hardcoded. This + makes creating ipkg's work with different OpenWRT releases + * fw_iptables.c: Fixed memory leak caused by not freeing return from + iptables_compile in iptables_load_ruleset + * http.c: Deleted unused call to client_list_find + * http.c: /about URL now shows wifidog version + * Cosmetic typo fixes + +2005-02-03 Philippe April + * Ping the users everytime we check their counters, that way we keep them + alive + * Optional ExternalInterface + * Optional GatewayAddress (we discover it. finally.) + * We check for the traffic from the clients to the firewall, to catch the + traffic the icmp ping is generating + * Fixed bug where we were doing the opposite of what desired when checking if authentication server was alive + * Bumped to alpha7 + +2005-01-23 Philippe April + * wdctl status will return the auth servers in the linked list + * We'll now forward to the auth server to display the used-to-be-ugly + messages like "go ahead and validate your account you have 15 minutes" + * Bumped to alpha6 + +2005-01-06 Philippe April + * fw_iptables.c: Changed REJECT to DROP for the end of the table Unknown, + REJECT doesn't seem to be available in the NAT table. + * fw_iptables.c: Indented things + * fw_iptables.c Fix: Created the authservers table at the beginning and destroy + at exit time only to avoid recreating it everytime + * Bumped to alpha5 + +2005-01-05 Philippe April + * Typo, fixed some spaces (mostly esthetic) + * Bumped to alpha4 + +2004-12-19 Alexandre Carmel-Veilleux + * src/fw_iptables.c: Tweak of auth_server firewall rule setting + code. (and promptly undone, fixing the cause is better then + fixing the symptom) + * src/conf.c: NULL-fill auth_server struct so that + auth_server->last_ip always equals NULL when first filled. + +2004-12-16 Benoit GrĂ©goire + * src/fw_iptables.c: Display iptables command that is run in debug mode. + +2004-12-07 Benoit GrĂ©goire + * src/firewall.c: Fix reversed incoming and outgoing connections in statistics code + * bump version to alpha3 + +2004-11-29 Alexandre Carmel-Veilleux + * wifidog.conf: Fixed firewall rule bug. + * src/fw_iptables.c: Unknown user default block rule not "REJECT" + instead of "DROP" + +2004-11-23 Alexandre Carmel-Veilleux + * src/conf.c: Fixed a NULL pointer dereference in get_ruleset(). + +2004-11-22 Alexandre Carmel-Veilleux + * libhttpd/api.c: Fix leak in HttpdEndRequest(). + * src/ping_thread.c: Fix auth_server IP change code with latest + from previous branch. + * src/conf.h: Same as above. + * src/fw_iptables.c: Same as above. + * src/conf.[ch]: Firewall rule set parsing code. + * wifidog.conf: Default firewall rule set defined. + * src/fw_iptables.[ch]: Firewall rule set enacting code. + * configure.in: bumped version to 1.1.0-alpha2 + +2004-11-18 Benoit GrĂ©goire + * src/ping_thread.c: Merge phil's bug fixes from stable branch + * ipkg/rules: Merge phil's bug fixes from stable branch + * configure.in: Set version to 1.1.0alpha + +2004-11-18 Alexandre Carmel-Veilleux + * src/fw_iptables.[ch]: Merged in Phil's patch. + * src/*: Added ping_thread hooks to reset authserver table in the + firewall if it notices the auth_servers changing IPs. + +2004-11-17 Alexandre Carmel-Veilleux + * libhttpd/*: libhttpd has been taken behind the shed and shot in + the back of the head. The replacement separates the request struct + from the server struct. It's thread safe if none of OUR threads + write to server. + * src/*: All the changes to handle the new libhttpd and also to + move over to a worker thread system. http_callback_auth() no + longer spawns a thread either. + * *: this update preceded by a cvs tag PRE_NEW_LIBHTTPD. + * *: You want to check the mailing list archive also. + +2004-11-10 Alexandre Carmel-Veilleux + * libhttpd/protocol.c: select() based timeout. + +2004-10-31 Alexandre Carmel-Veilleux + * configure.in: bumped version number to "1.0.2-pre1" since we + already have ile sans fil hot spots advertising "1.0.1". + +2004-10-30 Alexandre Carmel-Veilleux + * src/ping_thread.c: asynch read(). fixed bug in byte counting. + +2004-10-29 Philippe April + * ipkg/rules: added conffiles so it does not overwrite config files + +2004-10-29 Alexandre Carmel-Veilleux + * src/ping_thread.c: Much new debugging information + * multiple files: Logging for all mutexes + +2004-10-28 Philippe April + * ipkg/rules: building ipkg-tools before packaging + +2004-10-28 Alexandre Carmel-Veilleux + * multiple files: Implemented a FirewallRule config command, it + doesn't actually do anything yet. + * libhttpd: #if 0'd out lots of request parsing code. + * libhttpd: changed URL parsing. + +2004-10-27 Philippe April + * ipkg/rules: removed --build=mipsel from ./configure + +2004-10-26 Philippe April + * ipkg/rules: sed -i is not standard, did a workaround. + * ipkg/rules: openwrt's buildroot has changed, modified ipkg + accordingly, please read README.openwrt + +2004-10-22 Alexandre Carmel-Veilleux + * src/various: Added wd_gethostbyname, a thread-safe (serialized) + version of gethostbyname. + +2004-10-15 Alexandre Carmel-Veilleux + * src/auth.c: Fixed hard coded port. + +2004-10-09 Alexandre Carmel-Veilleux + * src/gateway.c: More logging on termination_handler. + +2004-10-08 Alexandre Carmel-Veilleux + * src/wdctl_thread.c: Fix wdctl_status to return all connected + users. + +2004-10-07 Alexandre Carmel-Veilleux + * src/conf.c: Fixed mark_auth_server_bad() for the case where there + is only one auth server. + * src/ping_thread.c: Added extra debugging. + * src/ping_thread.c: Fixed file descriptor leak. + * src/centralserver.c: Fixed many file descriptor leaks. + * src/centralserver.c: Failure of read() no longer fatal. + * src/centralserver.c: In case of failure, return from + auth_server_request() is no longer an undefined authresponse. + * src/util.c: Fixed typo in logging. + * src/wdctl_thread.c: Added logging when socket path is too long. + * src/debug.c: Debug now logs the time of an event. + +2004-08-30 Alexandre Carmel-Veilleux + * wifidog.conf: Corrected an example + * README.openwrt: Typo fixed, editorial changes + * ChangeLog: Benoit's last update entry was set in the future ;-). + * All over src/: Compiled with -Wall and fixed all nagging. + +2004-08-30 Benoit GrĂ©goire + * Makefile.am: Add rpm target + * wifidog.spec.in: Rework spec file. Now works and include the init script + * ipkg/rules: Deal with the incomplete init.d system of the OpenWrt. Install scripts/init.d/wifidog as /usr/bin/wifidog-init, and call wifidog-init start from S65wifidog. + * scripts/openwrt/S65wifidog: Add file + * scripts/init.d/wifidog: Fix performance and protability problem. Make it chkconfig compliant. Test that chkconfig --add wifidog works (at least on mandrake) + * src/wdctl.c: Change some message, make sure wdctl return 0 unless there is an error. + +2004-08-30 Benoit GrĂ©goire + * README.openwrt: Documentation update + * Makefile.am: Make a ipkg target to ease WRT54G installation + * ipkg/rules: Add wdctl and the init.d script. + * Add BUILDROOT variable to the build system so we can use it when needed + * src/ping_thread.c: Have the server ping immediately on boot. Note that this will only help if the second server responds. The logic of the ping itself should be changed so it iterates in the list until it finds one that responds or exausts the list + * wifidog.conf: Add more doc, and (most) of ISF's default config in comments. + * Bump version in anticipation for release + +2004-08-29 Guillaume Beaudoin + * wifidog.spec.in: Changed prefix to match scripts/init.d/wifidog. + * debian/rules: Configuration and init.d file added. + * debian/control: Description and Depends field changed. + * Makefile.am: Added scripts directory and ipkg/rules file. + +2004-08-29 Pascal Leclerc + * scripts/init.d/wifidog: Startup/shutdown script for Wifidog deamon + +2004-08-29 Guillaume Beaudoin + * wifidog.spec.in: Must be in decending chronological order. + +2004-08-29 Guillaume Beaudoin + * wifidog.spec.in: Remove some leftover from libOFX. + * Makefile.am: Include debian/* files. + * We should now be able to package .deb and .rpm from dist. + +2004-08-27 Benoit GrĂ©goire + * README.openwrt,src/conf.c,h: Documentation update + * src/gateway.c, src/ping_thread.c, src/wdctl.c, src/wdctl_thread.c: Fix linking problems related to errno.h and extern int errno + +2004-08-26 Pascal Leclerc + * Makefile.am: Remove phpauth from EXTRA_DIST + +2004-08-25 Alexandre Carmel-Veilleux + * src/auth.c: Path as changed in 1.26 was preceded by a /, the path already contains a / so it would yield http://host//path/ + +2004-08-25 Benoit GrĂ©goire + * src/auth.c: Remove hardcoded path. + +2004-08-23 Benoit GrĂ©goire + * src/ping_thread.c: Send the gateway id to the central server during ping, so the server know which gateway checked in, and then knows for sure that it is up (well, once the server implements it...). + +2004-08-23 Benoit GrĂ©goire + * src/centralserver.c: Fix path for auth by appending /auth/ to auth_server->authserv_path. Wifidog works again. + +2004-08-20 Alexandre Carmel-Veilleux + * Debug output of all HTTP transactions and their responses. + * Changed ipkg to use wifidog.conf from the base tree + * Send url to central server for link back out + +2004-08-19 Alexandre Carmel-Veilleux + * Sort of fixed the hanging thread (with an explicit thread kill) + * Fixed ping code + +2004-08-13 Alexandre Carmel-Veilleux + * All Auth Server configuration now handled by the "AuthServer" + directive. + * The "AuthServer" directive is now multi line. + +2004-08-11 Alexandre Carmel-Veilleux + * Added code to do heartbeat. + * Changed AuthServer yet again. + +2004-08-09 Alexandre Carmel-Veilleux + * WiFiDog now can read multiple auth servers in its config file. + * Added functions to handle the auth servers list. + * WiFiDog can failover between servers for its internal requests. + * Firewall sets rules for all auth servers. + +2004-08-06 Alexandre Carmel-Veilleux + * AuthservPath no longer mandatory in config file. + +2004-08-04 Philippe April + * Renamed iptables.[ch] to fw_iptables.[ch] + +2004-08-03 Alexandre Carmel-Veilleux + * Fixed broken sockaddr_un usage in wdctl.c and wdctl_thread.c + +2004-08-01 Benoit GrĂ©goire + * Delete everything in phpauth, it will now live in it's own module (wifidog-auth) + +2004-08-01 Alexandre Carmel-Veilleux + * Added wdctl facility + +2004-07-21 Philippe April + * Cleaned up the ipkg makefile + * Added makefile to build on Debian + +2004-07-19 Alexandre Carmel-Veilleux + * Build script for OpenWRT ipkg + +2004-07-06 Alexandre Carmel-Veilleux + * Added cache control to default error message returned. + +2004-07-05 Philippe April + * Fixed an endless loop in client_list_delete + +2004-06-10 Alexandre Carmel-Veilleux + * Added debugging to libhttpd so that httpdGetConnection() traces + its execution into ./httpdGetConnection.log. This should be removed + once it's no longer needed or put within #ifdef DEBUG's. + +2004-06-01 Philippe April + * Sending User-Agent header to central server + +2004-05-28 Philippe April + * Fixed bugs implemented after major changes + +2004-05-27 Benoit GrĂ©goire + * Massive Doxygen update in all files. IMPORTANT: The new convention is: @brief in the .h, long description and parameters in the .c + * Cleaned up some more issues in my notes taken at the formal review + * client_list.c,h: Make client_list_free_node() private, define and document client_list_mutex here + * config.c: Start the hunt for evil globals: Get rid of the config global + * doc/doxygen.cfg.in: Enable generation of internal doc, a few other tweaks + * Documentation now generates a TODO list and DEPRECATED list, please look at them + +2004-05-27 Alexandre Carmel-Veilleux + * Cleaned up all the issues brought forward in the code review + on 2004-05-26 at Benoit's. There are to many changes to list + individually. + +2004-05-15 Philippe April + * Commented out cookie handling in libhttpd because it segfaults if + you pass a particular formatting/buggy one + +2004-05-14 Philippe April + * Fixed crash when receiving SIGPIPE signal with write() would fail + +2004-05-13 Philippe April + * Advertise to the central server when we logged out a user + +2004-05-12 Philippe April + * Sending a "stage" when doing authentication for the server + to be able to know if it's a login, or just a counters update. + +2004-05-11 Philippe April + * Now tracking the hotspot id and ip in database + +2004-05-07 Philippe April + * Now we store both incoming and outgoing counters on server + and expire if no activity at all on both + * Changed the structure of nodes a little + +2004-05-07 Philippe April + * New parameter ExternalInterface + * Made possible to count inbound traffic by inserting new rules + +2004-05-07 Philippe April + * Cleaned up common.h from files + +2004-05-07 Philippe April + * Made iptables' tables DEFINEs instead of being hardcoded + +2004-05-07 Philippe April + * Fixed typo + +2004-05-06 Philippe April + * Cleanups and standardized things + +2004-05-06 Philippe April + * Cleanups in fw_counter function + +2004-05-05 Philippe April + * Calling iptables directly instead of using shell scripts + for fw_init, fw_destroy and fw_allow/fw_deny + * Removed shell script for fw.counters + * Fixed memory leaks + * Moved most of the iptables-specific (all but the counters) + to iptables.c to modularize a bit more + * Hack to allow deciding if we want FW calls' messages quiet or not + +2004-04-23 Philippe April + * Fixed a debug line + +2004-04-22 Philippe April + * Major changes, cleaned up code + * Changed the way firewall tags traffic + +2004-04-21 Philippe April + * Changed fw.destroy so it cleans up more in a while loop + +2004-04-20 Alexandre Carmel-Veilleux + * fixed expiration time + +2004-04-20 Philippe April + * A lot of changes regarding debugging facilities and added logging + to syslog + * Removed possibility to specify port on command line + +2004-04-19 Philippe April + * Changed some debugging severity + +2004-04-19 Benoit GrĂ©goire + * Properly integrate libhttpd into the source tree ;) Note that this will create a proper system wide shared library for libghttpd. Still to be done: 1- Store Mina's patch somewhere, in case we want to upgrade libhttpd. 2-Add configure option not to build httpd, and use an already installed one. + +2004-04-18 Alexandre Carmel-Veilleux + * Fixed pthread_cond_timedwait. The mutex needed to be locked as + per the POSIX spec, yet Linux or Mac OS X don't care... + * Fixed the double SIGTERM handler on Linux... + +2004-04-17 Alexandre Carmel-Veilleux + * Added work around for uClibc bug in auth.c + +2004-04-17 Philippe April + * Fixed firewall scripts to make them standard and some firewall functions + +2004-04-17 Alexandre Carmel-Veilleux + * Updated documentation in firewall.c + +2004-04-17 Philippe April + * Fixed path returning to gateway in phpauth/login/index.php + +2004-04-16 Alexandre Carmel-Veilleux + * Merged in libhttpd into the source tree + +2004-04-16 Philippe April + * Fixed CRLF/formatting in phpauth/login/index.php + * Added some documentation for firewall.c, commandline.c + * Removed an unnecessary line dist_sysconf_DATA from Makefile.am + +2004-04-15 Alexandre Carmel-Veilleux + * Changed the locking mechanism, now all access to t_node * structs + are properly protected. + +2004-04-15 Alexandre Carmel-Veilleux + * Connection now closed if counter hasn't change for one full + period. + +2004-04-14 Philippe April + * Fixed shell script hardcoded interface + +2004-04-14 Alexandre Carmel-Veilleux + * Existing IPs are logged off when they're authenticated again. + +2004-04-14 Alexandre Carmel-Veilleux + * Fixed clean up so it happens at the right time. + +2004-04-14 Alexandre Carmel-Veilleux + * Major retooling of insert_userclass(), fixed seg fault. + * The program now works as advertised. + +2004-04-14 Alexandre Carmel-Veilleux + * Switched to threads. Alpha quality build, at best + +2004-04-12 Alexandre Carmel-Veilleux + * Changed child return value handling, again. Now it's actually + using the real value instead of the flag. + * The http.c authentication code now closes the http connection + from the user. + +2004-04-11 Alexandre Carmel-Veilleux + * Added extra debugging information. + * Fixed return value handling in debugging calls. + +2004-04-11 Alexandre Carmel-Veilleux + * Removed duplicates signal handling hooks + * Additional comments in SIGCHLD handler + +2004-04-11 Alexandre Carmel-Veilleux + * Node find if's expressions changed + +2004-04-11 Alexandre Carmel-Veilleux + * SIGCHLD Handler initializaed outside of deamon mode now. + +2004-04-11 Alexandre Carmel-Veilleux + * Very large modification. The entire architecture has been reworked + so that authentications to the central server are performed in a + fork()'d child process and the exit code from that child is then + used to set the User Class of the connection. + * The UserClasses (global definitions) and Rights (per connection) + have been integrated. + +2004-03-16 Mina Naguib + * Changed HTTP server tasks to be handled by libhttpd - merged + incorporate_libhttpd branch + +2004-03-13 Philippe April + * Modified the way firewall scripts are called so we can configure + them in the config file (a bit more modular than it was) + * Added simple linked list to keep track of clients and to + keep a counter of the utilization and send it to the auth server + * Fixed CRLF/formatting in phpauth/auth/index.php + * Hacked phpauth/auth/index.php to handle very basic utilization tracking + +2004-03-12 Philippe April + * Changed all perror()s into debug()s and added errno.h to common.h + +2004-03-10 Philippe April + * Small fix to firewall.c so we don't define variables after + the function has started (so it builds on gcc-2.95) + +2004-03-09 Philippe April + * Major changes, not forking anymore for new connections, now using + select() instead. It will allow us to efficiently use a linked list to track + users and other things. It introduces some bugs and design issues but will + be better in the end. + +2004-03-09 Philippe April + * Small fix in the default.php login page + * exit() where the program was supposed to exit but wasn't when the + firewall could not be setup + +2004-03-09 Alexandre Carmel-Veilleux + * Tiny change to increase cross-platform compatibility. It can now build on OS X and it comes close to building on my old BSD box. + +2004-03-08 Benoit GrĂ©goire + * Initial CVS import. Integrate a standrad GNU build system and Doxygen to the build process. Add Doxygen and CVS headers, .cvsignores, etc. Note that the imported code is Philippe April (papril777 at yahoo.com)'s work. Tell me if I forgot anything. Please note that the paths in the src/fw* scripts are still hardcoded. Don't forget to update the ChangeLog file every commit and add doxygen comments to your code. Happy hacking. + diff --git a/FAQ b/FAQ new file mode 100755 index 00000000..fb8d82d2 --- /dev/null +++ b/FAQ @@ -0,0 +1,488 @@ +# +# $Id$ +# +# The latest version of this document lives at: +# http://www.ilesansfil.org/wiki/WiFiDog/FAQ +# +# Please check the above URL if you have a FAQ that does not appear here. +# + +WiFiDog/FAQ + +The WiFi Dog Captive Portal Frequently Asked Questions + + To alleviate the repetition on the [9][WWW] WiFiDog mailing list, and + to help people get started quickly, here are the FAQs: + 1. [10]The WiFi Dog Captive Portal Frequently Asked Questions + 1. [11]General questions + 1. [12]What is WiFiDog ? + 2. [13]Who makes WiFiDog ? + 3. [14]Who can use WiFiDog ? + 4. [15]Who currently uses WiFiDog ? + 5. [16]What can it do ? + 6. [17]What is it composed of ? + 7. [18]What are the main differences between it and NoCat ? + 8. [19]How does it work ? + 9. [20]What does it run on ? + 10. [21]Can I write my own client ? + 11. [22]Can I write my own auth server ? + 12. [23]What does it look like ? + 2. [24]The WiFiDog Client + 1. [25]What do I need ? + 2. [26]Pre-installation + 3. [27]Installation + 4. [28]Configuration + 5. [29]Running + 6. [30]Testing + 3. [31]The WiFiDog client on a linksys WRT54G + 1. [32]What do I need ? + 2. [33]Pre-installation + 3. [34]Installation + 1. [35]Introduction + 2. [36]Compiling a MIPS-friendly WiFiDog + 3. [37]Getting the new MIPS-friendly WiFiDog onto the + router + 4. [38]Actual installation + 4. [39]Configuration, Running and Testing + 5. [40]The intricate link between WiFiDog and OpenWRT + 6. [41]I am not comfortable with linux and don't know how + to do all this compiling stuff. Is there an easier way + for me to get the WiFiDog client running on a Linksys + WRT54G ? + 4. [42]The WiFiDog auth server + 1. [43]What do I need ? + 2. [44]Installation + 3. [45]Configuration + 4. [46]Testing + +General questions + +What is WiFiDog ? + + [47]WiFiDog is software used to create wireless hotspots. It is a + next-generation alternative to [48][WWW] NoCat. + +Who makes WiFiDog ? + + The technical team of [49]IleSansFil created and maintains + [50]WiFiDog. + +Who can use WiFiDog ? + + On the legal/licensing front, anyone can use [51]WiFiDog. It is free + software released under the GPL license. + + On the practical front, we would like the answer to also be + "everyone", however this would not be the truth. The main target user + base of [52]WiFiDog is network administrators, hotspot administrators + and hackers who "know what they're doing". Odds are that an average + windows user would not benefit from, or be able to correctly setup and + continually administer a [53]WiFiDog installation. + + If the software ever reaches a point of complete point-and-click ease + that we feel average users can safely administer, we will update this + document. + +Who currently uses WiFiDog ? + + The following companies, organizations, groups or persons are known to + use [54]WiFiDog on their hotspots: + * [55]IleSansFil + * [56][WWW] BC Wireless + +What can it do ? + + See the [57]WiFiDog/FeatureList page for the feature list. + +What is it composed of ? + + It is composed of 2 components: + 1. The client is a daemon process - this gets installed on every + wireless router + 2. The auth server is a web application - this gets installed in a + central location + +What are the main differences between it and NoCat ? + + On the client side, it's smaller, has far fewer dependencies, and runs + well on embedded devices. + + On the auth server side, it's more customizable, and is geared towards + capitalizing the infrastructure for the purposes of building portals + and communities. + +How does it work ? + + The client daemon uses firewall rules to control traffic going through + the router. When a new user tries to access a web site, the client + will transparently re-direct them to the auth server where they can + either log-in or sign-up. The client and the auth server then + negotiate what to do with the client and either allow or deny them + certain network access. + + The client also talks to the auth server every X minutes to update it + on vital statistics including uptime, load, traffic count per client, + and to let it know it's still there. + + Refer to the [58]WiFiDog/FlowDiagram document for some more details. + +What does it run on ? + + The client runs on any linux machine that has a working + netfilter+iptables installation. + + The auth server runs on any PHP-enabled web server. + +Can I write my own client ? + + Sure, but why ? We've done all the work. The client is written in C + and is extremely lightweight so that it runs comfortably in embedded + environments such as the [59][WWW] Linksys WRT54G router. + + The client is time-tested and is fairly stable. It is used extensively + in [60][WWW] IleSansFil's deployed hotspots. + +Can I write my own auth server ? + + Again, we've done all the work. However our auth server at the time of + this writing is not as polished as the client. Feel free to make it + better or write your own from scratch. If you go with the later option + you'll have to respect the same protocol the client uses for the whole + system to work correctly. + +What does it look like ? + + The client is a daemon process that runs in the background. It looks + like zen, chi, the ether, zilch. It has no user interface. + + The auth server is a web application that can be customized via + templates to look however you want it to look. To check out + [61]IleSansFil's auth server installation see [62][WWW] + https://auth.ilesansfil.org + +The WiFiDog Client + +What do I need ? + + 1. Basic proficiency in a linux environment + 2. A linux OS with netfilter compiled into the kernel + 3. The iptables package + 4. The GNU C compiler (gcc). Other compilers may work, but we have + not tested and will not support them. + 5. The latest [63]WiFiDog tarball which can be obtained from + [64][WWW] SourceForge + +Pre-installation + + This is where a lot of people run into problems, so let's state this + in bold: + + MAKE SURE EVERYTHING WORKS FIRST BEFORE INTRODUCING [65]WiFiDog INTO + THE ENVIRONMENT + + That especially means: + * The router must boot properly + * The router must bring up the interfaces properly + * The router must set up the routes properly + * The router must connect to the internet properly + * DNS settings must be set or obtained properly. DNS must work. + * DHCP settings (client, server or both) must be set or obtained + properly. + * If using NAT, the router must setup NAT/masquerading rules with + iptables properly + * Clients on the desired ([66]WiFi) network must be able to bind, + associate, lease and connect the internet properly + * All the above must happen automatically when the router starts or + gets rebooted + + Do NOT proceed with installing [67]WiFiDog until you've satisfied the + above. It will not work otherwise and you will waste lots of time. + +Installation + + [68]WiFiDog, like many open source projects, is distributed with + standard autotools utilities to make installation easy. Unpack the + tarball, then follow the standard: +./configure +make +make install + +Configuration + + Edit /etc/wifidog.conf and follow the instructions in the file. Things + should be self-explanatory. + +Running + + For the first time, run [69]WiFiDog with the following switches: +wifidog -f -d 7 + + -f means to run in foreground (do not become a background daemon) + + -d 7 increases debug output level to the maximum + +Testing + + As a client on the [70]WiFi network (or whatever interface is + configured as the LAN interface in /etc/wifidog.conf), open a web + browser and try to browse to your favourite web site. + + Monitor the output of the running [71]WiFiDog to see what it's doing. + +The WiFiDog client on a linksys WRT54G + + Due to the lightness of the [72]WiFiDog client it is often installed + inside the linksys WRT54G. There are some profound issues that arise + with this setup that it warrants its own section in this FAQ: + +What do I need ? + + You will need to have basic/full proficiency in a linux environment + + You need to re-flash your router with a hacker-friendly firmware + called [73][WWW] OpenWRT. [74][WWW] Follow the user guide on the + OpenWRT site to get this part done. + + Do not proceed until you've completed the above. We also recommend you + spend some time familiarizing yourself with your new router's OS + before introducing [75]WiFiDog into that environment. This especially + includes the nvram settings, network interfaces and existing interface + bridges. + +Pre-installation + + The same rules apply as the pre-installation in a non-WRT54G + environment above. Do not proceed until you've satisfied them. In + summary: Make sure EVERYTHING works first. + +Installation + +Introduction + + Installation of the client on the WRT54G is a bit tricky. The space + limitations on the device mean there is no compiler in the OpenWRT + operating system. That means that you must compile the client on an + external machine then transfer the compiled form onto the router. + + To complicate things more, if you compile your client regularly on a + standard x86 desktop the produced binary will not run on the router + due to the different type of processor (MIPS) on that router. + + What is needed is called cross-compilation, In that scenario you use + an architecture (such as your x86 desktop) to produce binaries + explicitly designed to run on a different architecture (your MIPS + router). + + The above was the bad news since it makes things sound complicated. + The good news is that it's not too complicated and we've built scripts + to make this a snap for you. As a matter of fact, you've already done + this before! + + Remember when you followed the OpenWRT building instructions ? Without + knowing it, you already cross-compiled stuff! You used your desktop to + cross-compile an entire operating system for the MIPS architecture + which resulted in one compressed firmware image you installed on your + router. + +Compiling a MIPS-friendly WiFiDog + + 1. Download the latest [76][WWW] WiFiDog tarball from sourceforge. + 2. Uncompress the tarball, enter the directory + 3. Run the following, replacing /usr/local/openwrt/ with wherever you + unpacked the OpenWRT tarball earlier: + +ipkg/rules BUILDROOT=/usr/local/openwrt/ + + You're done. If all is well you should now have a new file named + wifidog_1.1.0_mipsel.ipk (version number may be different depending on + the tarball you downloaded). + +Getting the new MIPS-friendly WiFiDog onto the router + + The .ipk is a data file for the simple "ipkg/i-Package" package + manager already on your router. All that's needed now is to copy that + file onto your router. If you have installed the dropbear SSH daemon + package on your router you can use scp on your desktop to copy the + .ipk file to the router. Otherwise copy that file to any web server + you have access to, then use wget on the router to download the file + from the web server. + + Either way, place the file in the /tmp/ directory on the router. + +Actual installation + + Once you have the .ipk file on the router, use this command to install + it: +ipkg install /tmp/wifidog_1.1.0_mipsel.ipk + + Once that is successful delete the .ipk file from /tmp/ to free the + occupied memory. + +Configuration, Running and Testing + + Same as the earlier section in a non-WRT54G environment + +The intricate link between WiFiDog and OpenWRT + + Repeat after me: + + A [77]WiFiDog RUNNING ON AN OpenWRT INSTALLATION MUST HAVE BEEN + COMPILED AGAINST THE SAME OpenWRT BUILDROOT USED TO CREATE THAT + INSTALLATION + + What does that mean ? + 1. If you downloaded and compiled OpenWRT yourself, download and + compile [78]WiFiDog yourself against the same buildroot - Do not + use someone else's pre-compiled [79]WiFiDog + 2. If you downloaded a pre-compiled OpenWRT firmware image: + 1. Ask the person who built it to compile [80]WiFiDog for you + against the same buildroot + 2. Or ask them for a copy of their OpenWRT buildroot so you may + compile [81]WiFiDog against it + +I am not comfortable with linux and don't know how to do all this compiling +stuff. Is there an easier way for me to get the WiFiDog client running on a +Linksys WRT54G ? + + You can use an OpenWRT and [82]WiFiDog compiled by someone else. They + must be compiled by the same person against the same OpenWRT + buildroot. + + [83]IleSansFil makes it's own pair of OpenWRT images and [84]WiFiDog + .ipk compiled files available to the public: + * You can download a pre-compiled OpenWRT firmware image [85][WWW] + here + * And you can download a compatible [86]WiFiDog .ipk file [87][WWW] + here + + Look in the [88][WWW] OpenWRT site for instructions on how to re-flash + your router with the firmware image (skip any download/building + instructions). + + Then follow the above installation instructions for installing the + [89]WiFiDog .ipk file into the OpenWRT-flashed router. + + Please note that the above saves you from the knowledge and time + needed to compile and produced these binary files. It is however no + magical cure for linux illiteracy. You need to be proficient enough in + a unix environment to be able to telnet/ssh into the router and + perform the outlined installation and configuration tasks. If you do + not feel comfortable doing this we advise you consult with someone who + is proficient in linux and networking. + +The WiFiDog auth server + +What do I need ? + + Refer to [90]WiFiDog/AuthServerDoc + +Installation + + Refer to [91]WiFiDog/AuthServerDoc + +Configuration + + Refer to [92]WiFiDog/AuthServerDoc + +Testing + + Refer to [93]WiFiDog/AuthServerDoc + + last edited 2005-03-27 13:11:15 by [94]MinaNaguib + +References + + 1. http://www.ilesansfil.org/wiki/FrontPage + 2. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=raw + 3. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print + 4. http://www.ilesansfil.org/wiki/WiFiDog + 5. http://www.ilesansfil.org/wiki/FindPage + 6. http://www.ilesansfil.org/wiki/TitleIndex + 7. http://www.ilesansfil.org/wiki/WordIndex + 8. http://www.ilesansfil.org/wiki/HelpOnFormatting + 9. http://listes.ilesansfil.org/ + 10. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-b9d27a8844e66371abfbb27bf54669896d8bf4fa + 11. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-eb7dd5c81583187efb2d29ebc9ab2b6457417b13 + 12. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-e05420efb19364f3fa0844223f1bcfc71be7db00 + 13. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-80293173c84355ebeff2ecbfabaa32edb3c3ae75 + 14. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2aa554753e8b93818ba5ef190e67e401421931b9 + 15. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-975f3574aa59265dd2b0c45ae96e90c98c8bc7d5 + 16. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-dccf73ff2dcc305d6334dfd0ed90d1c4221b8a12 + 17. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-ebd81c14ab1b66d6aada9fc399597b644e120036 + 18. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-9b4c49acb692c6ba8bc2c0e43a991c5fc7b80220 + 19. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-5aa44a01d2ff78d1e2b5240e0a6c75910d584a0e + 20. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-738ab14de6f62065ca3daf9dd3341bfcabc06223 + 21. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-6059fbd6c262224baf06331fbe83f319ffe730fa + 22. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-e8131f271e42589291d507afd89d0c5d24f02ad1 + 23. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-6a764a3be722e0ff8d1446586643ea57d70cd489 + 24. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-a650736551182819fd6f742597362be729d9b70d + 25. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-57aaa0d1e21d38a7f5bedea65950c36b422cbbb6 + 26. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2b75ffe2445295c9982d0873d48e11d5cd89816e + 27. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-930f69b528374c4c55fc91b52e030deef8a93648 + 28. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-4b221edbf4c2383afab601694f2db039700c21cc + 29. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-9fcf91fbcf4712b6de6d5b70e703192dd882afa8 + 30. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-18cc26d84a97b42f3bc06af0203038062a8efb06 + 31. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-8ba37f479842312562f131032bb11e4fb68942aa + 32. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-57aaa0d1e21d38a7f5bedea65950c36b422cbbb6-2 + 33. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2b75ffe2445295c9982d0873d48e11d5cd89816e-2 + 34. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-930f69b528374c4c55fc91b52e030deef8a93648-2 + 35. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-b6830b2e74230b45153f4fa98ee189d5748ec9f0 + 36. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-78504516e51f8fc43cc111b9a8a41a85cb652fff + 37. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-92221794cfda95baa91352d087656f27754027d2 + 38. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-2474f5bb689b7b06fc3334eb8e29a26ed60c4280 + 39. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-37c9cfe0aa830fa8ef3e6f617bd3c741cca6947c + 40. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-1dee9a0f840701e6518a0763c48aef734d1996f8 + 41. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-158e6f354a348c9374107d0a66a7f4c84603ba8a + 42. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-30106563831cfdb0840b05fa48e9194d7876f12e + 43. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-57aaa0d1e21d38a7f5bedea65950c36b422cbbb6-3 + 44. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-930f69b528374c4c55fc91b52e030deef8a93648-3 + 45. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-4b221edbf4c2383afab601694f2db039700c21cc-2 + 46. http://www.ilesansfil.org/wiki/WiFiDog/FAQ?action=print#head-18cc26d84a97b42f3bc06af0203038062a8efb06-2 + 47. http://www.ilesansfil.org/wiki/WiFiDog + 48. http://nocat.net/ + 49. http://www.ilesansfil.org/wiki/IleSansFil + 50. http://www.ilesansfil.org/wiki/WiFiDog + 51. http://www.ilesansfil.org/wiki/WiFiDog + 52. http://www.ilesansfil.org/wiki/WiFiDog + 53. http://www.ilesansfil.org/wiki/WiFiDog + 54. http://www.ilesansfil.org/wiki/WiFiDog + 55. http://www.ilesansfil.org/wiki/IleSansFil + 56. http://www.bcwireless.net/ + 57. http://www.ilesansfil.org/wiki/WiFiDog/FeatureList + 58. http://www.ilesansfil.org/wiki/WiFiDog/FlowDiagram + 59. http://www.linksys.com/products/product.asp?prid=508&scid=35 + 60. http://auth.ilesansfil.org/hotspot_status.php + 61. http://www.ilesansfil.org/wiki/IleSansFil + 62. https://auth.ilesansfil.org/ + 63. http://www.ilesansfil.org/wiki/WiFiDog + 64. http://sourceforge.net/projects/wifidog + 65. http://www.ilesansfil.org/wiki/WiFiDog + 66. http://www.ilesansfil.org/wiki/WiFi + 67. http://www.ilesansfil.org/wiki/WiFiDog + 68. http://www.ilesansfil.org/wiki/WiFiDog + 69. http://www.ilesansfil.org/wiki/WiFiDog + 70. http://www.ilesansfil.org/wiki/WiFi + 71. http://www.ilesansfil.org/wiki/WiFiDog + 72. http://www.ilesansfil.org/wiki/WiFiDog + 73. http://openwrt.org/ + 74. http://openwrt.org/OpenWrtDocs + 75. http://www.ilesansfil.org/wiki/WiFiDog + 76. http://sourceforge.net/projects/wifidog + 77. http://www.ilesansfil.org/wiki/WiFiDog + 78. http://www.ilesansfil.org/wiki/WiFiDog + 79. http://www.ilesansfil.org/wiki/WiFiDog + 80. http://www.ilesansfil.org/wiki/WiFiDog + 81. http://www.ilesansfil.org/wiki/WiFiDog + 82. http://www.ilesansfil.org/wiki/WiFiDog + 83. http://www.ilesansfil.org/wiki/IleSansFil + 84. http://www.ilesansfil.org/wiki/WiFiDog + 85. http://www.ilesansfil.org/dist/openwrt/ + 86. http://www.ilesansfil.org/wiki/WiFiDog + 87. http://www.ilesansfil.org/dist/wifidog/ + 88. http://www.openwrt.org/ + 89. http://www.ilesansfil.org/wiki/WiFiDog + 90. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 91. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 92. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 93. http://www.ilesansfil.org/wiki/WiFiDog/AuthServerDoc + 94. http://www.ilesansfil.org/wiki/MinaNaguib diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 00000000..686ee881 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,53 @@ +# $Id$ + +SUBDIRS = libhttpd src . doc + +docdir = ${prefix}/share/doc/wifidog-@VERSION@ + +doc_DATA = \ + AUTHORS \ + COPYING \ + INSTALL \ + NEWS \ + README \ + ChangeLog + +EXTRA_DIST = \ + FAQ \ + wifidog.spec.in \ + wifidog.spec \ + config \ + scripts \ + contrib \ + wifidog.conf + +.PHONY: doc +doc: + $(MAKE) -C doc doc + +.PHONY: whiterussianipk +whiterussianipk: dist + make -C $(OPENWRTSDK) distclean + mkdir -p $(OPENWRTSDK)/dl + cp -f ${srcdir}/wifidog-@VERSION@.tar.gz $(OPENWRTSDK)/dl/ + make -C ${srcdir}/contrib/build-openwrt-whiterussianipk/wifidog TOPDIR=$(OPENWRTSDK) PKG_MD5SUM= V=99 + @echo DONE. If there were no errors, your package should be in: $(OPENWRTSDK)/bin/packages/ + +.PHONY: kamikazeipk +kamikazeipk: dist + make -C $(OPENWRTSDK) distclean + mkdir -p $(OPENWRTSDK)/dl + cp -f ${srcdir}/wifidog-@VERSION@.tar.gz $(OPENWRTSDK)/dl/ + make -C ${srcdir}/contrib/build-openwrt-kamikazeipk/wifidog TOPDIR=$(OPENWRTSDK) PKG_MD5SUM= V=99 SDK=1 DEVELOPER=1 + @echo DONE. If there were no errors, your package should be in: $(OPENWRTSDK)/bin/packages/ + +.PHONY: rpm +rpm: dist + cp ${builddir}wifidog.spec /usr/src/RPM/SPECS + cp ${builddir}wifidog-@VERSION@.tar.gz /usr/src/RPM/SOURCES + rpmbuild -ta ${builddir}wifidog-@VERSION@.tar.gz + +#clean-local: +# echo "clean-local: " && pwd +# rm -f /usr/src/RPM/SPECS/wifidog.spec +# rm -f /usr/src/RPM/SOURCES/wifidog-@VERSION@.tar.gz diff --git a/NEWS b/NEWS new file mode 100755 index 00000000..ad25e269 --- /dev/null +++ b/NEWS @@ -0,0 +1,116 @@ +# $Id$ +WiFiDog 1.1.5: + * First supported version on OpenWRT kamikaze + +WiFiDog 1.1.4: + * Fix incorrect firewal rule deletion introduced in 1.1.3rc1. Caused the incoming byte count reported to be incorrect for users that logged in a second time on a gateway that wasn't restarted in between. + +WiFiDog 1.1.3: + * Fix incomplete change to make te gateway retry external interface forever. + * Remove hardcoded authserver paths. Can now be defined in the config file (auth server section). + * Add manual logout URL, based in part on work by David Bird + +WiFiDog 1.1.3rc1: + * Close #321: Make the Gateway retry forever if it cannot find it's interface. You never know when someone may finally replug the network cable or something... + * Close #332: Apply patch from Laurent Marchal. biguphpcgmailcom + * fw_iptables.c: Fix error in iptables_fw_access(). Rules were created as ACCEPT instead of DROP + * firewall.c: Fix bug in fw_sync_with_authserver(). The traffic for the validation period of a user who validated his account while connected wouldn't get counted. + * doc/wifidog_firewall_map.dia: At long last, full documentation of the firewall. We would have avoided a lot of stupid mistakes if we produced that sooner. + * Release 1.1.3_rc1 + * Fix #324 + * wifidog.conf: Improve comments and add examples of blocking access to the upstream LAN. + * conf.h: The DEFAULT_CHECKINTERVAL was 5 instead of 60 (as stated in the config file) which caused huge needless load on the auth servers, and needless ping traffic towards the clients if it wasn't manually set. + * contrib/ Add contrib dir to collect the scripts and other code distributed with, but not really part of wifidog. + * Modify the build system to finally be able to build wifidog directly from the wifidog directory using the same files + used to make the official .ipk, without having to copy ANYTHNG to the openwrt SDK. + There is now a new target: make ipk make ipk OPENWRTSDK=path_to_openwrt_sdk + +WiFiDog 1.1.3beta6: + -Fix bug #238 (config file location was hardcoded) + -Fix problem with autodectection of the External interface if the interface isn't fully up yet. wifidog wil now retry for up to two minutes. + +WiFiDog 1.1.3beta4: + -Changed ordering in the filter.FORWARD chain + -Added TCPMSS rule + -Fixed rules bieng left over on shutdown + -Fixed wdctl reset problem + +WiFiDog 1.1.3beta2: + -Fix bug #65 (Whitelisted servers would still splash on port 80 + -Fix incorrect default value for Path in the AuthServer configuration + -Add more info to wdctl status + +WiFiDog 1.1.3beta1: + -Added patch by wireless London to use the GW interface's mac address as the node_id + if no node_id is specified. It allows the use of generic configuration files without + the need to hardcoding the node_id in. + -Added TrustedMACList configuration variable which allows specifying + MAC addresses which are allowed to go through without authentication. + -New wdctl command "restart" which will get wifidog to restart itself + while preserving the existing clientlist. Perfect for 0-downtime + upgrading! + -libhttpd: Fixed two bugs parsing the GET query string making wifidog segfault + + +WiFiDog 1.1.2: + - Added some informations so it compiles on newer OpenWRT's (whiterussian-rc2) + - Fixed minor issue with wdctl + - Changed the iptables rules priority to allow existing NAT rules to work + - read()s from central server in auth_server_request() are + now timed-out (via select). This is hopefully a bugfix to the + thread-freezing problem. + - Bugfix non-RFC compliant HTTP requests using \n instead of \r\n as line + terminations as per email from ludocornut@users.sourceforge.net + - Firewall: make the default ruleset for validating users = allow all + (except sending SMTP) + +Fixed issue with FAQ + +WiFiDog 1.1.1: + - An auth server on port 80 will now work + - Added an FAQ + +WiFiDog 1.1.0: + - Changes: + - Visual tweaks in the web interface + - Internal code & documentation touch-ups + - More debugging output + - Bugfixes: + - Wrong reported uptime + - Invalid http header sent during redirection + - Mixed long/long long type for counter + - Respect SSL setting in auth server definition + - Explicitly allow traffic coming into the router + - SIGPIPE handling + - Firewall destruction not occuring on wifidog termination + +WiFiDog 1.1.0_beta3: + - Completely re-did the iptables rules. Most of the rules are now in the filter table instead of the nat table. Also DROPs are now replaced with REJECTs to help tell the user connection refused instead of endless pauses + - wdctl status will return more informations + - Some error messages are now displayed by the auth server (used to be done in a non-pretty way by wifidog) + - We now 'ping' authserver and detect when authservers are changing IPs + - Fixed memory leaks + - Incoming and outgoing counters were reversed + - More verbose debugging + - ICMP Ping the users everytime we check their counters to keep them alive + - Optional ExternalInterface + - Optional GatewayAddress + - /about URL now shows wifidog version + - Keep track of last times we successfully & unsuccessfully spoke to the auth server/used DNS. Then, if we know we're not online, show a little apology to the user instead of re-directing them to the auth server. + - When pinging auth server now also sends sys_uptime, sys_memfree and sys_load + - Bugfix: Traffic from client to router was counted twice in the "outgoing" bytecount since it increased both counters in mangle.* and filter.* - Got rid of TABLE_WIFIDOG_WIFI_TO_GW completely since it's unneeded + - Do not update the last_updated field on incoming traffic - update it on outgoing traffic only. This should be a much more reliable indication of client no longer being there + - WiFiDog status is now viewable with a web browser at http://ip:port/wifidog/status + +WiFiDog 1.0.2: + - Fix reversed incoming and outgoing connections in statistics reported to the auth server + - Will now gracefully handle auth servers changing IP adress. + - Fixes two bugs in byte counting. (Possible missed data, and incoming and outgoing were reversed. + - Fixed file descriptor leaks + - wdctl_status now returns all connected users. + - worked around sed -i not being available on all platform + - ipkg no longuer overwrites config file + - Several code changes in thread handling and libhttpd to fix occasional hangs. + +WiFiDog 1.0.0: + - Initial release diff --git a/README b/README new file mode 100755 index 00000000..15c6bc87 --- /dev/null +++ b/README @@ -0,0 +1,16 @@ +# +# $Id$ +# + +The WiFi Guard Dog project is a complete and embeddable captive portal +solution for wireless community groups or individuals who wish to open a +free HotSpot while still preventing abuse of their Internet connection. + +The project's homepage is: + http://dev.wifidog.org/ + +Mailing list interface: + http://listes.ilesansfil.org/cgi-bin/mailman/listinfo/wifidog + +The project's software is released under the GPL license and is copyright it's respective owners. + diff --git a/README.openwrt b/README.openwrt new file mode 100755 index 00000000..f40cc473 --- /dev/null +++ b/README.openwrt @@ -0,0 +1,96 @@ +$Id$ + +OpenWRT specific README +======================= + +So, you want to run wifidog on one of linksys's WRT wireless routers! + +OpenWRT is the embedded linux-gnu bundle that runs on the linksys WRT +series routers (among numerous others). + +OpenWRT's home page is http://openwrt.org/ + +---- I just want to RUN the thing: ---- +-DO NOT use the wifidog packages distributed by OpenWRT (you are asking for trouble, they are broken in various ways; you will get no support if you do) +-Use the official wifidog packages on sourceforge (currently only available for whiterussian. + +---- I want to develop and test on OpenWRT ---- + +To build wifidog so that it may be run on the linksys wrt routers you +must first obtain the OpenWRT toolchain. This toolchain is a set of +compilers and other software development tools that will allow you, +running on your intel/pentium/mac computer to compile and develop software +that is to run on the mips based linksys wrt series routers, which is +based on another computer cpu chip entirely. + +You have several options for building wifidog using the OpenWRT toolchain. + +Option 1. get the prebuilt, minimal OpenWRT toolchain (The OpenWRT SDK), and give the makefile it's path. This is the best option, assuming you have a x86_64 Os (the SDK is distributed only for x86_64). + +For OpenWRT 0.9 (Whiterussian): + cd ~ + wget http://downloads.openwrt.org/whiterussian/newest/OpenWrt-SDK-Linux-i686-1.tar.bz2 + tar -jxvf OpenWrt-SDK-Linux-i686-1.tar.bz2 + cd wifidog + make whiterussianipk OPENWRTSDK=~/OpenWrt-SDK-Linux-i686-1/ + +For OpenWRT Kamikaze up till 7.09: + cd ~ + wget http://downloads.openwrt.org/kamikaze/7.09/brcm-2.4/OpenWrt-SDK-brcm-2.4-for-Linux-x86_64.tar.bz2 + tar -jxvf OpenWrt-SDK-brcm-2.4-for-Linux-x86_64.tar.bz2 + cd wifidog + make kamikazeipk OPENWRTSDK=~/OpenWrt-SDK-brcm-2.4-for-Linux-x86_64 + +For OpenWRT Kamikaze 8.09 and up, there is no SDK available and the 7.09 SDK does not work. So Option 1 is not an option. Option 2 is not an option either since building the SDK did not seem to work (https://forum.openwrt.org/viewtopic.php?id=17879). So jump to Option 3! + + If it works (!) you will have an ipkg file in $(OPENWRTSDK)/bin/packages/ + You can then boot up your OpenWrt + router, copy the .ipk to it, and install it using the ipkg commands. + + You should also make sure that the wifidog prereqs are already + installed on the router before you try to run wifidog. Note that if you build the + packages with the instructions above, they will download the required dependencies auomatically (if you have an internet connecion on yout router) and will refuse to install without them. + + The prereqs are: + * iptables command and modules mac, mark and MARK + * iptables kernel module mac + * libpthread + + These are all packages you can install on your running OpenWrt router + using the ipkg commands. If the router is on the net, the ipkg + commands can download the packages from www.openwrt.org, just like + debian apt-get or fedora yum or up2date. + +Option 2. Build your own SDK (or find someone to do it for you) +cd ~ +wget http://downloads.openwrt.org/kamikaze/7.09/kamikaze_7.09.tar.bz2 +tar -jxvf kamikaze_7.09.tar.bz2 +cd kamikaze_7.09 +make menuconfig #(Make sure you build the SDK in "special targets") +make #(could take hours downloading and compiling all dependencies) +Follow the instructions in Option 1, using the SDK you build instead of downloading it. + +Option 3. Use the full buildroot directly (time consuming...) + cd wifidog + make dist + cd ~ + wget http://downloads.openwrt.org/kamikaze/7.09/kamikaze_7.09.tar.bz2 + tar -jxvf kamikaze_7.09.tar.bz2 + cp -R wifidog/contrib/build-openwrt-kamikazeipk/wifidog kamikaze_7.09/package/ + cp wifidog/wifidog-1.1.5.tar.gz kamikaze_7.09/dl/ + cd kamikaze_7.09 + make menuconfig #(Follow instructions on OpenWRT's site to setup your buildroot for your platform) + make #(could take hours downloading and compiling all dependencies) + +For Kamikaze 8.09 and up, there is an extra dependency to add to the package, so here would be the new procedure + cd wifidog + make dist + cd ~ + wget http://downloads.openwrt.org/kamikaze/8.09/kamikaze_8.09.tar.bz2 + tar -jxvf kamikaze_8.09.tar.bz2 + cp -R wifidog/contrib/build-openwrt-kamikazeipk8.09up/wifidog kamikaze_8.09/package/ + cp wifidog/wifidog-1.1.5.tar.gz kamikaze_8.09/dl/ + cd kamikaze_8.09 + make menuconfig #(Follow instructions on OpenWRT's site to setup your buildroot for your platform) + make #(could take hours downloading and compiling all dependencies) + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..b0f95786 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,65 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +# +# $Id$ + +if [ -r Makefile ] +then + echo "Doing distclean" + make distclean +fi + +if [ "X$1" != "X" ] +then + BUILDROOT=`echo "$1" | sed 's/^[^=]*[=]//'` + + OLDCC=${CC} + OLDRANLIB=${RANLIB} + OLDAR=${AR} + + CC=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-gcc + RANLIB=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-ranlib + AR=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-ar + + POSTCONF=--host=mipsel + + export CC + export RANLIB + export AR +else + OLDCC=${CC} + OLDRANLIB=${RANLIB} + OLDAR=${AR} + POSTCONF= +fi + +echo "Running mkdir -p config" +mkdir -p config + +if [ "X"`uname` = "XDarwin" ] +then + echo "Running glibtoolize --force" + glibtoolize --force +else + echo "Running libtoolize --force" + libtoolize --force +fi + +echo "Running aclocal" +aclocal +echo "Running autoheader" +autoheader +echo "Running automake -a" +automake -a +echo "Running autoconf" +autoconf +echo "Running ./configure ${POSTCONF} --enable-maintainer-mode $conf_flags $@" +./configure ${POSTCONF} --enable-maintainer-mode $conf_flags "$@" + +CC=${OLDCC} +RANLIB=${OLDRANLIB} +AR=${OLDAR} + +export CC +export RANLIB +export AR diff --git a/configure.in b/configure.in new file mode 100755 index 00000000..4bf10f46 --- /dev/null +++ b/configure.in @@ -0,0 +1,105 @@ +## -*-m4-*- +# $Id$ + +dnl Process this file with autoconf to produce a configure script. + +# FILE: +# configure.in +# +# FUNCTION: +# implements checks for a variety of system-specific functions + +AC_INIT(src/common.h) +AM_CONFIG_HEADER(config.h) +AC_CONFIG_AUX_DIR(config) +AC_PROG_CC +AC_PROG_CXX +#AC_PROG_RANLIB + +AC_SUBST(BUILDROOT) + +WIFIDOG_MAJOR_VERSION=1 +WIFIDOG_MINOR_VERSION=1 +WIFIDOG_MICRO_VERSION=5 +WIFIDOG_VERSION=20140822-v1.0.0 + +AC_SUBST(WIFIDOG_MAJOR_VERSION) +AC_SUBST(WIFIDOG_MINOR_VERSION) +AC_SUBST(WIFIDOG_MICRO_VERSION) +AC_SUBST(WIFIDOG_VERSION) +AM_INIT_AUTOMAKE(wifidog,$WIFIDOG_VERSION) + + +AM_MAINTAINER_MODE + +AC_PROG_INSTALL + +AC_LIBTOOL_DLOPEN +AM_PROG_LIBTOOL + +AC_ISC_POSIX +AC_C_BIGENDIAN +AC_PROG_MAKE_SET +AC_HEADER_STDC + + +# check for doxygen, mostly stolen from http://log4cpp.sourceforge.net/ +# ---------------------------------------------------------------------------- +AC_DEFUN([BB_ENABLE_DOXYGEN], +[ +AC_ARG_ENABLE(doxygen, [ --enable-doxygen enable documentation generation with doxygen (auto)]) +AC_ARG_ENABLE(dot, [ --enable-dot use 'dot' to generate graphs in doxygen (auto)]) +AC_ARG_ENABLE(html-docs, [ --enable-html-docs enable HTML generation with doxygen (yes)], [], [ enable_html_docs=yes]) +AC_ARG_ENABLE(latex-docs, [ --enable-latex-docs enable LaTeX documentation generation with doxygen (no)], [], [ enable_latex_docs=no]) +if test "x$enable_doxygen" = xno; then + enable_doc=no +else + AC_PATH_PROG(DOXYGEN, doxygen, , $PATH) + if test x$DOXYGEN = x; then + if test "x$enable_doxygen" = xyes; then + AC_MSG_ERROR([could not find doxygen]) + fi + enable_doc=no + else + enable_doc=yes + AC_PATH_PROG(DOT, dot, , $PATH) + fi +fi +AM_CONDITIONAL(DOC, test x$enable_doc = xyes) + +if test x$DOT = x; then + if test "x$enable_dot" = xyes; then + AC_MSG_ERROR([could not find dot]) + fi + enable_dot=no +else + enable_dot=yes +fi +AM_CONDITIONAL(ENABLE_DOXYGEN, test x$enable_doc = xtrue) +AC_SUBST(enable_dot) +AC_SUBST(enable_html_docs) +AC_SUBST(enable_latex_docs) +]) + +# Acutally perform the doxygen check +BB_ENABLE_DOXYGEN + +# check for pthread +AC_CHECK_HEADER(pthread.h, , AC_MSG_ERROR(You need the pthread headers) ) +AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(You need the pthread library) ) + +# libhttpd dependencies +echo "Begining libhttpd dependencies check" +AC_CHECK_HEADERS(string.h strings.h stdarg.h unistd.h) +AC_HAVE_LIBRARY(socket) +AC_HAVE_LIBRARY(nsl) +echo "libhttpd dependencies check complete" + +AC_OUTPUT( Makefile + wifidog.spec + wifidog-msg.html + src/Makefile + libhttpd/Makefile + doc/Makefile + ) + diff --git a/contrib/dump_fw.sh b/contrib/dump_fw.sh new file mode 100755 index 00000000..37552efd --- /dev/null +++ b/contrib/dump_fw.sh @@ -0,0 +1,5 @@ +#!sh +iptables --list --table filter +iptables --list --table mangle +iptables --list --table nat + diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile new file mode 100644 index 00000000..f420c854 --- /dev/null +++ b/contrib/wifidog/Makefile @@ -0,0 +1,69 @@ +# +# Copyright (C) 2006,2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=wifidog +#PKG_VERSION:=gateway +PKG_VERSION:=20140822 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:= @SF/$(PKG_NAME) +#PKG_MD5SUM:=b992869cb6607d89362f2fc09a727af9 +PKG_MD5SUM:=7241d86b46bbfeef54fb72e48a56dc8c + +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/wifidog +# SUBMENU:=Captive Portals + SECTION:=wifidog + CATEGORY:=Wifidog +# SECTION:=net +# CATEGORY:=Network + DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +kmod-ipt-nat +iptables-mod-nat-extra +libpthread + TITLE:=A wireless captive portal solution + URL:=http://www.wifidog.org +endef + +define Package/wifidog/description + The Wifidog project is a complete and embeddable captive + portal solution for wireless community groups or individuals + who wish to open a free Hotspot while still preventing abuse + of their Internet connection. +endef + +define Package/wifidog/conffiles +/etc/wifidog.conf +endef + +define Package/wifidog/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_settings.sh $(1)/usr/bin/GET_settings + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/dog_conf_generator.sh $(1)/usr/bin/dog_conf_generator + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/white_black_flush.sh $(1)/usr/bin/white_black_flush + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/wifidog.conf.bak + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/conf/* $(1)/etc/config/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/etc/devicekey $(1)etc/.devicekey + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog +endef + +$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/wifidog/files/wifidog.conf b/contrib/wifidog/files/wifidog.conf new file mode 100644 index 00000000..fa6ec558 --- /dev/null +++ b/contrib/wifidog/files/wifidog.conf @@ -0,0 +1,281 @@ +# $Id$ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + + +# Parameter: WhiteList +# Default: none +# Optional +# Comma separated list of url who are allowed to pass +# through router +#WhiteList www.baidu.com,www.taobao.com + +# Parameter: BlackList +# Default: none +# Optional +# Comma separated list of url who are not allowed to pass +# through router +#BlackList www.av123.com,www.av456.com + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + + # FirewallRule syntax: + # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X]] [to IP/CIDR] + + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init new file mode 100644 index 00000000..31a4406a --- /dev/null +++ b/contrib/wifidog/files/wifidog.init @@ -0,0 +1,32 @@ +#!/bin/sh /etc/rc.common +# wifidog start on boot +#2015-08-12 +# + +START=99 + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print the status of the service" + + +start() { + /usr/bin/dog_conf_generator & + sleep 1 + /usr/bin/wifidog-init start + sleep 1 + /usr/bin/white_black_flush & +} + +stop() { + /usr/bin/wifidog-init stop + sleep 1 + rst=`ps | grep white_black | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi +} + +status() { + /usr/bin/wifidog-init status +} + diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100755 index 00000000..85cc11d5 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,52 @@ +SUBDIRS = + +docdir = ${prefix}/share/doc/wifidog-@VERSION@ + +EXTRA_DIST = \ + doxygen.cfg \ + doxygen.cfg.in \ + README.developers.txt + +all: + +doc: doxygen.cfg + echo "doc: " && pwd && echo "distdir: " && echo $(distdir) + rm -rf html/ refman.pdf + $(DOXYGEN) doxygen.cfg +# $(MAKE) -C latex/ +# mv latex/refman.pdf ./refman.pdf + +dist-hook: doxygen.cfg + echo "dist-hook: " && pwd + cd $(srcdir) && pwd && rm -rf html refman.pdf && $(DOXYGEN) doxygen.cfg + cp -rp html ${distdir} + +clean-local: + echo "clean-local: " && pwd + rm -rf latex/ + rm -f *~ + rm -f doxygen.log + rm -f doxygen.cfg + +maintainer-clean-local: clean-local + echo "maintainer-clean-local: " && pwd + rm -rf html refman.pdf + +install-data-hook: + $(mkinstalldirs) $(DESTDIR)$(docdir) + mkdir -p html #Workaround to allow libofx-cvs user to install without doc. + cp -rp html $(DESTDIR)$(docdir) + +uninstall-hook: + chmod +w -R $(DESTDIR)${docdir}/html #Why chmod is needed is a mystery + rm -rf $(DESTDIR)${docdir}/html + +## We borrow guile's convention and use @-...-@ as the substitution +## brackets here, instead of the usual @...@. This prevents autoconf +## from substituting the values directly into the left-hand sides of +## the sed substitutions. +doxygen.cfg: doxygen.cfg.in Makefile + rm -f $@.tmp + sed < $< > $@.tmp \ + -e 's:@-top_srcdir-@:${top_srcdir}:g' + mv $@.tmp $@ \ No newline at end of file diff --git a/doc/README.developers.txt b/doc/README.developers.txt new file mode 100755 index 00000000..d19645dd --- /dev/null +++ b/doc/README.developers.txt @@ -0,0 +1,37 @@ + +$Id$ + + +This file contains some small notes on developing the WiFiDog application. + +The application's home page is: + http://www.ilesansfil.org/wiki/WiFiDog + +The application's sourceforge page is: + http://sourceforge.net/projects/wifidog/ + +As a developer, you must subscribe to sourceforge as a "developer" under WiFiDog, as well as subscribe to the WiFiDog mailing list located at: + http://listes.ilesansfil.org/cgi-bin/mailman/listinfo/wifidog + + +SOURCE CODE: + - Please do not contribute unless you agree with the GPL license and are contributing your portion under that license. See the included LICENSE.txt + - Please respect the intellectual property of others. You are not allowed to taint WiFiDog by including source code from projects that do not allow so. + - Keep in mind that this application will run on extremely simple embedded devices. The binary size needs to be small, the dependencies absolutely minimal, and the memory footprint negligible. + - Always place the subversion "Id" macro at the top of every file + - Since this is a collaborative project, please aim for clearness instead of cleverness when faced with a choice. + - If you must use some cleverness, please add appropriate clear comments. + - Please re-indent your code before committing to subversion - see the "Formatting Your Source Code" section in the GNU Coding Standards at http://www.gnu.org/prep/standards_toc.html - the entire document makes a good reading if you haven't read it before. Also see the "indent" program. + - Before writing any brand-new large chunks of code, make sure it's logic has been discussed with the other team of developers or included in the design stage. + + +MEMORY ALLOCATION IN SOURCE CODE: + - Safe versions of C functions that allocate memory (safe_malloc, safe_asprintf, etc..) have been created in safe.c . You must use them instead of the original functions. + - If you need to use a memory-allocating C function that does not have a safe version in safe.c, create the safe wrapper first (following the template of the others) and use that instead of calling the original. + + +DOCUMENTATION: + - Please use DoxyGen-style comments (see http://www.doxygen.org/ for details) for source code documentation. + - Please use DocBook-SGML documentation for user documentation. This will make it easy to export documentation in multiple formats. Otherwise submit your documentation in plaintext format to someone who will change it to DocBook. + - Please thoroughly-comment non-clear sections in your code. + diff --git a/doc/doxygen.cfg.in b/doc/doxygen.cfg.in new file mode 100755 index 00000000..41b0857f --- /dev/null +++ b/doc/doxygen.cfg.in @@ -0,0 +1,1294 @@ +# Doxyfile 1.5.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = WifiDog + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = YES + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @-top_srcdir-@/src + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = @-top_srcdir-@/libhttpd/ + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = letter + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/doc/wifidog_firewall_diagram.dia b/doc/wifidog_firewall_diagram.dia new file mode 100755 index 0000000000000000000000000000000000000000..2946cc770d0ac8c8bafbb34fab1a9bdff80b0af0 GIT binary patch literal 8702 zcmVEt z=A-H4+hRUhn1&&IXGCeQ)*M!D2BR zz5B2j_9lbN;kVD;4Nm{Km`y)S&Ymr=T3vTK9ZzSyKL_J)pZ)DT{dx9$b(`n6?(@LC zuLc*xceCN(kLFv;_$P!-ZhbYJ-M#JQ)pS0Jmn=SA-MggWKJ@<^*Q~CZ$BQNx-~H_c z{B8M`R^Rw?uevwdc*x>%FuNE{?w=EXH{<0mLJQPd$6tmG7^DZUu74-%ANQ`?0lfmv4_OUkm7u_SWF*z|L248 zyo~_MZ-3Udbv5^5HadG)ac^DGaF>sxv&H+9e=_~LmUsWeboW0;^U=HUuH}U`oEyJ|>AU|oJYB5B`(Zr&c=~=YTlD_k`+oY* zXJ6co=yZ(EzI}EmZ~uPoN)+!FP2as=(AD(wQ)DW*EAM@4(RAx~@9y4t7T^3}axorW zTk&8k6aUv&QW#e`;q7L}4adXFlhf&Ja^D}=hBWE+$z-}(a z@qW>Km=<2%`lB~HZ2o@w@ubEsAOIpu0_c6J;2?uaABhM)Ul_|JR4rMp((&NWTH ziRAy?y6%pvc)5IX-yR(t9sYLw`pu6Gp5p`Nwh6nZlSSRh^!?uX;Bqwn6yM-rGJn>a zFFui7hzh>^(f=5Z{~Rtxr-Pg3YyEd{?|G~Jknr|1Cn4|9+oq>ZVV!W+R#rgJHt($4 zDD*(6B4yq|(Z{=(Tn_6$(Bb66Weq$(1kiOD(}a`Hzd*$1n4xkp!&b^Nf(8(1C`hQG zgwj5~a`6=>aBMD88{}|8dJi{{!!sg>5}{Fv3v%!v$7HZ5u+brGppXWac0m^8=nOe@ zE^>s*1V-e*6mDQb4)Q7DE0D~{vAIa?kOLq@=SblSKd>OjKE@nB93K7t;^_S0~?vTUeBL}b}2P}~Tgmdwg`cL%_&vn{KYt@*O(=sswmP=uurtuMr4$%-ZG)RIAtB~zNil--Q!kB76%(PS{L z3G6Z3FB8ESAHC`z6sKP%5Ld^@B_{>YS4t|OScCk0@!ACY$_Q`}te4=t52zIO-__(_Xyca28EjFKXy;c0M>Amc$7^N7Ol|O|-UBXwW5b@>t@e=>Z#$u1?-Z z5A%QG6BW_;A#-r2|8(tRBGA+Gn19GN!={iQHhoUv@y1OmJ@8=_H|dZL4IBF!Z3Cw| z=^nVwKO7D%wYKF|o4ao%Y${>XW?_@f37e2RYI-#qTuxJq@x8vU>}FvtjIlOUMhX`+ zvNjHDygmsuQX`l))>p~RPUH|iTHl&X+F4DpPF z04ZeY7TZtMIQ;GS$HRgeorWG(NE1y$fsC$s|0=ud_y*$h)_i>`s>Wkd&3E}K7-q6; zy>!jj1@#CE_H%K#^@XO?eM{Z9)4H$9V*Xq1!f%5MY`2k$*X%y9QYjga0%?Q-rBv9{ z@tU=?tNqPfO7V*K-7B697R4p*A{!6NAQ_0_6?d3O$!>%-rc#bGAD>nYD4M9y2NV6^ zN_l1s$q=b!GR1`g8+!>G^!4QU@Pwu)92^z!=mtCt3Imo5L&1&?u_L?fScOWnvVqd{ zPc2tzc&#hVO$W*lsTFo8p~~c){l<>hZz6QOIXEup(OKwW(UNH>=+Pm1;1=>%hChF0 z)R!Wz=^%S$bSdK&^jIG~etYxNo5SDV6wv6hglkH+s#DAeTZlNovPT?g${95vM9cuk zA8~*!m{Bleea!gr=fm$`{9GWTvp6F{29(Waoo+Uh+Xyo(f0%I%8NrwsX!wnJKJ5by z%iD5b)Qx%3{^<>nDuA&*V7&P4_&(koN+y1*5m9(|zdC>k^cS31O%>>g<4H(qPs4p>}5mg|@#T1ZnV zny2AdCp2Y<)e2g)u;`5OK?i_ft!ACeWWA#~P}W6+0dHKvmK|Wr*>JuXO@?PQto7n! zFN!%E&gTVQ*uxehbbL<8I|U;{ftM|Jx!vh+`wT7ljnQ9-*qr@sM8uNb&@mVvls+Ac zkchs~FWE4@pjMlc;pFVmHn(~qA9#v4M5Xw|oL=31A79|E^nC5E=PPU2r@qrMCbzxr zrAfWB+gGDEM?MhQWsL}&8XiwF%2m;q1n{<>YUM#CM6lX&Yj~5K4RrsFi?l_>pX@%T zJ4y;`Z9#Fjf7oxmt@G_*HW-hG2=I@7t*-84WAJ``@|H>t?Uk0;3dO!Sr^2>{(pH33>t^}3b zL8Vo~DXl79N?|N1%SR!}ZGlW-B|Dh{!fNJ#wb22!nx9OusZi}^4p^z&4OnsomI^F2 zjiNtz_4?@G<#Eb)4i>|YgHHvQI^bw%E3u0BRDh}DTAJU+00Z{<1u05`_*Z3p1;QA# zj(dawE4|NI7h=d4JUE4{^gcrg9P5DCgvy$*X$i6v(lQEZ^IrUw%ooG6-Y+j+7C>Pi zXy9q`IL1K7qbuu8I;);#_oPM>A5Ei=ADjbVU8F@PNlK@SXoQ37gQo%-&?6%yI_C6x zqnvd)J7I`tRMP8vmR|Q6>2+;6((5fWJiCJsjBp{RVAM{#<0%@D&Ornu?UvwNMUjTF zid(zuWURT&iRhO_BLGFW_pCa8r}~BK=(aH&6Hy=6ZIj>Xbxrr6wOfvr{t{2p+NG1E zOZ1n37#%((VnD#H-;HuM4@Xf&#rL~9zLttBzq@U>Cc7&~;l_~Ft_b1N*fEm^$I!s8 z=$0EPz*t~qPj4<(EB3SzN`rC1t7x$tW}Wp|(#HvdHaa>^fwR;GRM^vF(o&)<1_bol*?RiHXLk}% zfK@gpm16Wr=`IWeev?;!Q12FXL9?Q;DnaaSJ8tgG?oti z%xy+6JJU4o^n&x~oUJPetXf%5!*IAlx<&%k! zp$zxzXxV_tW|wPK@p^~}NUTfLG%Z|o3oDD$NS=@fX>OSx}@a-kGEJ zLrn&vtgPt{ML=$2@Rtniqra5IH2llco-?H+GmPX&RW_adwNd2rcFY1EUCrv!l;R_+ zPy&$dphIl|I)Y?J4h&y_BPf2{2(rLNfsM@-@sFB_10=C+8Dq%a+ zpiMNDw+S_@FvhydBR2(pbD>(|hDPgH6IW$5W@k`wYc*!Ui>~lO5>*{5?+azUOT@@- znsTy2&H*|$4Fblr!OWomqkM&qyI#JzQ0>a)29;OnulFkJ5_aq*mi&D9@~4AW1xC87 zmxEA22C@((@aPamU<=GE);VlT;#Gia-jxZy3XY$46Js87wAdh1RS)l{Xiv-6Z$` z)_VgEX-XG(#kx{Cc#Y`daoPt|n+}aAL&17EE0xb@)5~6bzJ{|&6lHWiI2{&X;RY6^ z=;05QwZdsE`;dbbon-2POuZF=j&vQ$m5UC9N5fhI-CV48nFwc{ zRq;P3$$NB$)q6A=we_e`>gYZC;ymtPjnI5Ch(GZ9P0CFax3PozXng7o`2a@V9HLy@ z#%@-oLUwbpbwWAn!r&zI(;;fv>Oq-qDWud`ImJw|$(5}Q$QWv3xv@UAjG8Q?CL0mz z)zRVGf=cYDMAW^IJlMk8=`fj*-JWc8YPHP?-`g%twOV;P$2kLipmE13T^`Lha*vs; z7qUJ&!U$kcmgDT(47!jp#|G|BMDJ=;mCbG(wU8q6yvMqo!nh*C_$F{L0(wXEiE1NjszabaK@7 z%AxSVa>IC|oV6=zrIL=`n049}Mc;2lUklBx=H5`!T$iwV3;U>*wkq$*Zo7|K`qfEF zyS`N-fYX&XG$~%ORw=e2WIMKt_e!D-*K8MLtyf??1$4j_+XYL(Vh06_i};*fL{rd< zw=86rjuw%u@YpM%z!$Ph=T!@9wh&21>xGq5%DjH$flu3BWu)&^>v z0O`RyX;urebg5dDszn1#osI{WSH0txZ-4pq*Md%6RWA}cmFh)T)eD>5EEYo&3>1o2vZ9$4+Akd%yKxIt`^-m^oHdumH>N^_vQom>w^95$BfDvLv?$AF z_wZ1~Fwk@u&T;$@1Ug9S979>4L1x~WsBqD1bC#QFT_@rLlQBvtTr1<#4g@K*REBm|Ii0nn;L)s6hFC4PASkPhmIh2JPH^^8SlaOAoK#+UA5be> zY7@JxO$hlaZtk&ZFl9nRt@K z=)}?bWa76)r%q{02ct#cX0SGiS;t`&-da@^*2}){V$9lGPo>T-dw=Ut>M zF*bS85OF)68MLWP46lM^PyN(LSTkfycqd)de<@thMZNc}`6Mg9tK{zZ zsxE*13{;+VahXYr1eSZtT#OtMDl{}F2U!`an~T*d_oJf|Pc%`b!GlwQm6oclMj0e1 zi&{FPOX{bje*RJeHGI$&DxqDO!`3}D)n)fY*ia!WD>c;@{F0Mu1duz4?3~oig=&K^ zAV4aEnk;`AqEYCm55m)nmoE?A9v3WPA2uB^NJ>vwREVhEl_8wj!bm6b*V6~5S!aUM zNzz4Vpe8)sw?RO(;&iZ;ioFB3Nz6L<62{S$C7H2b$qc75st``^hKB0$_maqEA`dxf zs3Ag*PUb&AprLJu-cvfm%1!sAx7O`C0quyM@^q zOTHyCv&&H_+G!X}NbJ+7*M=fWMmiHMVL+o0$_|*$ z^E>Yc^WG1?pZxOT=%>}H%9870uRBmLr&ARY9|20Lr=wI)b~6K+c|~U43U3wb#$#$| z@QzLb@XI0IApq?(1-t2%`SxyOlbj7(lFRy+{fh}*&OAlKz5eCV!eTbN+%xYqcQB1m&;I^lKAiPtAI8IZ@jkh| zPY*<6@Z?LBN@IuaXLd7$Lt&6UILkY*pUyGTCg(F?=+odE?HoNYRx0j+Hw{wOf!VUm zSel*oEo*5q+U4DjW_f$LjalA_jc5`pmovJICrLy)Ng<8AQBlE_A#c>!&_Pk6Ud{&+ zB~WyHzo`W4>A2fX*OOOUm|C}dpgpC&6|as5kbzEusBV3$g;mN`K?-dg|IoU6F>5Z> zLYnxlih}QV0%^UOH;Q}a&0`59pUq5mb~$_hG8_Im8h-3WbJB~NKDikFpMNcWXa`HBkoZtEiLdyf-T9%} zO&2hk`GD=zjU3Dre!i2W~&K zx#_~^H(fXZ=qL~Afq5G-m~@T{hT1QT(^Wv~k7o5n^Tlg9{u{NE;DU6LfBbh)Mrs4J z8J)&|yV8WQ%O;GsM~C0PIDUQjrg)L;eHdDp5ULQp1klBY?8t}QMjM7vnm#rcc+;6E zG<9Kw>n;o>B<*4gU3Fp9idkQkD@_>t=ScdjCJfjS5iYy+Vnqp2BJgf?3|a;{1`R0U z$DsF$e7k^weeGL~h|Tzv;cgb?{#vRP>-FY)x4YhaAM(S*N=Z&~OiI2~A(3OOkD5&f z#_u`98y;>hR*4HsT=-yI_|u!i-%Cu`MQ?t5?xP+X>bNdJVK+e`$}KpJ$yY+*tmE|? zL0hDQY|!L3f}_Vp3avc9*H|ax0}pYbRquI7xL$1`?51x5)fVV$(esH9w5GWjybLz) zZAd4FN^k%j@YiaEtWEeVuPW-jXX+ht_Pp(=^%3JyF+6?Zz z(9&b2l;m!Z$`!BO0uL3OQ_dC2YN4z?l0rH<_`e4)%l?ioI-{fwOHV=-HbG~JBiK%7 z6n$*`tx<;JHl(RKX_*uRw}d3=J86x&D`d@6Y=qHP7teDK>y0wQ^F*_w&@!8FZX`YV zo>#f)5a}=;O`!$3MyJ?Za3ZWSv32}^38MRWre%@$90EH z0?a0yD_0?BK3F9p0Xm8zwG+x=>Sk6>vl7iS#A-z(kU}Z+Xp~3kG)m37WH?6RP6ApC zTGHPNk)ZP>!{@!@!`>g0>BmX$bUca;e3D&ZpzfRBsBiT8zkM znrkn>lge?{BIpoJhon+O3=M-ffyUJERw8m`YvV`8BfynS;-wPNev^1FdMl+S(TxXc zu6K%uG9{x+4>Y?!f-((?26X2*UhTjs`kc;daswft>qpcGR4FGXR4VpK8BKE5!Wn`h z@3^?3`{jmWPM0I%?#5+=Y|^@cij%8u(u&eFt_^6>RN|fqK;9u4n+w%4bs416Us9Kf zHFXKJpA-SXS*7i!4Ob;~nU%Wy;pp&}lDzEJbqoTmbQQ)&#$%zgY{hk4C%F;S7Mg55 zdyB1Gb=Vp-Rp6cky0Jhln`@0RQtPl9K941rQF0j#pfn#YdV{O0+4O2Q8pNNw9L)ac zMfdb7em27bPhE8BI_HRBQxY59B{o8KqYs54k~WRyFp=896V0b4#Gt%}i~&#@-A5-| zsRB18t5MF{nSyDJVM%N3S6bsPv1+ZfMo_!qTZZiZp6Es?w7xPrYJlZTUD8P!=^zB} z`brD0T@?ct75zBw>UootHJ56kHN;Cx;&R{W=Q$d#Ia>KzC^&3E!BGZZ(Sku8^mvBK?6E@$D)JnI5 z@RU!lFzR&hNb3u2u#Sk;(mHPDTb+pauL=Sk(c_+yVvpmeev$(HX3Z`(V~5TCIfOdc zkwf6NU@|;LtPIRcJ>oGEr6#LkrSxPq5Q3s<%(Qfl-)huJSqw)p99!tkgs;$W_$?R? zBw}pND65v1!&$FamLnv81B3L-A&<)NTaH>Wi|Ht)V+(N#eubtZo48Mlyo`kkSc&@} ztX7t`h6S+Lr$aF~N(xxXzW$+3#2Q*82&Vw!dnz`g*o?Mu3gjd=wA+!@$fi|$VS;i{ zX_NlKIe$!Oi&~|VjJJJil%Y*BM#d<@a!-3{l(WV;5#C9c-k1xz6e0Ia({;{D?7Q`i z?eCa49?mXDlfk$~+i7-nF1xzoOk$EVU(rJBzLGSSJ5+|5|F*F_?OOQ^1oRlR@;;!J zPmunW{EA2QN!=kMqVPB`g1rh3_tdHio$sa(T6Dvzg7&trsr!sx;lA3osIq{K2Q;8AJYHx!Fax* z0Z7M045!C2|B&s(3rc2F=&v6_!x}0m3o%j<0fJO9Qc#vQm(%Q+z)f?gk+1e5Ybz+B z!M?GV?oNJNi@zjylLSyQn}du(8l-%@VK1RpX>q?=}!Eq~gy^PJ7 z0#zdaeN*qO6rbANc1b1kImi`fS%6~xG;Os{EI~smPP3d9??A{3S$nEIQa>;_w6s@J zv+k87lVe;wO;e&lm6qxqv{awZrkB0=bPZ>dD9Y%3a5^k8Eq_eALfd$@K~sX-ZrawA z%qG2i)>dj8T}6aI&D2JjKF#V!Pp$V-Tkf4yw03l@3XNWG$^%EHF4eN9viq)k}DJ7@X3NbAL{u>~@|#iHPQ58i9lSk#WDK+y8i zTn*RDM_==6xL#?vjw-I*QpH1{leyzFe>e~#sPDsH*w*S?(%&xYqw(a+*v zr>DdDyjJ5we$fRichx0LvF$rSJC8N>W$+R%Hy5c*)y2|4DzB`K{=G2@!4<}3VO$o* z<#m z=!4K;eTaxpJT309p;68U6te^ldpGis^!j5wLDw|jR`I+Xds+$;*OHhPp0X#(w zQY&2{2x%nuxR^Q#YYKc7nvxONL&Xj`)N0sK)=yp`;l}LBE6*mmS`}kpRIJ^OnieBio!T9Z zH2rv{kyb_3woJ=lzZiH?>eZ>fUl}0EO z_oui&#r-Lkr)$fjvk8}AnB5;k7AIOBI;U8kVtMX8a>epIWy{l4meTngP#S{ed=(^b zbEq*06$TN2sABQZ;8Ybr00i#MUv(nZwva;5whB*-3R<@KJndQ+VopKZ<_?coz8()g c4QJndvwRW%yO<3wzx(EY0d`2g%YSnM0GHJxJpcdz literal 0 HcmV?d00001 diff --git a/libhttpd/Makefile.am b/libhttpd/Makefile.am new file mode 100755 index 00000000..0338fca8 --- /dev/null +++ b/libhttpd/Makefile.am @@ -0,0 +1,19 @@ +# +# $Id$ +# + +lib_LTLIBRARIES = libhttpd.la + +libhttpd_la_SOURCES = protocol.c \ + api.c \ + version.c \ + ip_acl.c + +noinst_HEADERS = httpd_priv.h + +pkginclude_HEADERS = httpd.h + +EXTRA_DIST = README + +#AM_CPPFLAGS = \ +# -I${top_srcdir}/inc diff --git a/libhttpd/README b/libhttpd/README new file mode 100755 index 00000000..6d720519 --- /dev/null +++ b/libhttpd/README @@ -0,0 +1,23 @@ + +Welcome to LibHTTPD, a library for the creation of embedded web servers. +Complete documentation is available in the PDF file location in the doc +directory. + +To build this software simply run + + ./configure + make all + make install + +The software will be compiled and installed into /usr/local/lib and +/usr/local/include. To use the software you will have to include the +library's header file into your application and link against the library +itself. Details are privided in the documentation. + +This software has been developed by David J. Hughes (aka Bambi) of +Hughes Technologies in Australia. You can always find a current verion +of this software at www.Hughes.com.au + +This software is released under the GPL. If you wish to incorporate +this code in a commercial application then OEM licenses are available +from Hughes Technology. Please email info@Hughes.com.au for details. diff --git a/libhttpd/api.c b/libhttpd/api.c new file mode 100755 index 00000000..afc205ef --- /dev/null +++ b/libhttpd/api.c @@ -0,0 +1,1067 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#include +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "config.h" +#include "httpd.h" +#include "httpd_priv.h" + +#ifdef HAVE_STDARG_H +# include +#else +# include +#endif + + +char *httpdUrlEncode(str) + const char *str; +{ + char *new, + *cp; + + new = (char *)_httpd_escape(str); + if (new == NULL) + { + return(NULL); + } + cp = new; + while(*cp) + { + if (*cp == ' ') + *cp = '+'; + cp++; + } + return(new); +} + + + +char *httpdRequestMethodName(request *r) +{ + static char tmpBuf[255]; + + switch(r->request.method) + { + case HTTP_GET: return("GET"); + case HTTP_POST: return("POST"); + default: + snprintf(tmpBuf,255,"Invalid method '%d'", + r->request.method); + return(tmpBuf); + } +} + + +httpVar *httpdGetVariableByName(request *r, const char *name) +{ + httpVar *curVar; + + curVar = r->variables; + while(curVar) + { + if (strcmp(curVar->name, name) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); +} + + + +httpVar *httpdGetVariableByPrefix(request *r, const char *prefix) +{ + httpVar *curVar; + + if (prefix == NULL) + return(r->variables); + curVar = r->variables; + while(curVar) + { + if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); +} + + +httpVar *httpdGetVariableByPrefixedName(request *r, const char *prefix, const char *name) +{ + httpVar *curVar; + int prefixLen; + + if (prefix == NULL) + return(r->variables); + curVar = r->variables; + prefixLen = strlen(prefix); + while(curVar) + { + if (strncmp(curVar->name, prefix, prefixLen) == 0 && + strcmp(curVar->name + prefixLen, name) == 0) + { + return(curVar); + } + curVar = curVar->nextVariable; + } + return(NULL); +} + + +httpVar *httpdGetNextVariableByPrefix(curVar, prefix) + httpVar *curVar; + const char *prefix; +{ + if(curVar) + curVar = curVar->nextVariable; + while(curVar) + { + if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) + return(curVar); + curVar = curVar->nextVariable; + } + return(NULL); +} + + +int httpdAddVariable(request *r, const char *name, const char *value) +{ + httpVar *curVar, *lastVar, *newVar; + + while(*name == ' ' || *name == '\t') + name++; + newVar = malloc(sizeof(httpVar)); + bzero(newVar, sizeof(httpVar)); + newVar->name = strdup(name); + newVar->value = strdup(value); + lastVar = NULL; + curVar = r->variables; + while(curVar) + { + if (strcmp(curVar->name, name) != 0) + { + lastVar = curVar; + curVar = curVar->nextVariable; + continue; + } + while(curVar) + { + lastVar = curVar; + curVar = curVar->nextValue; + } + lastVar->nextValue = newVar; + return(0); + } + if (lastVar) + lastVar->nextVariable = newVar; + else + r->variables = newVar; + return(0); +} + +httpd *httpdCreate(host, port) + char *host; + int port; +{ + httpd *new; + int sock, + opt; + struct sockaddr_in addr; + + /* + ** Create the handle and setup it's basic config + */ + new = malloc(sizeof(httpd)); + if (new == NULL) + return(NULL); + bzero(new, sizeof(httpd)); + new->port = port; + if (host == HTTP_ANY_ADDR) + new->host = HTTP_ANY_ADDR; + else + new->host = strdup(host); + new->content = (httpDir*)malloc(sizeof(httpDir)); + bzero(new->content,sizeof(httpDir)); + new->content->name = strdup(""); + + /* + ** Setup the socket + */ +#ifdef _WIN32 + { + WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD( 2, 2 ); + + err = WSAStartup( wVersionRequested, &wsaData ); + + /* Found a usable winsock dll? */ + if( err != 0 ) + return NULL; + + /* + ** Confirm that the WinSock DLL supports 2.2. + ** Note that if the DLL supports versions greater + ** than 2.2 in addition to 2.2, it will still return + ** 2.2 in wVersion since that is the version we + ** requested. + */ + + if( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) { + + /* + ** Tell the user that we could not find a usable + ** WinSock DLL. + */ + WSACleanup( ); + return NULL; + } + + /* The WinSock DLL is acceptable. Proceed. */ + } +#endif + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + free(new); + return(NULL); + } +# ifdef SO_REUSEADDR + opt = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int)); +# endif + new->serverSock = sock; + bzero(&addr, sizeof(addr)); + addr.sin_family = AF_INET; + if (new->host == HTTP_ANY_ADDR) + { + addr.sin_addr.s_addr = htonl(INADDR_ANY); + } + else + { + addr.sin_addr.s_addr = inet_addr(new->host); + } + addr.sin_port = htons((u_short)new->port); + if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0) + { + close(sock); + free(new); + return(NULL); + } + listen(sock, 128); + new->startTime = time(NULL); + return(new); +} + +void httpdDestroy(server) + httpd *server; +{ + if (server == NULL) + return; + if (server->host) + free(server->host); + free(server); +} + + + +request *httpdGetConnection(server, timeout) + httpd *server; + struct timeval *timeout; +{ + int result; + fd_set fds; + struct sockaddr_in addr; + socklen_t addrLen; + char *ipaddr; + request *r; + + FD_ZERO(&fds); + FD_SET(server->serverSock, &fds); + result = 0; + while(result == 0) + { + result = select(server->serverSock + 1, &fds, 0, 0, timeout); + if (result < 0) + { + server->lastError = -1; + return(NULL); + } + if (timeout != 0 && result == 0) + { + return(NULL); + server->lastError = 0; + } + if (result > 0) + { + break; + } + } + /* Allocate request struct */ + r = (request *)malloc(sizeof(request)); + if (r == NULL) { + server->lastError = -3; + return(NULL); + } + memset((void *)r, 0, sizeof(request)); + /* Get on with it */ + bzero(&addr, sizeof(addr)); + addrLen = sizeof(addr); + r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr, + &addrLen); + ipaddr = inet_ntoa(addr.sin_addr); + if (ipaddr) { + strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN); + r->clientAddr[HTTP_IP_ADDR_LEN-1]=0; + } else + *r->clientAddr = 0; + r->readBufRemain = 0; + r->readBufPtr = NULL; + + /* + ** Check the default ACL + */ + if (server->defaultAcl) + { + if (httpdCheckAcl(server, r, server->defaultAcl) + == HTTP_ACL_DENY) + { + httpdEndRequest(r); + server->lastError = 2; + return(NULL); + } + } + return(r); +} + + + +int httpdReadRequest(httpd *server, request *r) +{ + static char buf[HTTP_MAX_LEN]; + int count, + inHeaders; + char *cp, *cp2; + int _httpd_decode(); + + + /* + ** Setup for a standard response + */ + strcpy(r->response.headers, + "Server: Hughes Technologies Embedded Server\n"); + strcpy(r->response.contentType, "text/html"); + strcpy(r->response.response,"200 Output Follows\n"); + r->response.headersSent = 0; + + + /* + ** Read the request + */ + count = 0; + inHeaders = 1; + while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0) + { + count++; + + /* + ** Special case for the first line. Scan the request + ** method and path etc + */ + if (count == 1) + { + /* + ** First line. Scan the request info + */ + cp = cp2 = buf; + while(isalpha((unsigned char)*cp2)) + cp2++; + *cp2 = 0; + if (strcasecmp(cp,"GET") == 0) + r->request.method = HTTP_GET; + if (strcasecmp(cp,"POST") == 0) + r->request.method = HTTP_POST; + if (r->request.method == 0) + { + _httpd_net_write( r->clientSock, + HTTP_METHOD_ERROR, + strlen(HTTP_METHOD_ERROR)); + _httpd_net_write( r->clientSock, cp, + strlen(cp)); + _httpd_writeErrorLog(server, r, LEVEL_ERROR, + "Invalid method received"); + return(-1); + } + cp = cp2+1; + while(*cp == ' ') + cp++; + cp2 = cp; + while(*cp2 != ' ' && *cp2 != 0) + cp2++; + *cp2 = 0; + strncpy(r->request.path,cp,HTTP_MAX_URL); + r->request.path[HTTP_MAX_URL-1]=0; + _httpd_sanitiseUrl(r->request.path); + continue; + } + + /* + ** Process the headers + */ + if (inHeaders) + { + if (*buf == 0) + { + /* + ** End of headers. Continue if there's + ** data to read + */ + if (r->request.contentLength == 0) + break; + inHeaders = 0; + break; + } +#if 0 + /** + * Philippe commenting this out, it crashed with a + * particular pattern sent from the browser + * and we don't need it + if (strncasecmp(buf,"Cookie: ",7) == 0) + { + char *var, + *val, + *end; + + var = strchr(buf,':'); + while(var) + { + var++; + val = strchr(var, '='); + *val = 0; + val++; + end = strchr(val,';'); + if(end) + *end = 0; + httpdAddVariable(r, var, val); + var = end; + } + } + */ +#endif + if (strncasecmp(buf,"Authorization: ",15) == 0) + { + cp = strchr(buf,':'); + if (cp) { + cp += 2; + + if (strncmp(cp,"Basic ", 6) != 0) + { + /* Unknown auth method */ + } + else + { + char authBuf[100]; + + cp = strchr(cp,' ') + 1; + _httpd_decode(cp, authBuf, 100); + r->request.authLength = + strlen(authBuf); + cp = strchr(authBuf,':'); + if (cp) + { + *cp = 0; + strncpy( + r->request.authPassword, + cp+1, HTTP_MAX_AUTH); + r->request.authPassword[HTTP_MAX_AUTH-1]=0; + } + strncpy(r->request.authUser, + authBuf, HTTP_MAX_AUTH); + r->request.authUser[HTTP_MAX_AUTH-1]=0; + } + } + } +#if 0 + if (strncasecmp(buf,"Referer: ",9) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + { + strncpy(r->request.referer,cp, + HTTP_MAX_URL); + r->request.referer[HTTP_MAX_URL-1]=0; + } + } +#endif + /* acv@acv.ca/wifidog: Added decoding of host: if + * present. */ + if (strncasecmp(buf,"Host: ",6) == 0) + { + cp = strchr(buf,':'); + if(cp) + { + cp += 2; + strncpy(r->request.host,cp, + HTTP_MAX_URL); + r->request.host[HTTP_MAX_URL-1]=0; + } + } + /* End modification */ +#if 0 + if (strncasecmp(buf,"If-Modified-Since: ",19) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + { + strncpy(r->request.ifModified,cp, + HTTP_MAX_URL); + r->request.ifModified[HTTP_MAX_URL-1]=0; + cp = strchr(r->request.ifModified, + ';'); + if (cp) + *cp = 0; + } + } + if (strncasecmp(buf,"Content-Type: ",14) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + { + strncpy(r->request.contentType,cp, + HTTP_MAX_URL); + r->request.contentType[HTTP_MAX_URL-1]=0; + } + } + if (strncasecmp(buf,"Content-Length: ",16) == 0) + { + cp = strchr(buf,':') + 2; + if(cp) + r->request.contentLength=atoi(cp); + } +#endif + continue; + } + } + + +#if 0 + /* XXX: For WifiDog, we only process the query string parameters + but keep the GET variables in the request.query! + */ + /* + ** Process and POST data + */ + if (r->request.contentLength > 0) + { + bzero(buf, HTTP_MAX_LEN); + _httpd_readBuf(r, buf, r->request.contentLength); + _httpd_storeData(r, buf); + + } +#endif + + /* + ** Process any URL data + */ + cp = strchr(r->request.path,'?'); + if (cp != NULL) + { + *cp++ = 0; + strncpy(r->request.query, cp, sizeof(r->request.query)); + r->request.query[sizeof(r->request.query)-1]=0; + _httpd_storeData(r, cp); + } + + return(0); +} + + +void httpdEndRequest(request *r) +{ + _httpd_freeVariables(r->variables); + shutdown(r->clientSock,2); + close(r->clientSock); + free(r); +} + + +void httpdFreeVariables(request *r) +{ + _httpd_freeVariables(r->variables); +} + + + +void httpdDumpVariables(request *r) +{ + httpVar *curVar, + *curVal; + + curVar = r->variables; + while(curVar) + { + printf("Variable '%s'\n", curVar->name); + curVal = curVar; + while(curVal) + { + printf("\t= '%s'\n",curVal->value); + curVal = curVal->nextValue; + } + curVar = curVar->nextVariable; + } +} + +void httpdSetFileBase(server, path) + httpd *server; + const char *path; +{ + strncpy(server->fileBasePath, path, HTTP_MAX_URL); + server->fileBasePath[HTTP_MAX_URL-1]=0; +} + + +int httpdAddFileContent(server, dir, name, indexFlag, preload, path) + httpd *server; + char *dir, + *name; + int (*preload)(); + int indexFlag; + char *path; +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_FILE; + newEntry->indexFlag = indexFlag; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + if (*path == '/') + { + /* Absolute path */ + newEntry->path = strdup(path); + } + else + { + /* Path relative to base path */ + newEntry->path = malloc(strlen(server->fileBasePath) + + strlen(path) + 2); + snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", + server->fileBasePath, path); + } + return(0); +} + + + +int httpdAddWildcardContent(server, dir, preload, path) + httpd *server; + char *dir; + int (*preload)(); + char *path; +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = NULL; + newEntry->type = HTTP_WILDCARD; + newEntry->indexFlag = HTTP_FALSE; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + if (*path == '/') + { + /* Absolute path */ + newEntry->path = strdup(path); + } + else + { + /* Path relative to base path */ + newEntry->path = malloc(strlen(server->fileBasePath) + + strlen(path) + 2); + snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", + server->fileBasePath, path); + } + return(0); +} + + + + +int httpdAddC404Content(server, function) + httpd *server; + void (*function)(); +{ + if (!server->handle404) { + server->handle404 = (http404*)malloc(sizeof(http404)); + } + + if (!server->handle404) { + return(-1); + } + + server->handle404->function = function; + return(0); +} + +int httpdAddCContent(server, dir, name, indexFlag, preload, function) + httpd *server; + char *dir; + char *name; + int (*preload)(); + void (*function)(); +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_C_FUNCT; + newEntry->indexFlag = indexFlag; + newEntry->function = function; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); +} + + +int httpdAddCWildcardContent(server, dir, preload, function) + httpd *server; + char *dir; + int (*preload)(); + void (*function)(); +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = NULL; + newEntry->type = HTTP_C_WILDCARD; + newEntry->indexFlag = HTTP_FALSE; + newEntry->function = function; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); +} + +int httpdAddStaticContent(server, dir, name, indexFlag, preload, data) + httpd *server; + char *dir; + char *name; + int (*preload)(); + char *data; +{ + httpDir *dirPtr; + httpContent *newEntry; + + dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); + newEntry = malloc(sizeof(httpContent)); + if (newEntry == NULL) + return(-1); + bzero(newEntry,sizeof(httpContent)); + newEntry->name = strdup(name); + newEntry->type = HTTP_STATIC; + newEntry->indexFlag = indexFlag; + newEntry->data = data; + newEntry->preload = preload; + newEntry->next = dirPtr->entries; + dirPtr->entries = newEntry; + return(0); +} + +void httpdSendHeaders(request *r) +{ + _httpd_sendHeaders(r, 0, 0); +} + +void httpdSetResponse(request *r, const char *msg) +{ + strncpy(r->response.response, msg, HTTP_MAX_URL); + r->response.response[HTTP_MAX_URL-1]=0; +} + +void httpdSetContentType(request *r, const char *type) +{ + strcpy(r->response.contentType, type); +} + + +void httpdAddHeader(request *r, const char *msg) +{ + int size; + size = HTTP_MAX_HEADERS - 2 - strlen(r->response.headers); + if(size > 0) + { + strncat(r->response.headers,msg,size); + if (r->response.headers[strlen(r->response.headers) - 1] != '\n') + strcat(r->response.headers,"\n"); + } +} + +void httpdSetCookie(request *r, const char *name, const char *value) +{ + char buf[HTTP_MAX_URL]; + + snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value); + httpdAddHeader(r, buf); +} + +void httpdOutput(request *r, const char *msg) +{ + const char *src; + char buf[HTTP_MAX_LEN], + varName[80], + *dest; + int count; + + src = msg; + dest = buf; + count = 0; + while(*src && count < HTTP_MAX_LEN) + { + if (*src == '$') + { + const char *tmp; + char *cp; + int count2; + httpVar *curVar; + + tmp = src + 1; + cp = varName; + count2 = 0; + while (*tmp && (isalnum((unsigned char)*tmp) || *tmp == '_') && + count2 < 80) + { + *cp++ = *tmp++; + count2++; + } + *cp = 0; + curVar = httpdGetVariableByName(r,varName); + if (curVar) + { + strcpy(dest, curVar->value); + dest = dest + strlen(dest); + count += strlen(dest); + } + else + { + *dest++ = '$'; + strcpy(dest, varName); + dest += strlen(varName); + count += 1 + strlen(varName); + } + src = src + strlen(varName) + 1; + continue; + } + *dest++ = *src++; + count++; + } + *dest = 0; + r->response.responseLength += strlen(buf); + if (r->response.headersSent == 0) + httpdSendHeaders(r); + _httpd_net_write( r->clientSock, buf, strlen(buf)); +} + + + +#ifdef HAVE_STDARG_H +void httpdPrintf(request *r, const char *fmt, ...) +{ +#else +void httpdPrintf(va_alist) + va_dcl +{ + request *r;; + const char *fmt; +#endif + va_list args; + char buf[HTTP_MAX_LEN]; + +#ifdef HAVE_STDARG_H + va_start(args, fmt); +#else + va_start(args); + r = (request *) va_arg(args, request * ); + fmt = (char *) va_arg(args, char *); +#endif + if (r->response.headersSent == 0) + httpdSendHeaders(r); + vsnprintf(buf, HTTP_MAX_LEN, fmt, args); + r->response.responseLength += strlen(buf); + _httpd_net_write( r->clientSock, buf, strlen(buf)); +} + + + + +void httpdProcessRequest(httpd *server, request *r) +{ + char dirName[HTTP_MAX_URL], + entryName[HTTP_MAX_URL], + *cp; + httpDir *dir; + httpContent *entry; + + r->response.responseLength = 0; + strncpy(dirName, httpdRequestPath(r), HTTP_MAX_URL); + dirName[HTTP_MAX_URL-1]=0; + cp = strrchr(dirName, '/'); + if (cp == NULL) + { + printf("Invalid request path '%s'\n",dirName); + return; + } + strncpy(entryName, cp + 1, HTTP_MAX_URL); + entryName[HTTP_MAX_URL-1]=0; + if (cp != dirName) + *cp = 0; + else + *(cp+1) = 0; + dir = _httpd_findContentDir(server, dirName, HTTP_FALSE); + if (dir == NULL) + { + _httpd_send404(server, r); + _httpd_writeAccessLog(server, r); + return; + } + entry = _httpd_findContentEntry(r, dir, entryName); + if (entry == NULL) + { + _httpd_send404(server, r); + _httpd_writeAccessLog(server, r); + return; + } + if (entry->preload) + { + if ((entry->preload)(server) < 0) + { + _httpd_writeAccessLog(server, r); + return; + } + } + switch(entry->type) + { + case HTTP_C_FUNCT: + case HTTP_C_WILDCARD: + (entry->function)(server, r); + break; + + case HTTP_STATIC: + _httpd_sendStatic(server, r, entry->data); + break; + + case HTTP_FILE: + _httpd_sendFile(server, r, entry->path); + break; + + case HTTP_WILDCARD: + if (_httpd_sendDirectoryEntry(server, r, entry, + entryName)<0) + { + _httpd_send404(server, r); + } + break; + } + _httpd_writeAccessLog(server, r); +} + +void httpdSetAccessLog(server, fp) + httpd *server; + FILE *fp; +{ + server->accessLog = fp; +} + +void httpdSetErrorLog(server, fp) + httpd *server; + FILE *fp; +{ + server->errorLog = fp; +} + +void httpdAuthenticate(request *r, const char *realm) +{ + char buffer[255]; + + if (r->request.authLength == 0) + { + httpdSetResponse(r, "401 Please Authenticate"); + snprintf(buffer,sizeof(buffer), + "WWW-Authenticate: Basic realm=\"%s\"\n", realm); + httpdAddHeader(r, buffer); + httpdOutput(r,"\n"); + } +} + + +void httpdForceAuthenticate(request *r, const char *realm) +{ + char buffer[255]; + + httpdSetResponse(r, "401 Please Authenticate"); + snprintf(buffer,sizeof(buffer), + "WWW-Authenticate: Basic realm=\"%s\"\n", realm); + httpdAddHeader(r, buffer); + httpdOutput(r,"\n"); +} diff --git a/libhttpd/httpd.h b/libhttpd/httpd.h new file mode 100755 index 00000000..732a992b --- /dev/null +++ b/libhttpd/httpd.h @@ -0,0 +1,250 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** hUghes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +/* +** libhttpd Header File +*/ + + +/*********************************************************************** +** Standard header preamble. Ensure singular inclusion, setup for +** function prototypes and c++ inclusion +*/ + +#ifndef LIB_HTTPD_H + +#define LIB_HTTPD_H 1 + +#include + +#if !defined(__ANSI_PROTO) +#if defined(_WIN32) || defined(__STDC__) || defined(__cplusplus) +# define __ANSI_PROTO(x) x +#else +# define __ANSI_PROTO(x) () +#endif +#endif + +#ifndef u_int +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*********************************************************************** +** Macro Definitions +*/ + + +#define HTTP_PORT 80 +#define HTTP_MAX_LEN 10240 +#define HTTP_MAX_URL 1024 +#define HTTP_MAX_HEADERS 1024 +#define HTTP_MAX_AUTH 128 +#define HTTP_IP_ADDR_LEN 17 +#define HTTP_TIME_STRING_LEN 40 +#define HTTP_READ_BUF_LEN 4096 +#define HTTP_ANY_ADDR NULL + +#define HTTP_GET 1 +#define HTTP_POST 2 + +#define HTTP_TRUE 1 +#define HTTP_FALSE 0 + +#define HTTP_FILE 1 +#define HTTP_C_FUNCT 2 +#define HTTP_EMBER_FUNCT 3 +#define HTTP_STATIC 4 +#define HTTP_WILDCARD 5 +#define HTTP_C_WILDCARD 6 + +#define HTTP_METHOD_ERROR "\nERROR : Method Not Implemented\n\n" + +#define httpdRequestMethod(s) s->request.method +#define httpdRequestPath(s) s->request.path +#define httpdRequestContentType(s) s->request.contentType +#define httpdRequestContentLength(s) s->request.contentLength + +#define HTTP_ACL_PERMIT 1 +#define HTTP_ACL_DENY 2 + + + +extern char LIBHTTPD_VERSION[], + LIBHTTPD_VENDOR[]; + +/*********************************************************************** +** Type Definitions +*/ + +typedef struct { + int method, + contentLength, + authLength; + char path[HTTP_MAX_URL], + query[HTTP_MAX_URL], + host[HTTP_MAX_URL], /* acv@acv.ca/wifidog: Added decoding + of host: header if present. */ + ifModified[HTTP_MAX_URL]; +#if(0) + userAgent[HTTP_MAX_URL], + referer[HTTP_MAX_URL], + contentType[HTTP_MAX_URL], +#endif + char authUser[HTTP_MAX_AUTH]; + char authPassword[HTTP_MAX_AUTH]; +} httpReq; + + +typedef struct _httpd_var{ + char *name, + *value; + struct _httpd_var *nextValue, + *nextVariable; +} httpVar; + +typedef struct _httpd_content{ + char *name; + int type, + indexFlag; + void (*function)(); + char *data, + *path; + int (*preload)(); + struct _httpd_content *next; +} httpContent; + +typedef struct { + int responseLength; + httpContent *content; + char headersSent, + headers[HTTP_MAX_HEADERS], + response[HTTP_MAX_URL], + contentType[HTTP_MAX_URL]; +} httpRes; + + +typedef struct _httpd_dir{ + char *name; + struct _httpd_dir *children, + *next; + struct _httpd_content *entries; +} httpDir; + + +typedef struct ip_acl_s{ + int addr; + char len, + action; + struct ip_acl_s *next; +} httpAcl; + +typedef struct _httpd_404 { + void (*function)(); +} http404; + +typedef struct { + int port, + serverSock, + startTime, + lastError; + char fileBasePath[HTTP_MAX_URL], + *host; + httpDir *content; + httpAcl *defaultAcl; + http404 *handle404; + FILE *accessLog, + *errorLog; +} httpd; + +typedef struct { + int clientSock, + readBufRemain; + httpReq request; + httpRes response; + httpVar *variables; + char readBuf[HTTP_READ_BUF_LEN + 1], + *readBufPtr, + clientAddr[HTTP_IP_ADDR_LEN]; +} request; + +/*********************************************************************** +** Function Prototypes +*/ + + +int httpdAddCContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),void(*)())); +int httpdAddFileContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); +int httpdAddStaticContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); +int httpdAddWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),char*)); +int httpdAddCWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),void(*)())); +int httpdAddVariable __ANSI_PROTO((request*, const char*, const char*)); +request *httpdGetConnection __ANSI_PROTO((httpd*, struct timeval*)); +int httpdReadRequest __ANSI_PROTO((httpd*, request*)); +int httpdCheckAcl __ANSI_PROTO((httpd*, request *, httpAcl*)); +int httpdAddC404Content __ANSI_PROTO((httpd*,void(*)())); + +char *httpdRequestMethodName __ANSI_PROTO((request*)); +char *httpdUrlEncode __ANSI_PROTO((const char *)); + +void httpdAddHeader __ANSI_PROTO((request*, const char*)); +void httpdSetContentType __ANSI_PROTO((request*, const char*)); +void httpdSetResponse __ANSI_PROTO((request*, const char*)); +void httpdEndRequest __ANSI_PROTO((request*)); + +httpd *httpdCreate __ANSI_PROTO(()); +void httpdFreeVariables __ANSI_PROTO((request*)); +void httpdDumpVariables __ANSI_PROTO((request*)); +void httpdOutput __ANSI_PROTO((request*, const char*)); +void httpdPrintf __ANSI_PROTO((request*, const char*, ...)); +void httpdProcessRequest __ANSI_PROTO((httpd*, request *)); +void httpdSendHeaders __ANSI_PROTO((request*)); +void httpdSetFileBase __ANSI_PROTO((httpd*, const char*)); +void httpdSetCookie __ANSI_PROTO((request*, const char*, const char*)); + +void httpdSetErrorLog __ANSI_PROTO((httpd*, FILE*)); +void httpdSetAccessLog __ANSI_PROTO((httpd*, FILE*)); +void httpdSetDefaultAcl __ANSI_PROTO((httpd*, httpAcl*)); + +httpVar *httpdGetVariableByName __ANSI_PROTO((request*, const char*)); +httpVar *httpdGetVariableByPrefix __ANSI_PROTO((request*, const char*)); +httpVar *httpdGetVariableByPrefixedName __ANSI_PROTO((request*, const char*, const char*)); +httpVar *httpdGetNextVariableByPrefix __ANSI_PROTO((httpVar*, const char*)); + +httpAcl *httpdAddAcl __ANSI_PROTO((httpd*, httpAcl*, char*, int)); + +void httpdAuthenticate __ANSI_PROTO((request*, const char*)); +void httpdForceAuthenticate __ANSI_PROTO((request*, const char*)); + +/*********************************************************************** +** Standard header file footer. +*/ + +#ifdef __cplusplus + } +#endif /* __cplusplus */ +#endif /* file inclusion */ + + diff --git a/libhttpd/httpd_priv.h b/libhttpd/httpd_priv.h new file mode 100755 index 00000000..d6d067f6 --- /dev/null +++ b/libhttpd/httpd_priv.h @@ -0,0 +1,83 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +/* +** libhttpd Private Header File +*/ + + +/*********************************************************************** +** Standard header preamble. Ensure singular inclusion, setup for +** function prototypes and c++ inclusion +*/ + +#ifndef LIB_HTTPD_PRIV_H + +#define LIB_HTTPD_H_PRIV 1 + +#if !defined(__ANSI_PROTO) +#if defined(_WIN32) || defined(__STDC__) || defined(__cplusplus) +# define __ANSI_PROTO(x) x +#else +# define __ANSI_PROTO(x) () +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#define LEVEL_NOTICE "notice" +#define LEVEL_ERROR "error" + +char * _httpd_unescape __ANSI_PROTO((char*)); +char *_httpd_escape __ANSI_PROTO((const char*)); +char _httpd_from_hex __ANSI_PROTO((char)); + + +void _httpd_catFile __ANSI_PROTO((request*, char*)); +void _httpd_send403 __ANSI_PROTO((request*)); +void _httpd_send404 __ANSI_PROTO((httpd*, request*)); +void _httpd_sendText __ANSI_PROTO((request*, char*)); +void _httpd_sendFile __ANSI_PROTO((httpd*, request*, char*)); +void _httpd_sendStatic __ANSI_PROTO((httpd*, request *, char*)); +void _httpd_sendHeaders __ANSI_PROTO((request*, int, int);) +void _httpd_sanitiseUrl __ANSI_PROTO((char*)); +void _httpd_freeVariables __ANSI_PROTO((httpVar*)); +void _httpd_formatTimeString __ANSI_PROTO((char*, int)); +void _httpd_storeData __ANSI_PROTO((request*, char*)); +void _httpd_writeAccessLog __ANSI_PROTO((httpd*, request*)); +void _httpd_writeErrorLog __ANSI_PROTO((httpd*, request *, char*, char*)); + + +int _httpd_net_read __ANSI_PROTO((int, char*, int)); +int _httpd_net_write __ANSI_PROTO((int, char*, int)); +int _httpd_readBuf __ANSI_PROTO((request*, char*, int)); +int _httpd_readChar __ANSI_PROTO((request*, char*)); +int _httpd_readLine __ANSI_PROTO((request*, char*, int)); +int _httpd_checkLastModified __ANSI_PROTO((request*, int)); +int _httpd_sendDirectoryEntry __ANSI_PROTO((httpd*, request *r, httpContent*, + char*)); + +httpContent *_httpd_findContentEntry __ANSI_PROTO((request*, httpDir*, char*)); +httpDir *_httpd_findContentDir __ANSI_PROTO((httpd*, char*, int)); + +#endif /* LIB_HTTPD_PRIV_H */ diff --git a/libhttpd/ip_acl.c b/libhttpd/ip_acl.c new file mode 100755 index 00000000..87435f7d --- /dev/null +++ b/libhttpd/ip_acl.c @@ -0,0 +1,224 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +#include "config.h" + +#include +#include +#include + +#if defined(_WIN32) +#else +#include +#endif + +#include "httpd.h" +#include "httpd_priv.h" + + +/************************************************************************** +** GLOBAL VARIABLES +**************************************************************************/ + + +/************************************************************************** +** PRIVATE ROUTINES +**************************************************************************/ + +static int scanCidr(val, result, length) + char *val; + u_int *result, + *length; +{ + u_int res, res1, res2, res3, res4, res5; + char *cp; + + cp = val; + res1 = atoi(cp); + cp = strchr(cp,'.'); + if (!cp) + return(-1); + cp++; + res2 = atoi(cp); + cp = strchr(cp,'.'); + if (!cp) + return(-1); + cp++; + res3 = atoi(cp); + cp = strchr(cp,'.'); + if (!cp) + return(-1); + cp++; + res4 = atoi(cp); + cp = strchr(cp,'/'); + if (!cp) + { + res5 = 32; + } + else + { + cp++; + res5 = atoi(cp); + } + + if (res1>255 || res2>255 || res3>255 || res4>255 || res5>32) + { + return(-1); + } + res = (res1 << 24) + (res2 << 16) + (res3 << 8) + res4; + *result = res; + *length = res5; + return(0); +} + + +static int _isInCidrBlock(httpd *server, request *r, int addr1, int len1, + int addr2, int len2) +{ + int count, + mask; + + /* if (addr1 == 0 && len1 == 0) + { + return(1); + }*/ + + if(len2 < len1) + { + _httpd_writeErrorLog(server, r, LEVEL_ERROR, + "IP Address must be more specific than network block"); + return(0); + } + + mask = count = 0; + while(count < len1) + { + mask = (mask << 1) + 1; + count++; + } + mask = mask << (32 - len1); + if ( (addr1 & mask) == (addr2 & mask)) + { + return(1); + } + else + { + return(0); + } +} + + +/************************************************************************** +** PUBLIC ROUTINES +**************************************************************************/ + +httpAcl *httpdAddAcl(server, acl, cidr, action) + httpd *server; + httpAcl *acl; + char *cidr; + int action; +{ + httpAcl *cur; + int addr, + len; + + /* + ** Check the ACL info is reasonable + */ + if(scanCidr(cidr, &addr, &len) < 0) + { + _httpd_writeErrorLog(server, NULL, LEVEL_ERROR, + "Invalid IP address format"); + return(NULL); + } + if (action != HTTP_ACL_PERMIT && action != HTTP_ACL_DENY) + { + _httpd_writeErrorLog(server, NULL, LEVEL_ERROR, + "Invalid acl action"); + return(NULL); + } + + /* + ** Find a spot to put this ACE + */ + if (acl) + { + cur = acl; + while(cur->next) + { + cur = cur->next; + } + cur->next = (httpAcl*)malloc(sizeof(httpAcl)); + cur = cur->next; + } + else + { + cur = (httpAcl*)malloc(sizeof(httpAcl)); + acl = cur; + } + + /* + ** Add the details and return + */ + cur->addr = addr; + cur->len = len; + cur->action = action; + cur->next = NULL; + return(acl); +} + + +int httpdCheckAcl(httpd *server, request *r, httpAcl *acl) +{ + httpAcl *cur; + int addr, len, + res, + action; + + + action = HTTP_ACL_DENY; + scanCidr(r->clientAddr, &addr, &len); + cur = acl; + while(cur) + { + res = _isInCidrBlock(server, r, cur->addr, cur->len, addr, len); + if (res == 1) + { + action = cur->action; + break; + } + cur = cur->next; + } + if (action == HTTP_ACL_DENY) + { + _httpd_send403(r); + _httpd_writeErrorLog(server, r, LEVEL_ERROR, + "Access denied by ACL"); + } + return(action); +} + + +void httpdSetDefaultAcl(server, acl) + httpd *server; + httpAcl *acl; +{ + server->defaultAcl = acl; +} diff --git a/libhttpd/protocol.c b/libhttpd/protocol.c new file mode 100755 index 00000000..5528c59b --- /dev/null +++ b/libhttpd/protocol.c @@ -0,0 +1,791 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#else +#include +#include +#endif + +#include "config.h" +#include "httpd.h" +#include "httpd_priv.h" + +int _httpd_net_read(sock, buf, len) + int sock; + char *buf; + int len; +{ +#if defined(_WIN32) + return( recv(sock, buf, len, 0)); +#else + /*return( read(sock, buf, len));*/ + /* XXX Select based IO */ + + int nfds; + fd_set readfds; + struct timeval timeout; + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + timeout.tv_sec = 10; + timeout.tv_usec = 0; + nfds = sock + 1; + + nfds = select(nfds, &readfds, NULL, NULL, &timeout); + + if (nfds > 0) { + return(read(sock, buf, len)); + } + return(nfds); +#endif +} + + +int _httpd_net_write(sock, buf, len) + int sock; + char *buf; + int len; +{ +#if defined(_WIN32) + return( send(sock, buf, len, 0)); +#else + return( write(sock, buf, len)); +#endif +} + +int _httpd_readChar(request *r, char *cp) +{ + if (r->readBufRemain == 0) + { + bzero(r->readBuf, HTTP_READ_BUF_LEN + 1); + r->readBufRemain = _httpd_net_read(r->clientSock, + r->readBuf, HTTP_READ_BUF_LEN); + if (r->readBufRemain < 1) + return(0); + r->readBuf[r->readBufRemain] = 0; + r->readBufPtr = r->readBuf; + } + *cp = *r->readBufPtr++; + r->readBufRemain--; + return(1); +} + + +int _httpd_readLine(request *r, char *destBuf, int len) +{ + char curChar, + *dst; + int count; + + + count = 0; + dst = destBuf; + while(count < len) + { + if (_httpd_readChar(r, &curChar) < 1) + return(0); + // Fixed by Mina - if we read binary junk it's probably not a regular HTTP client + //if (curChar == '\n') + if (curChar == '\n' || !isascii(curChar)) + { + *dst = 0; + return(1); + } + if (curChar == '\r') + { + continue; + } + else + { + *dst++ = curChar; + count++; + } + } + *dst = 0; + return(1); +} + + +int _httpd_readBuf(request *r, char *destBuf, int len) +{ + char curChar, + *dst; + int count; + + + count = 0; + dst = destBuf; + while(count < len) + { + if (_httpd_readChar(r, &curChar) < 1) + return(0); + *dst++ = curChar; + count++; + } + return(1); +} + +void _httpd_writeAccessLog(httpd *server, request *r) +{ + char dateBuf[30]; + struct tm *timePtr; + time_t clock; + int responseCode; + + + if (server->accessLog == NULL) + return; + clock = time(NULL); + timePtr = localtime(&clock); + strftime(dateBuf, 30, "%d/%b/%Y:%T %Z", timePtr); + responseCode = atoi(r->response.response); + fprintf(server->accessLog, "%s - - [%s] %s \"%s\" %d %d\n", + r->clientAddr, dateBuf, httpdRequestMethodName(r), + httpdRequestPath(r), responseCode, + r->response.responseLength); +} + +void _httpd_writeErrorLog(httpd *server, request *r, char *level, char *message) +{ + char dateBuf[30]; + struct tm *timePtr; + time_t clock; + + + if (server->errorLog == NULL) + return; + clock = time(NULL); + timePtr = localtime(&clock); + strftime(dateBuf, 30, "%a %b %d %T %Y", timePtr); + if (r != NULL && *r->clientAddr != 0) + { + fprintf(server->errorLog, "[%s] [%s] [client %s] %s\n", + dateBuf, level, r->clientAddr, message); + } + else + { + fprintf(server->errorLog, "[%s] [%s] %s\n", + dateBuf, level, message); + } +} + + + +int _httpd_decode (bufcoded, bufplain, outbufsize) + char * bufcoded; + char * bufplain; + int outbufsize; +{ + static char six2pr[64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M', + 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j','k','l','m', + 'n','o','p','q','r','s','t','u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9','+','/' + }; + + static unsigned char pr2six[256]; + + /* single character decode */ +# define DEC(c) pr2six[(int)c] +# define _DECODE_MAXVAL 63 + + static int first = 1; + + int nbytesdecoded, j; + register char *bufin = bufcoded; + register char *bufout = bufplain; + register int nprbytes; + + /* + ** If this is the first call, initialize the mapping table. + ** This code should work even on non-ASCII machines. + */ + if(first) + { + first = 0; + for(j=0; j<256; j++) pr2six[j] = _DECODE_MAXVAL+1; + for(j=0; j<64; j++) pr2six[(int)six2pr[j]] = (unsigned char)j; + } + + /* Strip leading whitespace. */ + + while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++; + + /* + ** Figure out how many characters are in the input buffer. + ** If this would decode into more bytes than would fit into + ** the output buffer, adjust the number of input bytes downwards. + */ + bufin = bufcoded; + while(pr2six[(int)*(bufin++)] <= _DECODE_MAXVAL); + nprbytes = bufin - bufcoded - 1; + nbytesdecoded = ((nprbytes+3)/4) * 3; + if(nbytesdecoded > outbufsize) + { + nprbytes = (outbufsize*4)/3; + } + bufin = bufcoded; + + while (nprbytes > 0) + { + *(bufout++)=(DEC(*bufin)<<2|DEC(bufin[1])>>4); + *(bufout++)=(DEC(bufin[1])<<4|DEC(bufin[2])>>2); + *(bufout++)=(DEC(bufin[2])<<6|DEC(bufin[3])); + bufin += 4; + nprbytes -= 4; + } + if(nprbytes & 03) + { + if(pr2six[(int)bufin[-2]] > _DECODE_MAXVAL) + { + nbytesdecoded -= 2; + } + else + { + nbytesdecoded -= 1; + } + } + bufplain[nbytesdecoded] = 0; + return(nbytesdecoded); +} + + + +char _httpd_from_hex (c) + char c; +{ + return c >= '0' && c <= '9' ? c - '0' + : c >= 'A' && c <= 'F'? c - 'A' + 10 + : c - 'a' + 10; /* accept small letters just in case */ +} + +char * _httpd_unescape(str) + char *str; +{ + char * p = str; + char * q = str; + static char blank[] = ""; + + if (!str) + return(blank); + while(*p) { + if (*p == '%') { + p++; + if (*p) *q = _httpd_from_hex(*p++) * 16; + if (*p) *q = (*q + _httpd_from_hex(*p++)); + q++; + } else { + if (*p == '+') { + *q++ = ' '; + p++; + } else { + *q++ = *p++; + } + } + } + + *q++ = 0; + return str; +} + + +void _httpd_freeVariables(var) + httpVar *var; +{ + httpVar *curVar, *lastVar; + + if (var == NULL) + return; + _httpd_freeVariables(var->nextVariable); + var->nextVariable = NULL; + curVar = var; + while(curVar) + { + lastVar = curVar; + curVar = curVar->nextValue; + free(lastVar->name); + free(lastVar->value); + free(lastVar); + } + return; +} + +void _httpd_storeData(request *r, char *query) +{ + char *cp, + *cp2, + *var, + *val, + *tmpVal; + + if (!query) + return; + + var = (char *)malloc(strlen(query)); + + cp = query; + cp2 = var; + bzero(var, strlen(query)); + val = NULL; + while(*cp) + { + if (*cp == '=') + { + cp++; + *cp2 = 0; + val = cp; + continue; + } + if (*cp == '&') + { + *cp = 0; + tmpVal = _httpd_unescape(val); + httpdAddVariable(r, var, tmpVal); + cp++; + cp2 = var; + val = NULL; + continue; + } + if (val) + { + cp++; + } + else + { + *cp2 = *cp++; + /* + if (*cp2 == '.') + { + strcpy(cp2,"_dot_"); + cp2 += 5; + } + else + { + */ + cp2++; + /* + } + */ + } + } + if (val != NULL) { + *cp = 0; + tmpVal = _httpd_unescape(val); + httpdAddVariable(r, var, tmpVal); + } + free(var); +} + + +void _httpd_formatTimeString(char *ptr, int clock) +{ + struct tm *timePtr; + time_t t; + + t = (clock == 0) ? time(NULL) : clock; + timePtr = gmtime(&t); + strftime(ptr, HTTP_TIME_STRING_LEN,"%a, %d %b %Y %T GMT",timePtr); +} + + +void _httpd_sendHeaders(request *r, int contentLength, int modTime) +{ + char tmpBuf[80], + timeBuf[HTTP_TIME_STRING_LEN]; + + if(r->response.headersSent) + return; + + r->response.headersSent = 1; + _httpd_net_write(r->clientSock, "HTTP/1.0 ", 9); + _httpd_net_write(r->clientSock, r->response.response, + strlen(r->response.response)); + _httpd_net_write(r->clientSock, r->response.headers, + strlen(r->response.headers)); + + _httpd_formatTimeString(timeBuf, 0); + _httpd_net_write(r->clientSock,"Date: ", 6); + _httpd_net_write(r->clientSock, timeBuf, strlen(timeBuf)); + _httpd_net_write(r->clientSock, "\n", 1); + + _httpd_net_write(r->clientSock, "Connection: close\n", 18); + _httpd_net_write(r->clientSock, "Content-Type: ", 14); + _httpd_net_write(r->clientSock, r->response.contentType, + strlen(r->response.contentType)); + _httpd_net_write(r->clientSock, "\n", 1); + + if (contentLength > 0) + { + _httpd_net_write(r->clientSock, "Content-Length: ", 16); + snprintf(tmpBuf, sizeof(tmpBuf), "%d", contentLength); + _httpd_net_write(r->clientSock, tmpBuf, strlen(tmpBuf)); + _httpd_net_write(r->clientSock, "\n", 1); + + _httpd_formatTimeString(timeBuf, modTime); + _httpd_net_write(r->clientSock, "Last-Modified: ", 15); + _httpd_net_write(r->clientSock, timeBuf, strlen(timeBuf)); + _httpd_net_write(r->clientSock, "\n", 1); + } + _httpd_net_write(r->clientSock, "\n", 1); +} + +httpDir *_httpd_findContentDir(server, dir, createFlag) + httpd *server; + char *dir; + int createFlag; +{ + char buffer[HTTP_MAX_URL], + *curDir; + httpDir *curItem, + *curChild; + + strncpy(buffer, dir, HTTP_MAX_URL); + buffer[HTTP_MAX_URL-1]=0; + curItem = server->content; + curDir = strtok(buffer,"/"); + while(curDir) + { + curChild = curItem->children; + while(curChild) + { + if (strcmp(curChild->name, curDir) == 0) + break; + curChild = curChild->next; + } + if (curChild == NULL) + { + if (createFlag == HTTP_TRUE) + { + curChild = malloc(sizeof(httpDir)); + bzero(curChild, sizeof(httpDir)); + curChild->name = strdup(curDir); + curChild->next = curItem->children; + curItem->children = curChild; + } + else + { + return(NULL); + } + } + curItem = curChild; + curDir = strtok(NULL,"/"); + } + return(curItem); +} + + +httpContent *_httpd_findContentEntry(request *r, httpDir *dir, char *entryName) +{ + httpContent *curEntry; + + curEntry = dir->entries; + while(curEntry) + { + if (curEntry->type == HTTP_WILDCARD || + curEntry->type ==HTTP_C_WILDCARD) + break; + if (*entryName == 0 && curEntry->indexFlag) + break; + if (strcmp(curEntry->name, entryName) == 0) + break; + curEntry = curEntry->next; + } + if (curEntry) + r->response.content = curEntry; + return(curEntry); +} + + +void _httpd_send304(request *r) +{ + httpdSetResponse(r, "304 Not Modified\n"); + _httpd_sendHeaders(r,0,0); +} + + +void _httpd_send403(request *r) +{ + httpdSetResponse(r, "403 Permission Denied\n"); + _httpd_sendHeaders(r,0,0); + _httpd_sendText(r, + "403 Permission Denied\n"); + _httpd_sendText(r, + "

Access to the request URL was denied!

\n"); +} + + +void _httpd_send404(httpd *server, request *r) +{ + char msg[HTTP_MAX_URL]; + + snprintf(msg, HTTP_MAX_URL, + "File does not exist: %s\n", r->request.path); + _httpd_writeErrorLog(server, r, LEVEL_ERROR, msg); + + if (server->handle404 && server->handle404->function) { + /* + * There's a custom C 404 handler defined with httpdAddC404Content + */ + (server->handle404->function)(server, r); + } + else { + /* + * Send stock 404 + */ + httpdSetResponse(r, "404 Not Found\n"); + _httpd_sendHeaders(r,0,0); + _httpd_sendText(r, + "404 Not Found\n"); + _httpd_sendText(r, + "

The request URL was not found!

\n"); + _httpd_sendText(r, "\n"); + } +} + + +void _httpd_catFile(request *r, char *path) +{ + int fd, + len; + char buf[HTTP_MAX_LEN]; + + fd = open(path,O_RDONLY); + if (fd < 0) + return; + len = read(fd, buf, HTTP_MAX_LEN); + while(len > 0) + { + r->response.responseLength += len; + _httpd_net_write(r->clientSock, buf, len); + len = read(fd, buf, HTTP_MAX_LEN); + } + close(fd); +} + + +void _httpd_sendStatic(httpd *server, request *r, char *data) +{ + if (_httpd_checkLastModified(r, server->startTime) == 0) + { + _httpd_send304(r); + } + _httpd_sendHeaders(r, server->startTime, strlen(data)); + httpdOutput(r, data); +} + + + +void _httpd_sendFile(httpd *server, request *r, char *path) +{ + char *suffix; + struct stat sbuf; + + suffix = strrchr(path, '.'); + if (suffix != NULL) + { + if (strcasecmp(suffix,".gif") == 0) + strcpy(r->response.contentType,"image/gif"); + if (strcasecmp(suffix,".jpg") == 0) + strcpy(r->response.contentType,"image/jpeg"); + if (strcasecmp(suffix,".xbm") == 0) + strcpy(r->response.contentType,"image/xbm"); + if (strcasecmp(suffix,".png") == 0) + strcpy(r->response.contentType,"image/png"); + } + if (stat(path, &sbuf) < 0) + { + _httpd_send404(server, r); + return; + } + if (_httpd_checkLastModified(r, sbuf.st_mtime) == 0) + { + _httpd_send304(r); + } + else + { + _httpd_sendHeaders(r, sbuf.st_size, sbuf.st_mtime); + _httpd_catFile(r, path); + } +} + + +int _httpd_sendDirectoryEntry(httpd *server, request *r, httpContent *entry, + char *entryName) +{ + char path[HTTP_MAX_URL]; + + snprintf(path, HTTP_MAX_URL, "%s/%s", entry->path, entryName); + _httpd_sendFile(server, r, path); + return(0); +} + + +void _httpd_sendText(request *r, char *msg) +{ + r->response.responseLength += strlen(msg); + _httpd_net_write(r->clientSock,msg,strlen(msg)); +} + + +int _httpd_checkLastModified(request *r, int modTime) +{ + char timeBuf[HTTP_TIME_STRING_LEN]; + + _httpd_formatTimeString(timeBuf, modTime); + if (strcmp(timeBuf, r->request.ifModified) == 0) + return(0); + return(1); +} + + +static unsigned char isAcceptable[96] = + +/* Overencodes */ +#define URL_XALPHAS (unsigned char) 1 +#define URL_XPALPHAS (unsigned char) 2 + +/* Bit 0 xalpha -- see HTFile.h +** Bit 1 xpalpha -- as xalpha but with plus. +** Bit 2 ... path -- as xpalpha but with / +*/ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + { 7,0,0,0,0,0,0,0,0,0,7,0,0,7,7,7, /* 2x !"#$%&'()*+,-./ */ + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0 }; /* 7X pqrstuvwxyz{\}~ DEL */ + +#define ACCEPTABLE(a) ( a>=32 && a<128 && ((isAcceptable[a-32]) & mask)) + +static char *hex = "0123456789ABCDEF"; + + +char *_httpd_escape(str) + const char *str; +{ + unsigned char mask = URL_XPALPHAS; + const char * p; + char * q; + char * result; + int unacceptable = 0; + for(p=str; *p; p++) + if (!ACCEPTABLE((unsigned char)*p)) + unacceptable +=2; + result = (char *) malloc(p-str + unacceptable + 1); + bzero(result,(p-str + unacceptable + 1)); + + if (result == NULL) + { + return(NULL); + } + for(q=result, p=str; *p; p++) { + unsigned char a = *p; + if (!ACCEPTABLE(a)) { + *q++ = '%'; /* Means hex commming */ + *q++ = hex[a >> 4]; + *q++ = hex[a & 15]; + } + else *q++ = *p; + } + *q++ = 0; /* Terminate */ + return result; +} + + + +void _httpd_sanitiseUrl(url) + char *url; +{ + char *from, + *to, + *last; + + /* + ** Remove multiple slashes + */ + from = to = url; + while(*from) + { + if (*from == '/' && *(from+1) == '/') + { + from++; + continue; + } + *to = *from; + to++; + from++; + } + *to = 0; + + + /* + ** Get rid of ./ sequences + */ + from = to = url; + while(*from) + { + if (*from == '/' && *(from+1) == '.' && *(from+2)=='/') + { + from += 2; + continue; + } + *to = *from; + to++; + from++; + } + *to = 0; + + + /* + ** Catch use of /../ sequences and remove them. Must track the + ** path structure and remove the previous path element. + */ + from = to = last = url; + while(*from) + { + if (*from == '/' && *(from+1) == '.' && + *(from+2)=='.' && *(from+3)=='/') + { + to = last; + from += 3; + continue; + } + if (*from == '/') + { + last = to; + } + *to = *from; + to++; + from++; + } + *to = 0; +} diff --git a/libhttpd/version.c b/libhttpd/version.c new file mode 100755 index 00000000..f88c8b5d --- /dev/null +++ b/libhttpd/version.c @@ -0,0 +1,23 @@ +/* +** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights +** reserved. +** +** Terms under which this software may be used or copied are +** provided in the specific license associated with this product. +** +** Hughes Technologies disclaims all warranties with regard to this +** software, including all implied warranties of merchantability and +** fitness, in no event shall Hughes Technologies be liable for any +** special, indirect or consequential damages or any damages whatsoever +** resulting from loss of use, data or profits, whether in an action of +** contract, negligence or other tortious action, arising out of or in +** connection with the use or performance of this software. +** +** +** $Id$ +** +*/ + +char LIBHTTPD_VERSION[] = "1.3", + LIBHTTPD_VENDOR[] = "Hughes Technologies Pty Ltd"; + diff --git a/scripts/GET_settings.sh b/scripts/GET_settings.sh new file mode 100755 index 00000000..a3dc9c4b --- /dev/null +++ b/scripts/GET_settings.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# description: get the settings of wireless, +# lan,wan,reboot_info and dhcp. +# use in OpenWrt router,based on uci +# Version: 1.0.0 +# Author: GaomingPan +# 2015-07-29 +# +# Pram: $1 gw_id +# $2 cmd_id +# +TMP=/tmp/.tmpfile +STMP=/tmp/.stmpfile +RESULT_FILE=/tmp/routersettings +RESULT="" +echo "" > $RESULT_FILE +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" +RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" +uci show wireless > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"lan\":{" +uci show network.lan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"wan\":{" +uci show network.wan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"dhcp\":{" +uci show dhcp > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," +RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}]}} + +rm $TMP $STMP +echo $RESULT > $RESULT_FILE + + diff --git a/scripts/auth.sh b/scripts/auth.sh new file mode 100755 index 00000000..492a392b --- /dev/null +++ b/scripts/auth.sh @@ -0,0 +1,25 @@ +#!/bin/sh +#live-8 empire.x@qq.com 20150513 + +hostname=`uci get wifidog.wifidog.gateway_hostname` +#DATE=`date +%Y-%m-%d-%H:%M:%S` +sum=0 +#echo --- 开始检查 --- +while [[ $sum -lt 3 ]] +do + if /bin/ping -c 1 $hostname >/dev/null + then +#echo --- æœå¡å™¨å¯è¿æ¥ï¼Œå†åˆ¤æ–­è¿›ç¨‹æ˜¯å¦å­˜åœ¨ï¼Œè¿›å…¥è¿›ç¨‹å®ˆæ¤å·¥ä½œ --- + ps | grep wifidog | grep -v grep | grep wifidog && echo wifidog-Running.... || /etc/init.d/wifidog start + + uci get wifidog.wifidog.wifidog_enable | grep '0' && echo "" > /usr/lm/script/wifidogcron.sh + + exit 0 + fi + sum=$((sum+1)) +# sleep 1 +done + ps | grep wifidog | grep -v grep | grep wifidog && /etc/init.d/wifidog stop + + uci get wifidog.wifidog.wifidog_enable | grep '0' && echo "" > /usr/lm/script/wifidogcron.sh + diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf new file mode 100644 index 00000000..9dd1a3eb --- /dev/null +++ b/scripts/conf/dog_post_conf @@ -0,0 +1,9 @@ + +config dog_post 'url' + option 'info_url' 'http://108.108.108.7:8080/WiFiAuth/wifidog/result' + option 'normal_url' 'http://108.108.108.7:8080/WiFiAuth/wifidog/result' + +config dog_post 'rmflag' + option 'info_rmflag' 'result' + option 'normal_rmflag' 'result' + diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf new file mode 100644 index 00000000..f5dd3468 --- /dev/null +++ b/scripts/conf/wifidog_conf @@ -0,0 +1,72 @@ +package 'wifidog_conf' + +config 'wifidog_conf' 'single' + option gatewayId '#GatewayID default is mac addr' + option externalInterface '# ExternalInterface eth0' + option gatewayInterface 'GatewayInterface br-lan' + option gatewayAddress '# GatewayAddress 192.168.1.1' + option htmlMessageFile '# HtmlMessageFile /opt/wifidog/etc/wifidog-.html' + option daemon '# Deamon 1' + option gatewayPort '# GatewayPort 2060' + option proxyPort '# ProxyPort 0' + option httpdName '# HTTPDName WiFiDog' + option httpdMaxConn '# HTTPDMaxConn 120' + option httpdRealm '# HTTPDRealm WiFiDog' + option httpdUserName '# HTTPDUserName admin' + option httpdPassword '# HTTPDPassword secret' + option checkInterval 'CheckInterval 30' + option clientTimeout 'ClientTimeout 5' + + +config 'wifidog_conf' 'authServer' + option 'hostname' 'Hostname 108.108.108.7' + option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' + option 'sslPort' '# SSLPort (Optional;Default:443)' + option 'httpPort' 'HTTPPort 8080' + option 'path' 'Path /WiFiAuth/wifidog/' + option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' + option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' + option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'pingScriptPathFragment' '# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'authScriptPathFragment' '# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.)' + +config 'wifidog_conf' 'trustedMACList' + option 'enable' '1' + list 'TrustedMACList' '11:22:33:44:55:66' + list 'TrustedMACList' 'aa:bb:cc:dd:ee:ff' + +config 'wifidog_conf' 'untrustedMACList' + option 'enable' '1' + list 'UntrustedMACList' 'aa:bb:cc:dd:ee:ff' + + +config 'wifidog_conf' 'whiteBlackList' + option 'white_enable' '1' + option 'black_enable' '1' + list 'WhiteList' 'www.baidu.com' + list 'WhiteList' 'www.taobao.com' + list 'BlackList' 'www.google.com' + list 'BlackList' 'www.hao123.com' + + +config 'wifidog_conf' 'firewallRule_global' + list 'FirewallRuleSet_global' '# FirewallRule block to 192.168.0.0/16 L' + list 'FirewallRuleSet_global' '# FirewallRule block to 172.16.0.0/12 L' + + +config 'wifidog_conf' 'firewallRule_validating_users' + list 'FirewallRuleSet_validating_users' 'FirewallRule allow to 0.0.0.0/0 L' + + +config 'wifidog_conf' 'firewallRule_known_users' + list 'FirewallRuleSet_known_users' 'FirewallRule allow to 0.0.0.0/0 L' + +config 'wifidog_conf' 'firewallRule_unknown_users' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 67 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 67 L' + +config 'wifidog_conf' 'firewallRule_locked_users' + list 'FirewallRuleSet_locked_users' 'FirewallRule block to 0.0.0.0/0 L' + diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh new file mode 100644 index 00000000..810926e3 --- /dev/null +++ b/scripts/dog_conf_generator.sh @@ -0,0 +1,167 @@ +#!/bin/sh +# +# Generates the wifidog config file based on UCI +# +# Author : GaomingPan +# Date : 2015-08-05 +# Version: 1.0.0 +# +########################################################## + +WIFI_DOG_CONF_FILE=/etc/wifidog.conf +WIFI_DOG_CONF=/etc/config/wifidog_conf +SINGLE=wifidog_conf.single +AUTH_SERVER=wifidog_conf.authServer +TRUSTED_MAC_LIST=wifidog_conf.trustedMACList +UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList +WHITE_LIST=wifidog_conf.whiteBlackList +BLACK_LIST=wifidog_conf.whiteBlackList +FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global +FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users +FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users +FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users +FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users + + +generate_single() +{ + echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE +} + +generate_authServer() +{ + echo "AuthServer {" >> $WIFI_DOG_CONF_FILE + echo "$(uci show $AUTH_SERVER | sed 1d | \ + awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_trustedMACList() +{ + enable=$(uci get "$TRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_untrustedMACList() +{ + enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_whiteList() +{ + white_enable=$(uci get "$WHITE_LIST.white_enable") + + if [ $white_enable -ne 1 ] + then + return + fi + + echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_blackList() +{ + black_enable=$(uci get "$BLACK_LIST.black_enable") + + if [ $black_enable -ne 1 ] + then + return + fi + + echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_global() +{ + echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + + +generate_firewallRule_validating_users() +{ + echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_known_users() +{ + echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_unknown_users() +{ + echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_locked_users() +{ + echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_wifidog_conf_file() +{ + echo "#############################################" > $WIFI_DOG_CONF_FILE + echo "## this is wifidog config file ###" >> $WIFI_DOG_CONF_FILE + echo "## auto generate by dog_conf_generator.sh ###" >> $WIFI_DOG_CONF_FILE + echo "## Version: 1.0.0 Based on UCI ###" >> $WIFI_DOG_CONF_FILE + echo "#############################################" >> $WIFI_DOG_CONF_FILE + generate_single + generate_authServer + generate_trustedMACList + generate_untrustedMACList + generate_whiteList + generate_blackList + generate_firewallRule_global + generate_firewallRule_validating_users + generate_firewallRule_known_users + generate_firewallRule_unknown_users + generate_firewallRule_locked_users + +#### +# delete the blank character at the line header + sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE + +#### +# delete the blank character at the line tail + sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE +} + +# +#echo "----- start generate ---------" +# +generate_wifidog_conf_file + +# +#echo "------ generate ok ----------" +# diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey new file mode 100644 index 00000000..5e3369b8 --- /dev/null +++ b/scripts/etc/devicekey @@ -0,0 +1,6 @@ +######################################################## +# +# this file is the device key, do NOT modify it. +# +######################################################## +ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file diff --git a/scripts/init.d/wifidog b/scripts/init.d/wifidog new file mode 100755 index 00000000..f5447651 --- /dev/null +++ b/scripts/init.d/wifidog @@ -0,0 +1,201 @@ +#!/bin/sh +# +# Could be better, but it's working as expected +# +# +# +# chkconfig: 345 65 35 +# +# description: Startup/shutdown script for Wifidog captive portal +# processname: wifidog + +# Date : 2004-08-25 +# Version : 1.0 + +IPT=/usr/sbin/iptables +WD_DIR=/usr/bin +OPTIONS="" + +case "$1" in + start) + echo "Starting Wifidog ... " + if $WD_DIR/wdctl status 2> /dev/null + then + echo "FAILED: Wifidog already running" + else + $0 test-module + if $WD_DIR/wifidog $OPTIONS + then + echo "OK" + else + echo "FAILED: Wifidog exited with non 0 status" + fi + fi + ;; + restart) + $0 stop + sleep 2 + $0 start + ;; + reload) + $0 stop + sleep 2 + $0 start + ;; + stop) + echo "Stopping Wifidog ... " + if $WD_DIR/wdctl status 2> /dev/null + then + if $WD_DIR/wdctl stop + then + echo "OK" + else + echo "FAILED: wdctl stop exited with non 0 status" + fi + + else + echo "FAILED: Wifidog was not running" + fi + ;; + status) + $WD_DIR/wdctl status + ;; + debug|test-module) + + ### Test ipt_mark with iptables + test_ipt_mark () { + IPTABLES_OK=$($IPT -A FORWARD -m mark --mark 2 -j ACCEPT 2>&1 | grep "No chain.target.match") + if [ -z "$IPTABLES_OK" ]; then + $IPT -D FORWARD -m mark --mark 2 -j ACCEPT 2>&1 + echo 1 + else + echo 0 + fi + } + ### Test ipt_mac with iptables + test_ipt_mac () { + IPTABLES_OK=$($IPT -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1 | grep "No chain.target.match") + if [ -z "$IPTABLES_OK" ]; then + $IPT -D INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1 + echo 1 + else + echo 0 + fi + } + + ### Test ipt_REDIRECT with iptables + test_ipt_REDIRECT () { + IPTABLES_OK=$($IPT -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 2060 2>&1 | grep "No chain.target.match") + if [ -z "$IPTABLES_OK" ]; then + $IPT -t nat -D PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 2060 2>&1 + echo 1 + else + echo 0 + fi + } + + ### Find a module on disk + module_exists () { + echo " Looking for a module on disk" + EXIST=$(find /lib/modules/`uname -r` -name $1.*o 2>/dev/null) + if [ -n "$EXIST" ]; then + echo 1 + else + echo 0 + fi + } + + ### Test if a module is in memory + module_in_memory () { + MODULE=$(lsmod | grep $1 | awk '{print $1}') + if [ "$MODULE" = "$1" ]; then + echo 1 + else + echo 0 + fi + } + + echo "Testing for iptables modules" + + echo " Testing ipt_mac" + TEST_IPT_MAC=$(test_ipt_mac) + if [ "$TEST_IPT_MAC" = "0" ]; then + echo " iptables is not working with ipt_mac" + echo " Scanning disk for ipt_mac module" + TEST_IPT_MAC_MODULE_EXISTS=$(module_exists "ipt_mac") + if [ "$TEST_IPT_MAC_MODULE_EXISTS" = "0" ]; then + echo " ipt_mac module is missing, please install it (kernel or module)" + exit + else + echo " ipt_mac module exists, trying to load" + insmod ipt_mac > /dev/null + TEST_IPT_MAC_MODULE_MEMORY=$(module_in_memory "ipt_mac") + if [ "$TEST_IPT_MAC_MODULE_MEMORY" = "0" ]; then + echo " Error: ipt_mac not loaded" + exit + else + echo " ipt_mac loaded sucessfully" + fi + fi + else + echo " ipt_mac module is working" + fi + + echo " Testing ipt_mark" + TEST_IPT_MARK=$(test_ipt_mark) + if [ "$TEST_IPT_MARK" = "0" ]; then + echo " iptables is not working with ipt_mark" + echo " Scanning disk for ipt_mark module" + TEST_IPT_MARK_MODULE_EXISTS=$(module_exists "ipt_mark") + if [ "$TEST_IPT_MARK_MODULE_EXISTS" = "0" ]; then + echo " iptables ipt_mark module missing, please install it (kernel or module)" + exit + else + echo " ipt_mark module exists, trying to load" + insmod ipt_mark + TEST_IPT_MARK_MODULE_MEMORY=$(module_in_memory "ipt_mark") + if [ "$TEST_IPT_MARK_MODULE_MEMORY" = "0" ]; then + echo " Error: ipt_mark not loaded" + exit + else + echo " ipt_mark loaded sucessfully" + fi + fi + else + echo " ipt_mark module is working" + fi + +##TODO: This will not test if required iptables userspace (iptables-mod-nat on Kamikaze) is installed + echo " Testing ipt_REDIRECT" + TEST_IPT_MAC=$(test_ipt_REDIRECT) + if [ "$TEST_IPT_MAC" = "0" ]; then + echo " iptables is not working with ipt_REDIRECT" + echo " Scanning disk for ipt_REDIRECT module" + TEST_IPT_MAC_MODULE_EXISTS=$(module_exists "ipt_REDIRECT") + if [ "$TEST_IPT_MAC_MODULE_EXISTS" = "0" ]; then + echo " ipt_REDIRECT module is missing, please install it (kernel or module)" + exit + else + echo " ipt_REDIRECT module exists, trying to load" + insmod ipt_REDIRECT > /dev/null + TEST_IPT_MAC_MODULE_MEMORY=$(module_in_memory "ipt_REDIRECT") + if [ "$TEST_IPT_MAC_MODULE_MEMORY" = "0" ]; then + echo " Error: ipt_REDIRECT not loaded" + exit + else + echo " ipt_REDIRECT loaded sucessfully" + fi + fi + else + echo " ipt_REDIRECT module is working" + fi + + ;; + + *) + echo "Usage: $0 {start|stop|restart|reload|status|test-module}" + exit 1 + ;; +esac + + diff --git a/scripts/white_black_flush.sh b/scripts/white_black_flush.sh new file mode 100755 index 00000000..c951267b --- /dev/null +++ b/scripts/white_black_flush.sh @@ -0,0 +1,86 @@ +#!/bin/sh + + +RUN_DOG_PID=`pidof wifidog` +GATEWAY_INTERFACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $NF}') +WHITE_LIST_URL=$(uci get wifidog_conf.whiteBlackList.WhiteList) +BLACK_LIST_URL=$(uci get wifidog_conf.whiteBlackList.BlackList) + +#touch files +mkdir -p /tmp/.white_black_list + +#compare +while [ true ] +do + + WHITE_LIST_URL=$(uci get wifidog_conf.whiteBlackList.WhiteList) + BLACK_LIST_URL=$(uci get wifidog_conf.whiteBlackList.BlackList) + + #detect + iptables -t nat -L WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -n --line-numbers | awk '{for(i=6;i /tmp/.white_black_list/.white_list + iptables -t mangle -L WiFiDog_"$GATEWAY_INTERFACE"_BlackList -n --line-numbers | awk '{for(i=6;i /tmp/.white_black_list/.black_list + + rm /tmp/.white_black_list/.white_list_tmp + for white_list in $WHITE_LIST_URL + do + nslookup $white_list | sed "1d" | sed "1d" | sed "1d" | sed "1d" | awk '{for(i=3;i> /tmp/.white_black_list/.white_list_tmp + done + invalid=`grep -e ".*0\.0\..*" /tmp/.white_black_list/.white_list_tmp -rn|cut -d : -f 1` + [ $invalid ] && sed -r -i "/"$invalid/"d" /tmp/.white_black_list/.white_list_tmp + + rm /tmp/.white_black_list/.black_list_tmp + for black_list in $BLACK_LIST_URL + do + nslookup $black_list |sed "1d"|sed "1d" |sed "1d" |sed "1d"|awk '{for(i=3;i> /tmp/.white_black_list/.black_list_tmp + done + invalid=`grep -e ".*0\.0\..*" /tmp/.white_black_list/.black_list_tmp -rn|cut -d : -f 1` + [ $invalid ] && sed -r -i "/"$invalid/"d" /tmp/.white_black_list/.black_list_tmp + + #white + while read line_new + do + i=0 + + while read line_old + do + if [ "$line_new" != "$line_old" ]; then + i=1 + else + i=0 + break + fi + done < /tmp/.white_black_list/.white_list + + if [ "$i" -eq "1" ]; then + iptables -t nat -A WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -d "$line_new" -j ACCEPT + iptables -t filter -A WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -d "$line_new" -j ACCEPT + #echo "-------------------------------------------------------------------------------limeng white diff -------------------------------------------------------------------------" + fi + done < /tmp/.white_black_list/.white_list_tmp + + sleep 10 + + #black + while read line_new + do + i=0 + + while read line_old + do + if [ "$line_new" != "$line_old" ]; then + i=1 + else + i=0 + break + fi + done < /tmp/.white_black_list/.black_list + + if [ "$i" -eq "1" ]; then + iptables -t mangle -A WiFiDog_"$GATEWAY_INTERFACE"_BlackList -d "$line_new" -j DROP + #echo "-------------------------------------------------------------------------------limeng black diff -------------------------------------------------------------------------" + fi + done < /tmp/.white_black_list/.black_list_tmp + + sleep 10 +done + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 00000000..ca180b39 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,63 @@ +# +# $Id$ +# + +bin_PROGRAMS = wifidog \ + wdctl + +AM_CPPFLAGS = \ + -I${top_srcdir}/libhttpd/ \ + -DSYSCONFDIR='"$(sysconfdir)"' +wifidog_LDADD = $(top_builddir)/libhttpd/libhttpd.la + +# +#@breif GaomingPan add file: +# get_devinfo.h get_devinfo.c +# shell_command.h +# get_clientinfo.h get_clientinfo.c +# get_remote_shell.h get_remote_shell.c +# +wifidog_SOURCES = commandline.c \ + conf.c \ + debug.c \ + fw_iptables.c \ + firewall.c \ + gateway.c \ + centralserver.c \ + http.c \ + auth.c \ + client_list.c \ + util.c \ + wdctl_thread.c \ + ping_thread.c \ + safe.c \ + httpd_thread.c \ + get_devinfo.c \ + get_clientinfo.c \ + get_remote_shell.c \ + device_key.c + +noinst_HEADERS = commandline.h \ + common.h \ + conf.h \ + debug.h \ + fw_iptables.h \ + firewall.h \ + gateway.h \ + centralserver.h \ + http.h \ + auth.h \ + client_list.h \ + util.h \ + wdctl_thread.h \ + wdctl.h \ + ping_thread.h \ + safe.h \ + httpd_thread.h \ + shell_command.h \ + get_devinfo.h \ + get_clientinfo.h \ + get_remote_shell.h \ + device_key.h + +wdctl_SOURCES = wdctl.c diff --git a/src/auth.c b/src/auth.c new file mode 100755 index 00000000..fd78ddb2 --- /dev/null +++ b/src/auth.c @@ -0,0 +1,224 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file auth.c + @brief Authentication handling thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" +#include "http.h" +#include "safe.h" +#include "conf.h" +#include "debug.h" +#include "auth.h" +#include "centralserver.h" +#include "fw_iptables.h" +#include "firewall.h" +#include "client_list.h" +#include "util.h" + +/* Defined in clientlist.c */ +extern pthread_mutex_t client_list_mutex; + +/* Defined in util.c */ +extern long served_this_session; + +/** Launches a thread that periodically checks if any of the connections has timed out +@param arg Must contain a pointer to a string containing the IP adress of the client to check to check +@todo Also pass MAC adress? +@todo This thread loops infinitely, need a watchdog to verify that it is still running? +*/ +void +thread_client_timeout_check(const void *arg) +{ + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + + while (1) { + /* Sleep for config.checkinterval seconds... */ + timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; + timeout.tv_nsec = 0; + + /* Mutex must be locked for pthread_cond_timedwait... */ + pthread_mutex_lock(&cond_mutex); + + /* Thread safe "sleep" */ + pthread_cond_timedwait(&cond, &cond_mutex, &timeout); + + /* No longer needs to be locked */ + pthread_mutex_unlock(&cond_mutex); + + debug(LOG_DEBUG, "Running fw_counter()"); + + fw_sync_with_authserver(); + } +} + +/** Authenticates a single client against the central server and returns when done + * Alters the firewall rules depending on what the auth server says +@param r httpd request struct +*/ +void +authenticate_client(request *r) +{ + t_client *client; + t_authresponse auth_response; + char *mac, + *token; + char *urlFragment = NULL; + s_config *config = NULL; + t_auth_serv *auth_server = NULL; + + LOCK_CLIENT_LIST(); + + client = client_list_find_by_ip(r->clientAddr); + + if (client == NULL) { + debug(LOG_ERR, "authenticate_client(): Could not find client for %s", r->clientAddr); + UNLOCK_CLIENT_LIST(); + return; + } + + mac = safe_strdup(client->mac); + token = safe_strdup(client->token); + + UNLOCK_CLIENT_LIST(); + + /* + * At this point we've released the lock while we do an HTTP request since it could + * take multiple seconds to do and the gateway would effectively be frozen if we + * kept the lock. + */ + auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0); + + LOCK_CLIENT_LIST(); + + /* can't trust the client to still exist after n seconds have passed */ + client = client_list_find(r->clientAddr, mac); + + if (client == NULL) { + debug(LOG_ERR, "authenticate_client(): Could not find client node for %s (%s)", r->clientAddr, mac); + UNLOCK_CLIENT_LIST(); + free(token); + free(mac); + return; + } + + free(token); + free(mac); + + /* Prepare some variables we'll need below */ + config = config_get_config(); + auth_server = get_auth_server(); + + switch(auth_response.authcode) { + + case AUTH_ERROR: + /* Error talking to central server */ + debug(LOG_ERR, "Got %d from central server authenticating token %s from %s at %s", auth_response, client->token, client->ip, client->mac); + send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server"); + break; + + case AUTH_DENIED: + /* Central server said invalid token */ + debug(LOG_INFO, "Got DENIED from central server authenticating token %s from %s at %s - deleting from firewall and redirecting them to denied message", client->token, client->ip, client->mac); + fw_deny(client->ip, client->mac, FW_MARK_KNOWN); + safe_asprintf(&urlFragment, "%smessage=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_DENIED + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message"); + free(urlFragment); + break; + + case AUTH_VALIDATION: + /* They just got validated for X minutes to check their email */ + debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s" + "- adding to firewall and redirecting them to activate message", client->token, + client->ip, client->mac); + client->fw_connection_state = FW_MARK_PROBATION; + fw_allow(client->ip, client->mac, FW_MARK_PROBATION); + safe_asprintf(&urlFragment, "%smessage=%s&gw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_ACTIVATE_ACCOUNT, + config->gw_id, + config->gw_address, + client->mac + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message"); + free(urlFragment); + break; + + case AUTH_ALLOWED: + /* Logged in successfully as a regular account */ + debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - " + "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac); + client->fw_connection_state = FW_MARK_KNOWN; + fw_allow(client->ip, client->mac, FW_MARK_KNOWN); + served_this_session++; + safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_portal_script_path_fragment, + config->gw_id, + config->gw_address, + client->mac + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); + free(urlFragment); + break; + + case AUTH_VALIDATION_FAILED: + /* Client had X minutes to validate account by email and didn't = too late */ + debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s " + "- redirecting them to failed_validation message", client->token, client->ip, client->mac); + safe_asprintf(&urlFragment, "%smessage=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message"); + free(urlFragment); + break; + + default: + debug(LOG_WARNING, "I don't know what the validation code %d means for token %s from %s at %s - sending error message", auth_response.authcode, client->token, client->ip, client->mac); + send_http_page(r, "Internal Error", "We can not validate your request at this time"); + break; + + } + + UNLOCK_CLIENT_LIST(); + return; +} + + diff --git a/src/auth.h b/src/auth.h new file mode 100755 index 00000000..89de88ce --- /dev/null +++ b/src/auth.h @@ -0,0 +1,61 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file auth.h + @brief Authentication handling thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _AUTH_H_ +#define _AUTH_H_ + +#include "httpd.h" + +/** + * @brief Authentication codes returned by auth server. + * + * Authentication result codes returned by auth_server_request() corresponding + * to result code from the central server itself. + */ +typedef enum { + AUTH_ERROR = -1, /**< An error occured during the validation process*/ + AUTH_DENIED = 0, /**< Client was denied by the auth server */ + AUTH_ALLOWED = 1, /**< Client was granted access by the auth server */ + AUTH_VALIDATION = 5, /**< A misnomer. Client is in 15 min probation to validate his new account */ + AUTH_VALIDATION_FAILED = 6, /**< Client had X minutes to validate account by email and didn't = too late */ + AUTH_LOCKED = 254 /**< Account has been locked */ +} t_authcode; + +/** + * @brief This structure contains all the information returned by the authentication server + */ +typedef struct _t_authresponse { + t_authcode authcode; /**< Authentication code returned by the server */ +} t_authresponse; + + +/** @brief Authenticate a single client against the central server */ +void authenticate_client(request *); + +/** @brief Periodically check if connections expired */ +void thread_client_timeout_check(const void *arg); + +#endif diff --git a/src/centralserver.c b/src/centralserver.c new file mode 100755 index 00000000..31a39b21 --- /dev/null +++ b/src/centralserver.c @@ -0,0 +1,454 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @file centralserver.c + @brief Functions to talk to the central server (auth/send stats/get rules/etc...) + @author Copyright (C) 2004 Philippe April + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" + +#include "common.h" +#include "safe.h" +#include "util.h" +#include "auth.h" +#include "conf.h" +#include "debug.h" +#include "centralserver.h" +#include "firewall.h" +#include "../config.h" + +#include "client_list.h" + +/** + * include my header file. + */ +#include "get_clientinfo.h" +#include "device_key.h" + +extern pthread_mutex_t client_list_mutex; + +extern pthread_mutex_t config_mutex; + +/** Initiates a transaction with the auth server, either to authenticate or to + * update the traffic counters at the server +@param authresponse Returns the information given by the central server +@param request_type Use the REQUEST_TYPE_* defines in centralserver.h +@param ip IP adress of the client this request is related to +@param mac MAC adress of the client this request is related to +@param token Authentification token of the client +@param incoming Current counter of the client's total incoming traffic, in bytes +@param outgoing Current counter of the client's total outgoing traffic, in bytes +*/ +t_authcode +auth_server_request(t_authresponse *authresponse, const char *request_type, const char *ip, const char *mac, const char *token, unsigned long long int incoming, unsigned long long int outgoing) +{ + int sockfd; + ssize_t numbytes; + size_t totalbytes; + char buf[MAX_BUF]; + char *tmp; + char *safe_token; + int done, nfds; + fd_set readfds; + struct timeval timeout; + t_auth_serv *auth_server = NULL; + auth_server = get_auth_server(); + + /* Blanket default is error. */ + authresponse->authcode = AUTH_ERROR; + + sockfd = connect_auth_server(); + if (sockfd == -1) { + /* Could not connect to any auth server */ + return (AUTH_ERROR); + } + + /** + * TODO: XXX change the PHP so we can harmonize stage as request_type + * everywhere. + */ + memset(buf, 0, sizeof(buf)); + safe_token=httpdUrlEncode(token); + + /** + * here I add some my info about the client. + */ + t_clientinfo *client_info; + long online_time; + + if(0 != collect_client_info()) + { + debug(LOG_ERR,"ERROR: at collect_client_info() failed."); + printf("ERROR: at collect_client_info() failed.\n"); + } + //client_info = get_client_info_by_ip(ip); + client_info = get_client_info_by_mac(mac); + if(NULL == client_info) + { + //debug(LOG_ERR,"ERROR: at get_client_info_by_ip(ip) failed."); + debug(LOG_ERR,"ERROR: at get_client_info_by_mac(mac) failed."); + //printf("ERROR: at get_client_info_by_ip(ip) failed.\n"); + } + + LOCK_CLIENT_LIST(); + online_time = get_online_time(ip,mac); + UNLOCK_CLIENT_LIST(); + + /******************************************/ + + + + if(NULL != client_info) + { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, + safe_token, + incoming, + outgoing, + config_get_config()->gw_id, + + /**************************** + * my new info. + * */ + client_info->host_name, + client_info->go_speed, + client_info->come_speed, + online_time, + get_client_auth_flag(), + /**************************/ + + VERSION, + auth_server->authserv_hostname, + /* device key*/ + get_device_key() + ); + } + else + { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, + safe_token, + incoming, + outgoing, + config_get_config()->gw_id, + + + /**************************** + * my new info. + * */ + "null",//client_info->host_name, + -1, //client_info->go_speed, + -1, //client_info->come_speed, + -1, //online_time, + get_client_auth_flag(), + /**************************/ + + VERSION, + auth_server->authserv_hostname, + /* device key*/ + get_device_key() + ); + } + + free(safe_token); + + debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf); + send(sockfd, buf, strlen(buf), 0); + + debug(LOG_DEBUG, "Reading response"); + numbytes = totalbytes = 0; + done = 0; + do { + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + timeout.tv_sec = 30; /* XXX magic... 30 second is as good a timeout as any */ + timeout.tv_usec = 0; + nfds = sockfd + 1; + + nfds = select(nfds, &readfds, NULL, NULL, &timeout); + + if (nfds > 0) { + /** We don't have to use FD_ISSET() because there + * was only one fd. */ + numbytes = read(sockfd, buf + totalbytes, MAX_BUF - (totalbytes + 1)); + if (numbytes < 0) { + debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return (AUTH_ERROR); + } + else if (numbytes == 0) { + done = 1; + } + else { + totalbytes += numbytes; + debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes); + } + } + else if (nfds == 0) { + debug(LOG_ERR, "Timed out reading data via select() from auth server"); + /* FIXME */ + close(sockfd); + return (AUTH_ERROR); + } + else if (nfds < 0) { + debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return (AUTH_ERROR); + } + } while (!done); + + close(sockfd); + + buf[totalbytes] = '\0'; + debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf); + + if ((tmp = strstr(buf, "Auth: "))) { + if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) { + debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode); + return(authresponse->authcode); + } else { + debug(LOG_WARNING, "Auth server did not return expected authentication code"); + return(AUTH_ERROR); + } + } + else { + return(AUTH_ERROR); + } + + /* XXX Never reached because of the above if()/else pair. */ + return(AUTH_ERROR); +} + +/* Tries really hard to connect to an auth server. Returns a file descriptor, -1 on error + */ +int connect_auth_server() { + int sockfd; + + LOCK_CONFIG(); + sockfd = _connect_auth_server(0); + UNLOCK_CONFIG(); + + if (sockfd == -1) { + debug(LOG_ERR, "Failed to connect to any of the auth servers"); + mark_auth_offline(); + } + else { + debug(LOG_DEBUG, "Connected to auth server"); + mark_auth_online(); + } + return (sockfd); +} + +/* Helper function called by connect_auth_server() to do the actual work including recursion + * DO NOT CALL DIRECTLY + @param level recursion level indicator must be 0 when not called by _connect_auth_server() + */ +int _connect_auth_server(int level) { + s_config *config = config_get_config(); + t_auth_serv *auth_server = NULL; + struct in_addr *h_addr; + int num_servers = 0; + char * hostname = NULL; + char * popular_servers[] = { + "www.google.com", + "www.yahoo.com", + NULL + }; + char ** popularserver; + char * ip; + struct sockaddr_in their_addr; + int sockfd; + + /* XXX level starts out at 0 and gets incremented by every iterations. */ + level++; + + /* + * Let's calculate the number of servers we have + */ + for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) { + num_servers++; + } + debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers); + + if (level > num_servers) { + /* + * We've called ourselves too many times + * This means we've cycled through all the servers in the server list + * at least once and none are accessible + */ + return (-1); + } + + /* + * Let's resolve the hostname of the top server to an IP address + */ + auth_server = config->auth_servers; + hostname = auth_server->authserv_hostname; + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname); + h_addr = wd_gethostbyname(hostname); + if (!h_addr) { + /* + * DNS resolving it failed + * + * Can we resolve any of the popular servers ? + */ + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname); + + for (popularserver = popular_servers; *popularserver; popularserver++) { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, *popularserver); + h_addr = wd_gethostbyname(*popularserver); + if (h_addr) { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] succeeded = [%s]", level, *popularserver, inet_ntoa(*h_addr)); + break; + } + else { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] failed", level, *popularserver); + } + } + + /* + * If we got any h_addr buffer for one of the popular servers, in other + * words, if one of the popular servers resolved, we'll assume the DNS + * works, otherwise we'll deal with net connection or DNS failure. + */ + if (h_addr) { + free (h_addr); + /* + * Yes + * + * The auth server's DNS server is probably dead. Try the next auth server + */ + debug(LOG_DEBUG, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname); + if (auth_server->last_ip) { + free(auth_server->last_ip); + auth_server->last_ip = NULL; + } + mark_auth_server_bad(auth_server); + return _connect_auth_server(level); + } + else { + /* + * No + * + * It's probably safe to assume that the internet connection is malfunctioning + * and nothing we can do will make it work + */ + mark_offline(); + debug(LOG_DEBUG, "Level %d: Failed to resolve auth server and all popular servers. " + "The internet connection is probably down", level); + return(-1); + } + } + else { + /* + * DNS resolving was successful + */ + ip = safe_strdup(inet_ntoa(*h_addr)); + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip); + + if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) { + /* + * But the IP address is different from the last one we knew + * Update it + */ + debug(LOG_DEBUG, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip); + if (auth_server->last_ip) free(auth_server->last_ip); + auth_server->last_ip = ip; + + /* Update firewall rules */ + fw_clear_authservers(); + fw_set_authservers(); + } + else { + /* + * IP is the same as last time + */ + free(ip); + } + + /* + * Connect to it + */ + debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port); + their_addr.sin_family = AF_INET; + their_addr.sin_port = htons(auth_server->authserv_http_port); + their_addr.sin_addr = *h_addr; + memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero)); + free (h_addr); + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno)); + return(-1); + } + + if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { + /* + * Failed to connect + * Mark the server as bad and try the next one + */ + debug(LOG_DEBUG, "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", level, hostname, auth_server->authserv_http_port, strerror(errno)); + close(sockfd); + mark_auth_server_bad(auth_server); + return _connect_auth_server(level); /* Yay recursion! */ + } + else { + /* + * We have successfully connected + */ + debug(LOG_DEBUG, "Level %d: Successfully connected to auth server %s:%d", level, hostname, auth_server->authserv_http_port); + return sockfd; + } + } +} diff --git a/src/centralserver.h b/src/centralserver.h new file mode 100755 index 00000000..36c9ca65 --- /dev/null +++ b/src/centralserver.h @@ -0,0 +1,63 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file centralserver.h + @brief Functions to talk to the central server (auth/send stats/get rules/etc...) + @author Copyright (C) 2004 Philippe April + */ + +#ifndef _CENTRALSERVER_H_ +#define _CENTRALSERVER_H_ + +#include "auth.h" + +/** @brief Ask the central server to login a client */ +#define REQUEST_TYPE_LOGIN "login" +/** @brief Notify the the central server of a client logout */ +#define REQUEST_TYPE_LOGOUT "logout" +/** @brief Update the central server's traffic counters */ +#define REQUEST_TYPE_COUNTERS "counters" + +/** @brief Sent when the user's token is denied by the central server */ +#define GATEWAY_MESSAGE_DENIED "denied" +/** @brief Sent when the user's token is accepted, but user is on probation */ +#define GATEWAY_MESSAGE_ACTIVATE_ACCOUNT "activate" +/** @brief Sent when the user's token is denied by the central server because the probation period is over */ +#define GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED "failed_validation" +/** @brief Sent after the user performed a manual log-out on the gateway */ +#define GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT "logged-out" + +/** @brief Initiates a transaction with the auth server */ +t_authcode auth_server_request(t_authresponse *authresponse, + const char *request_type, + const char *ip, + const char *mac, + const char *token, + unsigned long long int incoming, + unsigned long long int outgoing); + +/** @brief Tries really hard to connect to an auth server. Returns a connected file descriptor or -1 on error */ +int connect_auth_server(); + +/** @brief Helper function called by connect_auth_server() to do the actual work including recursion - DO NOT CALL DIRECTLY */ +int _connect_auth_server(int level); + +#endif /* _CENTRALSERVER_H_ */ diff --git a/src/client_list.c b/src/client_list.c new file mode 100755 index 00000000..bf895e92 --- /dev/null +++ b/src/client_list.c @@ -0,0 +1,258 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** @file client_list.c + @brief Client List Functions + @author Copyright (C) 2004 Alexandre Carmel-Veillex + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include + +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "client_list.h" + +/** Global mutex to protect access to the client list */ +pthread_mutex_t client_list_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** @internal + * Holds a pointer to the first element of the list + */ +t_client *firstclient = NULL; + +/** Get the first element of the list of connected clients + */ +t_client * +client_get_first_client(void) +{ + return firstclient; +} + +/** + * Initializes the list of connected clients (client) + */ +void +client_list_init(void) +{ + firstclient = NULL; +} + +/** Based on the parameters it receives, this function creates a new entry + * in the connections list. All the memory allocation is done here. + * @param ip IP address + * @param mac MAC address + * @param token Token + * @return Pointer to the client we just created + */ +t_client * +client_list_append(const char *ip, const char *mac, const char *token) +{ + t_client *curclient, *prevclient; + + prevclient = NULL; + curclient = firstclient; + + while (curclient != NULL) { + prevclient = curclient; + curclient = curclient->next; + } + + curclient = safe_malloc(sizeof(t_client)); + memset(curclient, 0, sizeof(t_client)); + + curclient->ip = safe_strdup(ip); + curclient->mac = safe_strdup(mac); + curclient->token = safe_strdup(token); + curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; + curclient->counters.last_updated = time(NULL); + + /*@breif:record the element create time + * GaomingPan + * */ + curclient->record_time = time(NULL); + //printf("New client: mac-->%s\nip-->%s\nrecord_time-->%ld\n\n",mac,ip,curclient->record_time); + + + if (prevclient == NULL) { + firstclient = curclient; + } else { + prevclient->next = curclient; + } + + debug(LOG_INFO, "Added a new client to linked list: IP: %s Token: %s", + ip, token); + + return curclient; +} + +/** Finds a client by its IP and MAC, returns NULL if the client could not + * be found + * @param ip IP we are looking for in the linked list + * @param mac MAC we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find(const char *ip, const char *mac) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->ip, ip) && 0 == strcmp(ptr->mac, mac)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** + * Finds a client by its IP, returns NULL if the client could not + * be found + * @param ip IP we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find_by_ip(const char *ip) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->ip, ip)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** + * Finds a client by its Mac, returns NULL if the client could not + * be found + * @param mac Mac we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find_by_mac(const char *mac) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->mac, mac)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** Finds a client by its token + * @param token Token we are looking for in the linked list + * @return Pointer to the client, or NULL if not found + */ +t_client * +client_list_find_by_token(const char *token) +{ + t_client *ptr; + + ptr = firstclient; + while (NULL != ptr) { + if (0 == strcmp(ptr->token, token)) + return ptr; + ptr = ptr->next; + } + + return NULL; +} + +/** @internal + * @brief Frees the memory used by a t_client structure + * This function frees the memory used by the t_client structure in the + * proper order. + * @param client Points to the client to be freed + */ +void +_client_list_free_node(t_client * client) +{ + + if (client->mac != NULL) + free(client->mac); + + if (client->ip != NULL) + free(client->ip); + + if (client->token != NULL) + free(client->token); + + free(client); +} + +/** + * @brief Deletes a client from the connections list + * + * Removes the specified client from the connections list and then calls + * the function to free the memory used by the client. + * @param client Points to the client to be deleted + */ +void +client_list_delete(t_client * client) +{ + t_client *ptr; + + ptr = firstclient; + + if (ptr == NULL) { + debug(LOG_ERR, "Node list empty!"); + } else if (ptr == client) { + firstclient = ptr->next; + _client_list_free_node(client); + } else { + /* Loop forward until we reach our point in the list. */ + while (ptr->next != NULL && ptr->next != client) { + ptr = ptr->next; + } + /* If we reach the end before finding out element, complain. */ + if (ptr->next == NULL) { + debug(LOG_ERR, "Node to delete could not be found."); + /* Free element. */ + } else { + ptr->next = client->next; + _client_list_free_node(client); + } + } +} diff --git a/src/client_list.h b/src/client_list.h new file mode 100755 index 00000000..51c9ba0a --- /dev/null +++ b/src/client_list.h @@ -0,0 +1,100 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file client_list.h + @brief Client List functions + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _CLIENT_LIST_H_ +#define _CLIENT_LIST_H_ + +/** Counters struct for a client's bandwidth usage (in bytes) + */ +typedef struct _t_counters { + unsigned long long incoming; /**< @brief Incoming data total*/ + unsigned long long outgoing; /**< @brief Outgoing data total*/ + unsigned long long incoming_history; /**< @brief Incoming data before wifidog restarted*/ + unsigned long long outgoing_history; /**< @brief Outgoing data before wifidog restarted*/ + time_t last_updated; /**< @brief Last update of the counters */ +} t_counters; + +/** Client node for the connected client linked list. + */ +typedef struct _t_client { + struct _t_client *next; /**< @brief Pointer to the next client */ + char *ip; /**< @brief Client Ip address */ + char *mac; /**< @brief Client Mac address */ + char *token; /**< @brief Client token */ + unsigned int fw_connection_state; /**< @brief Connection state in the + firewall */ + int fd; /**< @brief Client HTTP socket (valid only + during login before one of the + _http_* function is called */ + t_counters counters; /**< @brief Counters for input/output of + the client. */ + + /*@breif:record the element create time + * GaomingPan + * */ + time_t record_time; + +} t_client; + +/** @brief Get the first element of the list of connected clients + */ +t_client *client_get_first_client(void); + +/** @brief Initializes the client list */ +void client_list_init(void); + +/** @brief Adds a new client to the connections list */ +t_client *client_list_append(const char *ip, const char *mac, const char *token); + +/** @brief Finds a client by its IP and MAC */ +t_client *client_list_find(const char *ip, const char *mac); + +/** @brief Finds a client only by its IP */ +t_client *client_list_find_by_ip(const char *ip); /* needed by fw_iptables.c, auth.c + * and wdctl_thread.c */ + +/** @brief Finds a client only by its Mac */ +t_client *client_list_find_by_mac(const char *mac); /* needed by wdctl_thread.c */ + +/** @brief Finds a client by its token */ +t_client *client_list_find_by_token(const char *token); + +/** @brief Deletes a client from the connections list */ +void client_list_delete(t_client *client); + +#define LOCK_CLIENT_LIST() do { \ + debug(LOG_DEBUG, "Locking client list"); \ + pthread_mutex_lock(&client_list_mutex); \ + debug(LOG_DEBUG, "Client list locked"); \ +} while (0) + +#define UNLOCK_CLIENT_LIST() do { \ + debug(LOG_DEBUG, "Unlocking client list"); \ + pthread_mutex_unlock(&client_list_mutex); \ + debug(LOG_DEBUG, "Client list unlocked"); \ +} while (0) + +#endif /* _CLIENT_LIST_H_ */ diff --git a/src/commandline.c b/src/commandline.c new file mode 100755 index 00000000..c45ee8e8 --- /dev/null +++ b/src/commandline.c @@ -0,0 +1,180 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file commandline.c + @brief Command line argument handling + @author Copyright (C) 2004 Philippe April +*/ + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "safe.h" +#include "conf.h" + +#include "../config.h" + +/* + * Holds an argv that could be passed to exec*() if we restart ourselves + */ +char ** restartargv = NULL; + +static void usage(void); + +/* + * A flag to denote whether we were restarted via a parent wifidog, or started normally + * 0 means normally, otherwise it will be populated by the PID of the parent + */ +pid_t restart_orig_pid = 0; + +/** @internal + * @brief Print usage + * + * Prints usage, called when wifidog is run with -h or with an unknown option + */ +static void +usage(void) +{ + printf("Usage: wifidog [options]\n"); + printf("\n"); + printf(" -c [filename] Use this config file\n"); + printf(" -f Run in foreground\n"); + printf(" -d Debug level\n"); + printf(" -s Log to syslog\n"); + printf(" -w Wdctl socket path\n"); + printf(" -h Print usage\n"); + printf(" -v Print version information\n"); + printf(" -x pid Used internally by WiFiDog when re-starting itself *DO NOT ISSUE THIS SWITCH MANUAlLY*\n"); + printf(" -i Internal socket path used when re-starting self\n"); + printf("\n"); +} + +/** Uses getopt() to parse the command line and set configuration values + * also populates restartargv + */ +void parse_commandline(int argc, char **argv) { + int c; + int skiponrestart; + int i; + + s_config *config = config_get_config(); + + //MAGIC 3: Our own -x, the pid, and NULL : + restartargv = safe_malloc((argc + 3) * sizeof(char*)); + i=0; + restartargv[i++] = safe_strdup(argv[0]); + + while (-1 != (c = getopt(argc, argv, "c:hfd:sw:vx:i:"))) { + + skiponrestart = 0; + + switch(c) { + + case 'h': + usage(); + exit(1); + break; + + case 'c': + if (optarg) { + strncpy(config->configfile, optarg, sizeof(config->configfile)); + } + break; + + case 'w': + if (optarg) { + free(config->wdctl_sock); + config->wdctl_sock = safe_strdup(optarg); + } + break; + + case 'f': + skiponrestart = 1; + config->daemon = 0; + break; + + case 'd': + if (optarg) { + config->debuglevel = atoi(optarg); + } + break; + + case 's': + config->log_syslog = 1; + break; + + case 'v': + printf("This is WiFiDog version " VERSION "\n"); + exit(1); + break; + + case 'x': + skiponrestart = 1; + if (optarg) { + restart_orig_pid = atoi(optarg); + } + else { + printf("The expected PID to the -x switch was not supplied!"); + exit(1); + } + break; + + case 'i': + if (optarg) { + free(config->internal_sock); + config->internal_sock = safe_strdup(optarg); + } + break; + + default: + usage(); + exit(1); + break; + + } + + if (!skiponrestart) { + /* Add it to restartargv */ + safe_asprintf(&(restartargv[i++]), "-%c", c); + if (optarg) { + restartargv[i++] = safe_strdup(optarg); + } + } + + } + + /* Finally, we should add the -x, pid and NULL to restartargv + * HOWEVER we cannot do it here, since this is called before we fork to background + * so we'll leave this job to gateway.c after forking is completed + * so that the correct PID is assigned + * + * We add 3 nulls, and the first 2 will be overridden later + */ + restartargv[i++] = NULL; + restartargv[i++] = NULL; + restartargv[i++] = NULL; + +} + diff --git a/src/commandline.h b/src/commandline.h new file mode 100755 index 00000000..d87b2342 --- /dev/null +++ b/src/commandline.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file commandline.h + @brief Command line argument handling + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _COMMANDLINE_H_ +#define _COMMANDLINE_H_ + +/** @brief Parses the command line and set the config accordingly */ +void parse_commandline(int, char**); + +#endif /* _COMMANDLINE_H_ */ diff --git a/src/common.h b/src/common.h new file mode 100755 index 00000000..5e25efb8 --- /dev/null +++ b/src/common.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file common.h + @brief Common constants and other bits + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +/** @brief Read buffer for socket read? */ +#define MAX_BUF 4096 + +#endif /* _COMMON_H_ */ diff --git a/src/conf.c b/src/conf.c new file mode 100755 index 00000000..a351d640 --- /dev/null +++ b/src/conf.c @@ -0,0 +1,1044 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @file conf.c + @brief Config file parsing + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2007 Benoit GrĂ©goire, Technologies Coeus inc. + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include + +#include +#include + +#include "common.h" +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "http.h" +#include "auth.h" +#include "firewall.h" + +#include "util.h" + + +/** @internal + * Holds the current configuration of the gateway */ +static s_config config; + +/** + * Mutex for the configuration file, used by the auth_servers related + * functions. */ +pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER; + +/** @internal + * A flag. If set to 1, there are missing or empty mandatory parameters in the config + */ +static int missing_parms; + +/** @internal + The different configuration options */ +typedef enum { + oBadOption, + oDaemon, + oDebugLevel, + oExternalInterface, + oGatewayID, + oGatewayInterface, + oGatewayAddress, + oGatewayPort, + oAuthServer, + oAuthServHostname, + oAuthServSSLAvailable, + oAuthServSSLPort, + oAuthServHTTPPort, + oAuthServPath, + oAuthServLoginScriptPathFragment, + oAuthServPortalScriptPathFragment, + oAuthServMsgScriptPathFragment, + oAuthServPingScriptPathFragment, + oAuthServAuthScriptPathFragment, + oHTTPDMaxConn, + oHTTPDName, + oHTTPDRealm, + oHTTPDUsername, + oHTTPDPassword, + oClientTimeout, + oCheckInterval, + oWdctlSocket, + oSyslogFacility, + oFirewallRule, + oFirewallRuleSet, + oTrustedMACList, + oUntrustedMACList, /*gaomingpan*/ + oHtmlMessageFile, + oProxyPort, + oWhiteList, /*limeng*/ + oBlackList, +} OpCodes; + +/** @internal + The config file keywords for the different configuration options */ +static const struct { + const char *name; + OpCodes opcode; +} keywords[] = { + { "daemon", oDaemon }, + { "debuglevel", oDebugLevel }, + { "externalinterface", oExternalInterface }, + { "gatewayid", oGatewayID }, + { "gatewayinterface", oGatewayInterface }, + { "gatewayaddress", oGatewayAddress }, + { "gatewayport", oGatewayPort }, + { "authserver", oAuthServer }, + { "httpdmaxconn", oHTTPDMaxConn }, + { "httpdname", oHTTPDName }, + { "httpdrealm", oHTTPDRealm }, + { "httpdusername", oHTTPDUsername }, + { "httpdpassword", oHTTPDPassword }, + { "clienttimeout", oClientTimeout }, + { "checkinterval", oCheckInterval }, + { "syslogfacility", oSyslogFacility }, + { "wdctlsocket", oWdctlSocket }, + { "hostname", oAuthServHostname }, + { "sslavailable", oAuthServSSLAvailable }, + { "sslport", oAuthServSSLPort }, + { "httpport", oAuthServHTTPPort }, + { "path", oAuthServPath }, + { "loginscriptpathfragment", oAuthServLoginScriptPathFragment }, + { "portalscriptpathfragment", oAuthServPortalScriptPathFragment }, + { "msgscriptpathfragment", oAuthServMsgScriptPathFragment }, + { "pingscriptpathfragment", oAuthServPingScriptPathFragment }, + { "authscriptpathfragment", oAuthServAuthScriptPathFragment }, + { "firewallruleset", oFirewallRuleSet }, + { "firewallrule", oFirewallRule }, + { "trustedmaclist", oTrustedMACList }, + { "untrustedMACList", oUntrustedMACList}, /*gaomingpan*/ + { "htmlmessagefile", oHtmlMessageFile }, + { "proxyport", oProxyPort }, + { "whitelist", oWhiteList}, /*limeng*/ + { "blacklist", oBlackList}, + { NULL, oBadOption }, +}; + +static void config_notnull(const void *parm, const char *parmname); +static int parse_boolean_value(char *); +static void parse_auth_server(FILE *, const char *, int *); +static int _parse_firewall_rule(const char *ruleset, char *leftover); +static void parse_firewall_ruleset(const char *, FILE *, const char *, int *); + +static OpCodes config_parse_token(const char *cp, const char *filename, int linenum); + +/** Accessor for the current gateway configuration +@return: A pointer to the current config. The pointer isn't opaque, but should be treated as READ-ONLY + */ +s_config * +config_get_config(void) +{ + return &config; +} + +/** Sets the default config parameters and initialises the configuration system */ +void +config_init(void) +{ + debug(LOG_DEBUG, "Setting default config parameters"); + strncpy(config.configfile, DEFAULT_CONFIGFILE, sizeof(config.configfile)); + config.htmlmsgfile = safe_strdup(DEFAULT_HTMLMSGFILE); + config.debuglevel = DEFAULT_DEBUGLEVEL; + config.httpdmaxconn = DEFAULT_HTTPDMAXCONN; + config.external_interface = NULL; + config.gw_id = DEFAULT_GATEWAYID; + config.gw_interface = NULL; + config.gw_address = NULL; + config.gw_port = DEFAULT_GATEWAYPORT; + config.auth_servers = NULL; + config.httpdname = NULL; + config.httpdrealm = DEFAULT_HTTPDNAME; + config.httpdusername = NULL; + config.httpdpassword = NULL; + config.clienttimeout = DEFAULT_CLIENTTIMEOUT; + config.checkinterval = DEFAULT_CHECKINTERVAL; + config.syslog_facility = DEFAULT_SYSLOG_FACILITY; + config.daemon = -1; + config.log_syslog = DEFAULT_LOG_SYSLOG; + config.wdctl_sock = safe_strdup(DEFAULT_WDCTL_SOCK); + config.internal_sock = safe_strdup(DEFAULT_INTERNAL_SOCK); + config.rulesets = NULL; + config.trustedmaclist = NULL; + config.untrustedmaclist = NULL; /*gaomingpan*/ + config.proxy_port = 0; + config.white_list = NULL; /*limeng*/ + config.black_list = NULL; + +} + +/** + * If the command-line didn't provide a config, use the default. + */ +void +config_init_override(void) +{ + if (config.daemon == -1) config.daemon = DEFAULT_DAEMON; +} + +/** @internal +Parses a single token from the config file +*/ +static OpCodes +config_parse_token(const char *cp, const char *filename, int linenum) +{ + int i; + + for (i = 0; keywords[i].name; i++) + if (strcasecmp(cp, keywords[i].name) == 0) + return keywords[i].opcode; + + debug(LOG_ERR, "%s: line %d: Bad configuration option: %s", + filename, linenum, cp); + return oBadOption; +} + +/** @internal +Parses auth server information +*/ +static void +parse_auth_server(FILE *file, const char *filename, int *linenum) +{ + char *host = NULL, + *path = NULL, + *loginscriptpathfragment = NULL, + *portalscriptpathfragment = NULL, + *msgscriptpathfragment = NULL, + *pingscriptpathfragment = NULL, + *authscriptpathfragment = NULL, + line[MAX_BUF], + *p1, + *p2; + int http_port, + ssl_port, + ssl_available, + opcode; + t_auth_serv *new, + *tmp; + + /* Defaults */ + path = safe_strdup(DEFAULT_AUTHSERVPATH); + loginscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVLOGINPATHFRAGMENT); + portalscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVPORTALPATHFRAGMENT); + msgscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVMSGPATHFRAGMENT); + pingscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVPINGPATHFRAGMENT); + authscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVAUTHPATHFRAGMENT); + http_port = DEFAULT_AUTHSERVPORT; + ssl_port = DEFAULT_AUTHSERVSSLPORT; + ssl_available = DEFAULT_AUTHSERVSSLAVAILABLE; + + + /* Parsing loop */ + while (memset(line, 0, MAX_BUF) && fgets(line, MAX_BUF - 1, file) && (strchr(line, '}') == NULL)) { + (*linenum)++; /* increment line counter. */ + + /* skip leading blank spaces */ + for (p1 = line; isblank(*p1); p1++); + + /* End at end of line */ + if ((p2 = strchr(p1, '#')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\r')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\n')) != NULL) { + *p2 = '\0'; + } + + /* next, we coopt the parsing of the regular config */ + if (strlen(p1) > 0) { + p2 = p1; + /* keep going until word boundary is found. */ + while ((*p2 != '\0') && (!isblank(*p2))) + p2++; + + /* Terminate first word. */ + *p2 = '\0'; + p2++; + + /* skip all further blanks. */ + while (isblank(*p2)) + p2++; + + /* Get opcode */ + opcode = config_parse_token(p1, filename, *linenum); + + switch (opcode) { + case oAuthServHostname: + host = safe_strdup(p2); + break; + case oAuthServPath: + free(path); + path = safe_strdup(p2); + break; + case oAuthServLoginScriptPathFragment: + free(loginscriptpathfragment); + loginscriptpathfragment = safe_strdup(p2); + break; + case oAuthServPortalScriptPathFragment: + free(portalscriptpathfragment); + portalscriptpathfragment = safe_strdup(p2); + break; + case oAuthServMsgScriptPathFragment: + free(msgscriptpathfragment); + msgscriptpathfragment = safe_strdup(p2); + break; + case oAuthServPingScriptPathFragment: + free(pingscriptpathfragment); + pingscriptpathfragment = safe_strdup(p2); + break; + case oAuthServAuthScriptPathFragment: + free(authscriptpathfragment); + authscriptpathfragment = safe_strdup(p2); + break; + case oAuthServSSLPort: + ssl_port = atoi(p2); + break; + case oAuthServHTTPPort: + http_port = atoi(p2); + break; + case oAuthServSSLAvailable: + ssl_available = parse_boolean_value(p2); + if (ssl_available < 0) + ssl_available = 0; + break; + case oBadOption: + default: + debug(LOG_ERR, "Bad option on line %d " + "in %s.", *linenum, + filename); + debug(LOG_ERR, "Exiting..."); + exit(-1); + break; + } + } + } + + /* only proceed if we have an host and a path */ + if (host == NULL) + return; + + debug(LOG_DEBUG, "Adding %s:%d (SSL: %d) %s to the auth server list", + host, http_port, ssl_port, path); + + /* Allocate memory */ + new = safe_malloc(sizeof(t_auth_serv)); + + /* Fill in struct */ + memset(new, 0, sizeof(t_auth_serv)); /*< Fill all with NULL */ + new->authserv_hostname = host; + new->authserv_use_ssl = ssl_available; + new->authserv_path = path; + new->authserv_login_script_path_fragment = loginscriptpathfragment; + new->authserv_portal_script_path_fragment = portalscriptpathfragment; + new->authserv_msg_script_path_fragment = msgscriptpathfragment; + new->authserv_ping_script_path_fragment = pingscriptpathfragment; + new->authserv_auth_script_path_fragment = authscriptpathfragment; + new->authserv_http_port = http_port; + new->authserv_ssl_port = ssl_port; + + /* If it's the first, add to config, else append to last server */ + if (config.auth_servers == NULL) { + config.auth_servers = new; + } else { + for (tmp = config.auth_servers; tmp->next != NULL; + tmp = tmp->next); + tmp->next = new; + } + + debug(LOG_DEBUG, "Auth server added"); +} + +/** +Advance to the next word +@param s string to parse, this is the next_word pointer, the value of s + when the macro is called is the current word, after the macro + completes, s contains the beginning of the NEXT word, so you + need to save s to something else before doing TO_NEXT_WORD +@param e should be 0 when calling TO_NEXT_WORD(), it'll be changed to 1 + if the end of the string is reached. +*/ +#define TO_NEXT_WORD(s, e) do { \ + while (*s != '\0' && !isblank(*s)) { \ + s++; \ + } \ + if (*s != '\0') { \ + *s = '\0'; \ + s++; \ + while (isblank(*s)) \ + s++; \ + } else { \ + e = 1; \ + } \ +} while (0) + +/** @internal +Parses firewall rule set information +*/ +static void +parse_firewall_ruleset(const char *ruleset, FILE *file, const char *filename, int *linenum) +{ + char line[MAX_BUF], + *p1, + *p2; + int opcode; + + debug(LOG_DEBUG, "Adding Firewall Rule Set %s", ruleset); + + /* Parsing loop */ + while (memset(line, 0, MAX_BUF) && fgets(line, MAX_BUF - 1, file) && (strchr(line, '}') == NULL)) { + (*linenum)++; /* increment line counter. */ + + /* skip leading blank spaces */ + for (p1 = line; isblank(*p1); p1++); + + /* End at end of line */ + if ((p2 = strchr(p1, '#')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\r')) != NULL) { + *p2 = '\0'; + } else if ((p2 = strchr(p1, '\n')) != NULL) { + *p2 = '\0'; + } + + /* next, we coopt the parsing of the regular config */ + if (strlen(p1) > 0) { + p2 = p1; + /* keep going until word boundary is found. */ + while ((*p2 != '\0') && (!isblank(*p2))) + p2++; + + /* Terminate first word. */ + *p2 = '\0'; + p2++; + + /* skip all further blanks. */ + while (isblank(*p2)) + p2++; + + /* Get opcode */ + opcode = config_parse_token(p1, filename, *linenum); + + debug(LOG_DEBUG, "p1 = [%s]; p2 = [%s]", p1, p2); + + switch (opcode) { + case oFirewallRule: + _parse_firewall_rule(ruleset, p2); + break; + + case oBadOption: + default: + debug(LOG_ERR, "Bad option on line %d " + "in %s.", *linenum, + filename); + debug(LOG_ERR, "Exiting..."); + exit(-1); + break; + } + } + } + + debug(LOG_DEBUG, "Firewall Rule Set %s added.", ruleset); +} + +/** @internal +Helper for parse_firewall_ruleset. Parses a single rule in a ruleset +*/ +static int +_parse_firewall_rule(const char *ruleset, char *leftover) +{ + int i; + t_firewall_target target = TARGET_REJECT; /**< firewall target */ + int all_nums = 1; /**< If 0, port contained non-numerics */ + int finished = 0; /**< reached end of line */ + char *token = NULL; /**< First word */ + char *port = NULL; /**< port to open/block */ + char *protocol = NULL; /**< protocol to block, tcp/udp/icmp */ + char *mask = NULL; /**< Netmask */ + char *other_kw = NULL; /**< other key word */ + t_firewall_ruleset *tmpr; + t_firewall_ruleset *tmpr2; + t_firewall_rule *tmp; + t_firewall_rule *tmp2; + + debug(LOG_DEBUG, "leftover: %s", leftover); + + /* lower case */ + for (i = 0; *(leftover + i) != '\0' + && (*(leftover + i) = tolower((unsigned char)*(leftover + i))); i++); + + token = leftover; + TO_NEXT_WORD(leftover, finished); + + /* Parse token */ + if (!strcasecmp(token, "block") || finished) { + target = TARGET_REJECT; + } else if (!strcasecmp(token, "drop")) { + target = TARGET_DROP; + } else if (!strcasecmp(token, "allow")) { + target = TARGET_ACCEPT; + } else if (!strcasecmp(token, "log")) { + target = TARGET_LOG; + } else if (!strcasecmp(token, "ulog")) { + target = TARGET_ULOG; + } else { + debug(LOG_ERR, "Invalid rule type %s, expecting " + "\"block\",\"drop\",\"allow\",\"log\" or \"ulog\"", token); + return -1; + } + + /* Parse the remainder */ + /* Get the protocol */ + if (strncmp(leftover, "tcp", 3) == 0 + || strncmp(leftover, "udp", 3) == 0 + || strncmp(leftover, "icmp", 4) == 0) { + protocol = leftover; + TO_NEXT_WORD(leftover, finished); + } + + /* should be exactly "port" */ + if (strncmp(leftover, "port", 4) == 0) { + TO_NEXT_WORD(leftover, finished); + /* Get port now */ + port = leftover; + TO_NEXT_WORD(leftover, finished); + for (i = 0; *(port + i) != '\0'; i++) + if (!isdigit((unsigned char)*(port + i))) + all_nums = 0; /*< No longer only digits */ + if (!all_nums) { + debug(LOG_ERR, "Invalid port %s", port); + return -3; /*< Fail */ + } + } + + /* Now, further stuff is optional */ + if (!finished) { + /* should be exactly "to" */ + other_kw = leftover; + TO_NEXT_WORD(leftover, finished); + if (strcmp(other_kw, "to") || finished) { + debug(LOG_ERR, "Invalid or unexpected keyword %s, " + "expecting \"to\"", other_kw); + return -4; /*< Fail */ + } + + /* Get port now */ + mask = leftover; + TO_NEXT_WORD(leftover, finished); + all_nums = 1; + for (i = 0; *(mask + i) != '\0'; i++) + if (!isdigit((unsigned char)*(mask + i)) && (*(mask + i) != '.') + && (*(mask + i) != '/')) + all_nums = 0; /*< No longer only digits */ + if (!all_nums) { + debug(LOG_ERR, "Invalid mask %s", mask); + return -3; /*< Fail */ + } + } + + /* Generate rule record */ + tmp = safe_malloc(sizeof(t_firewall_rule)); + memset((void *)tmp, 0, sizeof(t_firewall_rule)); + tmp->target = target; + if (protocol != NULL) + tmp->protocol = safe_strdup(protocol); + if (port != NULL) + tmp->port = safe_strdup(port); + if (mask == NULL) + tmp->mask = safe_strdup("0.0.0.0/0"); + else + tmp->mask = safe_strdup(mask); + + debug(LOG_DEBUG, "Adding Firewall Rule %s %s port %s to %s", token, tmp->protocol, tmp->port, tmp->mask); + + /* Append the rule record */ + if (config.rulesets == NULL) { + config.rulesets = safe_malloc(sizeof(t_firewall_ruleset)); + memset(config.rulesets, 0, sizeof(t_firewall_ruleset)); + config.rulesets->name = safe_strdup(ruleset); + tmpr = config.rulesets; + } else { + tmpr2 = tmpr = config.rulesets; + while (tmpr != NULL && (strcmp(tmpr->name, ruleset) != 0)) { + tmpr2 = tmpr; + tmpr = tmpr->next; + } + if (tmpr == NULL) { + /* Rule did not exist */ + tmpr = safe_malloc(sizeof(t_firewall_ruleset)); + memset(tmpr, 0, sizeof(t_firewall_ruleset)); + tmpr->name = safe_strdup(ruleset); + tmpr2->next = tmpr; + } + } + + /* At this point, tmpr == current ruleset */ + if (tmpr->rules == NULL) { + /* No rules... */ + tmpr->rules = tmp; + } else { + tmp2 = tmpr->rules; + while (tmp2->next != NULL) + tmp2 = tmp2->next; + tmp2->next = tmp; + } + + return 1; +} + +t_firewall_rule * +get_ruleset(const char *ruleset) +{ + t_firewall_ruleset *tmp; + + for (tmp = config.rulesets; tmp != NULL + && strcmp(tmp->name, ruleset) != 0; tmp = tmp->next); + + if (tmp == NULL) + return NULL; + + return(tmp->rules); +} + +/** +@param filename Full path of the configuration file to be read +*/ +void +config_read(const char *filename) +{ + FILE *fd; + char line[MAX_BUF], *s, *p1, *p2; + int linenum = 0, opcode, value, len; + + debug(LOG_INFO, "Reading configuration file '%s'", filename); + + if (!(fd = fopen(filename, "r"))) { + debug(LOG_ERR, "Could not open configuration file '%s', " + "exiting...", filename); + exit(1); + } + + while (!feof(fd) && fgets(line, MAX_BUF, fd)) { + linenum++; + s = line; + + if (s[strlen(s) - 1] == '\n') + s[strlen(s) - 1] = '\0'; + + if ((p1 = strchr(s, ' '))) { + p1[0] = '\0'; + } else if ((p1 = strchr(s, '\t'))) { + p1[0] = '\0'; + } + + if (p1) { + p1++; + + // Trim leading spaces + len = strlen(p1); + while (*p1 && len) { + if (*p1 == ' ') + p1++; + else + break; + len = strlen(p1); + } + + + if ((p2 = strchr(p1, ' '))) { + p2[0] = '\0'; + } else if ((p2 = strstr(p1, "\r\n"))) { + p2[0] = '\0'; + } else if ((p2 = strchr(p1, '\n'))) { + p2[0] = '\0'; + } + } + + if (p1 && p1[0] != '\0') { + /* Strip trailing spaces */ + + if ((strncmp(s, "#", 1)) != 0) { + debug(LOG_DEBUG, "Parsing token: %s, " + "value: %s", s, p1); + opcode = config_parse_token(s, filename, linenum); + + switch(opcode) { + case oDaemon: + if (config.daemon == -1 && ((value = parse_boolean_value(p1)) != -1)) { + config.daemon = value; + } + break; + case oExternalInterface: + config.external_interface = safe_strdup(p1); + break; + case oGatewayID: + config.gw_id = safe_strdup(p1); + break; + case oGatewayInterface: + config.gw_interface = safe_strdup(p1); + break; + case oGatewayAddress: + config.gw_address = safe_strdup(p1); + break; + case oGatewayPort: + sscanf(p1, "%d", &config.gw_port); + break; + case oAuthServer: + parse_auth_server(fd, filename, + &linenum); + break; + case oFirewallRuleSet: + parse_firewall_ruleset(p1, fd, filename, &linenum); + break; + case oTrustedMACList: + parse_trusted_mac_list(p1); + break; + /*gaomingpan*/ + case oUntrustedMACList: + parse_untrusted_mac_list(p1); + break; + case oHTTPDName: + config.httpdname = safe_strdup(p1); + break; + case oHTTPDMaxConn: + sscanf(p1, "%d", &config.httpdmaxconn); + break; + case oHTTPDRealm: + config.httpdrealm = safe_strdup(p1); + break; + case oHTTPDUsername: + config.httpdusername = safe_strdup(p1); + break; + case oHTTPDPassword: + config.httpdpassword = safe_strdup(p1); + break; + case oBadOption: + debug(LOG_ERR, "Bad option on line %d " + "in %s.", linenum, + filename); + debug(LOG_ERR, "Exiting..."); + exit(-1); + break; + case oCheckInterval: + sscanf(p1, "%d", &config.checkinterval); + break; + case oWdctlSocket: + free(config.wdctl_sock); + config.wdctl_sock = safe_strdup(p1); + break; + case oClientTimeout: + sscanf(p1, "%d", &config.clienttimeout); + break; + case oSyslogFacility: + sscanf(p1, "%d", &config.syslog_facility); + break; + case oHtmlMessageFile: + config.htmlmsgfile = safe_strdup(p1); + break; + case oProxyPort: + sscanf(p1, "%d", &config.proxy_port); + break; + /*limeng*/ + case oWhiteList: + parse_white_list(p1); + break; + case oBlackList: + parse_black_list(p1); + break; + + } + } + } + } + + if (config.httpdusername && !config.httpdpassword) { + debug(LOG_ERR, "HTTPDUserName requires a HTTPDPassword to be set."); + exit(-1); + } + + fclose(fd); +} + +/** @internal +Parses a boolean value from the config file +*/ +static int +parse_boolean_value(char *line) +{ + if (strcasecmp(line, "yes") == 0) { + return 1; + } + if (strcasecmp(line, "no") == 0) { + return 0; + } + if (strcmp(line, "1") == 0) { + return 1; + } + if (strcmp(line, "0") == 0) { + return 0; + } + + return -1; +} + +void parse_trusted_mac_list(const char *ptr) { + char *ptrcopy = NULL; + char *possiblemac = NULL; + char *mac = NULL; + t_trusted_mac *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for trusted MAC addresses", ptr); + + mac = safe_malloc(18); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblemac = strsep(&ptrcopy, ", "))) { + if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { + /* Copy mac to the list */ + + debug(LOG_DEBUG, "Adding MAC address [%s] to trusted list", mac); + + if (config.trustedmaclist == NULL) { + config.trustedmaclist = safe_malloc(sizeof(t_trusted_mac)); + config.trustedmaclist->mac = safe_strdup(mac); + config.trustedmaclist->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.trustedmaclist; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_trusted_mac)); + p = p->next; + p->mac = safe_strdup(mac); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(mac); + +} + +/*gaomingpan*/ +void parse_untrusted_mac_list(const char *ptr) +{ + char *ptrcopy = NULL; + char *possiblemac = NULL; + char *mac = NULL; + t_untrusted_mac *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for untrusted MAC addresses", ptr); + + mac = safe_malloc(18); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblemac = strsep(&ptrcopy, ", "))) { + if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { + /* Copy mac to the list */ + + debug(LOG_DEBUG, "Adding MAC address [%s] to untrusted list", mac); + + if (config.untrustedmaclist == NULL) { + config.untrustedmaclist = safe_malloc(sizeof(t_trusted_mac)); + config.untrustedmaclist->mac = safe_strdup(mac); + config.untrustedmaclist->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.untrustedmaclist; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_untrusted_mac)); + p = p->next; + p->mac = safe_strdup(mac); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(mac); +} + + + +/*limeng*/ +void parse_white_list(const char *ptr) { + char *ptrcopy = NULL; + char *possiblewhitelist = NULL; + char *ip = NULL; + t_white_list *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for white list addresses", ptr); + + ip = safe_malloc(512); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblewhitelist = strsep(&ptrcopy, ", "))) { + if (sscanf(possiblewhitelist, " %s[A-Za-z0-9.]", ip) == 1) { + /* Copy white list to the list */ + + debug(LOG_DEBUG, "Adding ip address [%s] to white list", ip); + + if (config.white_list == NULL) { + config.white_list = safe_malloc(sizeof(t_white_list)); + config.white_list->ip = safe_strdup(ip); + config.white_list->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.white_list; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_white_list)); + p = p->next; + p->ip = safe_strdup(ip); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(ip); + +} + +void parse_black_list(const char *ptr) { + char *ptrcopy = NULL; + char *possibleblacklist = NULL; + char *ip = NULL; + t_black_list *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for black list addresses", ptr); + + ip = safe_malloc(512); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possibleblacklist = strsep(&ptrcopy, ", "))) { + if (sscanf(possibleblacklist, " %s[A-Za-z0-9.]", ip) == 1) { + /* Copy black list to the list */ + + debug(LOG_DEBUG, "Adding ip address [%s] to black list", ip); + + if (config.black_list == NULL) { + config.black_list = safe_malloc(sizeof(t_black_list)); + config.black_list->ip = safe_strdup(ip); + config.black_list->next = NULL; + } + else { + /* Advance to the last entry */ + for (p = config.black_list; p->next != NULL; p = p->next); + p->next = safe_malloc(sizeof(t_black_list)); + p = p->next; + p->ip = safe_strdup(ip); + p->next = NULL; + } + + } + } + + free(ptrcopy); + + free(ip); + +} + + + +/** Verifies if the configuration is complete and valid. Terminates the program if it isn't */ +void +config_validate(void) +{ + config_notnull(config.gw_interface, "GatewayInterface"); + config_notnull(config.auth_servers, "AuthServer"); + + if (missing_parms) { + debug(LOG_ERR, "Configuration is not complete, exiting..."); + exit(-1); + } +} + +/** @internal + Verifies that a required parameter is not a null pointer +*/ +static void +config_notnull(const void *parm, const char *parmname) +{ + if (parm == NULL) { + debug(LOG_ERR, "%s is not set", parmname); + missing_parms = 1; + } +} + +/** + * This function returns the current (first auth_server) + */ +t_auth_serv * +get_auth_server(void) +{ + + /* This is as good as atomic */ + return config.auth_servers; +} + +/** + * This function marks the current auth_server, if it matches the argument, + * as bad. Basically, the "bad" server becomes the last one on the list. + */ +void +mark_auth_server_bad(t_auth_serv *bad_server) +{ + t_auth_serv *tmp; + + if (config.auth_servers == bad_server && bad_server->next != NULL) { + /* Go to the last */ + for (tmp = config.auth_servers; tmp->next != NULL; tmp = tmp->next); + /* Set bad server as last */ + tmp->next = bad_server; + /* Remove bad server from start of list */ + config.auth_servers = bad_server->next; + /* Set the next pointe to NULL in the last element */ + bad_server->next = NULL; + } + +} diff --git a/src/conf.h b/src/conf.h new file mode 100755 index 00000000..b4c289bd --- /dev/null +++ b/src/conf.h @@ -0,0 +1,244 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file conf.h + @brief Config file parsing + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/*@{*/ +/** Defines */ +/** How many times should we try detecting the interface with the default route + * (in seconds). If set to 0, it will keep retrying forever */ +#define NUM_EXT_INTERFACE_DETECT_RETRY 0 +/** How often should we try to detect the interface with the default route + * if it isn't up yet (interval in seconds) */ +#define EXT_INTERFACE_DETECT_RETRY_INTERVAL 1 + +/** Defaults configuration values */ +#ifndef SYSCONFDIR + #define DEFAULT_CONFIGFILE "/etc/wifidog.conf" + #define DEFAULT_HTMLMSGFILE "/etc/wifidog-msg.html" +#else + #define DEFAULT_CONFIGFILE SYSCONFDIR"/wifidog.conf" + #define DEFAULT_HTMLMSGFILE SYSCONFDIR"/wifidog-msg.html" +#endif +#define DEFAULT_DAEMON 1 +#define DEFAULT_DEBUGLEVEL LOG_INFO +#define DEFAULT_HTTPDMAXCONN 10 +#define DEFAULT_GATEWAYID NULL +#define DEFAULT_GATEWAYPORT 2060 +#define DEFAULT_HTTPDNAME "WiFiDog" +#define DEFAULT_CLIENTTIMEOUT 5 +//#define DEFAULT_CHECKINTERVAL 60 +#define DEFAULT_CHECKINTERVAL 30 +#define DEFAULT_LOG_SYSLOG 1 +#define DEFAULT_SYSLOG_FACILITY LOG_DAEMON +#define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" +#define DEFAULT_INTERNAL_SOCK "/tmp/wifidog.sock" +#define DEFAULT_AUTHSERVPORT 80 +#define DEFAULT_AUTHSERVSSLPORT 443 +/** Note that DEFAULT_AUTHSERVSSLAVAILABLE must be 0 or 1, even if the config file syntax is yes or no */ +#define DEFAULT_AUTHSERVSSLAVAILABLE 0 +/** Note: The path must be prefixed by /, and must be suffixed /. Put / for the server root.*/ +#define DEFAULT_AUTHSERVPATH "/wifidog/" +#define DEFAULT_AUTHSERVLOGINPATHFRAGMENT "login/?" +#define DEFAULT_AUTHSERVPORTALPATHFRAGMENT "portal/?" +#define DEFAULT_AUTHSERVMSGPATHFRAGMENT "gw_message.php?" +#define DEFAULT_AUTHSERVPINGPATHFRAGMENT "ping/?" +#define DEFAULT_AUTHSERVAUTHPATHFRAGMENT "auth/?" +/*@}*/ + +/** + * Information about the authentication server + */ +typedef struct _auth_serv_t { + char *authserv_hostname; /**< @brief Hostname of the central server */ + char *authserv_path; /**< @brief Path where wifidog resides */ + char *authserv_login_script_path_fragment; /**< @brief This is the script the user will be sent to for login. */ + char *authserv_portal_script_path_fragment; /**< @brief This is the script the user will be sent to after a successfull login. */ + char *authserv_msg_script_path_fragment; /**< @brief This is the script the user will be sent to upon error to read a readable message. */ + char *authserv_ping_script_path_fragment; /**< @brief This is the ping heartbeating script. */ + char *authserv_auth_script_path_fragment; /**< @brief This is the script that talks the wifidog gateway protocol. */ + int authserv_http_port; /**< @brief Http port the central server + listens on */ + int authserv_ssl_port; /**< @brief Https port the central server + listens on */ + int authserv_use_ssl; /**< @brief Use SSL or not */ + char *last_ip; /**< @brief Last ip used by authserver */ + struct _auth_serv_t *next; +} t_auth_serv; + +/** + * Firewall targets + */ +typedef enum { + TARGET_DROP, + TARGET_REJECT, + TARGET_ACCEPT, + TARGET_LOG, + TARGET_ULOG +} t_firewall_target; + +/** + * Firewall rules + */ +typedef struct _firewall_rule_t { + t_firewall_target target; /**< @brief t_firewall_target */ + char *protocol; /**< @brief tcp, udp, etc ... */ + char *port; /**< @brief Port to block/allow */ + char *mask; /**< @brief Mask for the rule *destination* */ + struct _firewall_rule_t *next; +} t_firewall_rule; + +/** + * Firewall rulesets + */ +typedef struct _firewall_ruleset_t { + char *name; + t_firewall_rule *rules; + struct _firewall_ruleset_t *next; +} t_firewall_ruleset; + +/** + * Trusted MAC Addresses + */ +typedef struct _trusted_mac_t { + char *mac; + struct _trusted_mac_t *next; +} t_trusted_mac; + +/** + * gaomingpan + * untrusted mac addresses + * */ +typedef struct _untrusted_mac_t { + char *mac; + struct _untrusted_mac_t *next; +} t_untrusted_mac; + +/*limeng*/ +/** + * Trusted White list Addresses + */ +typedef struct _white_list_t { + char *ip; + struct _white_list_t *next; +} t_white_list; + +typedef struct _black_list_t { + char *ip; + struct _black_list_t *next; +} t_black_list; + + +/** + * Configuration structure + */ +typedef struct { + char configfile[255]; /**< @brief name of the config file */ + char *htmlmsgfile; /**< @brief name of the HTML file used for messages */ + char *wdctl_sock; /**< @brief wdctl path to socket */ + char *internal_sock; /**< @brief internal path to socket */ + int daemon; /**< @brief if daemon > 0, use daemon mode */ + int debuglevel; /**< @brief Debug information verbosity */ + char *external_interface; /**< @brief External network interface name for + firewall rules */ + char *gw_id; /**< @brief ID of the Gateway, sent to central + server */ + char *gw_interface; /**< @brief Interface we will accept connections on */ + char *gw_address; /**< @brief Internal IP address for our web + server */ + int gw_port; /**< @brief Port the webserver will run on */ + + t_auth_serv *auth_servers; /**< @brief Auth servers list */ + char *httpdname; /**< @brief Name the web server will return when + replying to a request */ + int httpdmaxconn; /**< @brief Used by libhttpd, not sure what it + does */ + char *httpdrealm; /**< @brief HTTP Authentication realm */ + char *httpdusername; /**< @brief Username for HTTP authentication */ + char *httpdpassword; /**< @brief Password for HTTP authentication */ + int clienttimeout; /**< @brief How many CheckIntervals before a client + must be re-authenticated */ + int checkinterval; /**< @brief Frequency the the client timeout check + thread will run. */ + int log_syslog; /**< @brief boolean, wether to log to syslog */ + int syslog_facility; /**< @brief facility to use when using syslog for + logging */ + int proxy_port; /**< @brief Transparent proxy port (0 to disable) */ + /*limeng*/ + t_white_list *white_list; /**< @brief White list */ + t_black_list *black_list; /**< @brief black list */ + t_firewall_ruleset *rulesets; /**< @brief firewall rules */ + t_trusted_mac *trustedmaclist; /**< @brief list of trusted macs */ + t_untrusted_mac *untrustedmaclist; /**< @brief list of untrusted macs*/ +} s_config; + +/** @brief Get the current gateway configuration */ +s_config *config_get_config(void); + +/** @brief Initialise the conf system */ +void config_init(void); + +/** @brief Initialize the variables we override with the command line*/ +void config_init_override(void); + +/** @brief Reads the configuration file */ +void config_read(const char *filename); + +/** @brief Check that the configuration is valid */ +void config_validate(void); + +/** @brief Get the active auth server */ +t_auth_serv *get_auth_server(void); + +/** @brief Bump server to bottom of the list */ +void mark_auth_server_bad(t_auth_serv *); + +/** @brief Fetch a firewall rule set. */ +t_firewall_rule *get_ruleset(const char *); + +void parse_trusted_mac_list(const char *); + +/*gaomingpan*/ +void parse_untrusted_mac_list(const char *); + +/* limeng */ +void parse_white_list(const char *); +void parse_black_list(const char *) ; + +#define LOCK_CONFIG() do { \ + debug(LOG_DEBUG, "Locking config"); \ + pthread_mutex_lock(&config_mutex); \ + debug(LOG_DEBUG, "Config locked"); \ +} while (0) + +#define UNLOCK_CONFIG() do { \ + debug(LOG_DEBUG, "Unlocking config"); \ + pthread_mutex_unlock(&config_mutex); \ + debug(LOG_DEBUG, "Config unlocked"); \ +} while (0) + +#endif /* _CONFIG_H_ */ diff --git a/src/debug.c b/src/debug.c new file mode 100755 index 00000000..529c4cf4 --- /dev/null +++ b/src/debug.c @@ -0,0 +1,76 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file debug.c + @brief Debug output routines + @author Copyright (C) 2004 Philippe April +*/ + +#include +#include +#include +#include +#include +#include + +#include "conf.h" + +/** @internal +Do not use directly, use the debug macro */ +void +_debug(const char *filename, int line, int level, const char *format, ...) +{ + char buf[28]; + va_list vlist; + s_config *config = config_get_config(); + time_t ts; + + time(&ts); + + if (config->debuglevel >= level) { + + if (level <= LOG_WARNING) { + fprintf(stderr, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), + filename, line); + va_start(vlist, format); + vfprintf(stderr, format, vlist); + va_end(vlist); + fputc('\n', stderr); + } else if (!config->daemon) { + fprintf(stdout, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), + filename, line); + va_start(vlist, format); + vfprintf(stdout, format, vlist); + va_end(vlist); + fputc('\n', stdout); + fflush(stdout); + } + + if (config->log_syslog) { + openlog("wifidog", LOG_PID, config->syslog_facility); + va_start(vlist, format); + vsyslog(level, format, vlist); + va_end(vlist); + closelog(); + } + } +} + diff --git a/src/debug.h b/src/debug.h new file mode 100755 index 00000000..94744fa1 --- /dev/null +++ b/src/debug.h @@ -0,0 +1,38 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file debug.h + @brief Debug output routines + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +/** @brief Used to output messages. + *The messages will include the finlname and line number, and will be sent to syslog if so configured in the config file + */ +#define debug(level, format...) _debug(__FILE__, __LINE__, level, format) + +/** @internal */ +void _debug(const char *filename, int line, int level, const char *format, ...); + +#endif /* _DEBUG_H_ */ diff --git a/src/device_key.c b/src/device_key.c new file mode 100644 index 00000000..f9ebc668 --- /dev/null +++ b/src/device_key.c @@ -0,0 +1,55 @@ +/* + * device_key.c + * + * Created on: Aug 14, 2015 + * Author: GaomingPan + */ + +#include +#include +#include + +#include "device_key.h" + + +static char device_key[64] = {0}; + + + +char * get_device_key() +{ + return device_key; +} + + + + + +int init_device_key() +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t read_len; + + fp = fopen(DEVICE_KEY_FILE,"r"); + if(NULL == fp) + { + return -1; + } + while((read_len = getline(&line,&len,fp)) != -1) + { + if('#' == line[0] || ' ' == line[0] || '\t' == line[0]) + continue; + else + { + sprintf(device_key,"%s",line); + free(line); + fclose(fp); + return 0; + } + } + free(line); + fclose(fp); + return -2; +} diff --git a/src/device_key.h b/src/device_key.h new file mode 100644 index 00000000..872a4784 --- /dev/null +++ b/src/device_key.h @@ -0,0 +1,19 @@ +/* + * device_key.h + * + * Created on: Aug 14, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_DEVICE_KEY_H_ +#define SRC_DEVICE_KEY_H_ + + +#define DEVICE_KEY_FILE "/etc/.devicekey" + +char * get_device_key(); + + +int init_device_key(); + +#endif /* SRC_DEVICE_KEY_H_ */ diff --git a/src/firewall.c b/src/firewall.c new file mode 100755 index 00000000..a3f20428 --- /dev/null +++ b/src/firewall.c @@ -0,0 +1,424 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** @internal + @file firewall.c + @brief Firewall update functions + @author Copyright (C) 2004 Philippe April + 2006 Benoit GrĂ©goire, Technologies Coeus inc. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#include +#include +#endif + +#if defined(__NetBSD__) +#include +#include +#include +#endif + +#include "httpd.h" +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "firewall.h" +#include "fw_iptables.h" +#include "auth.h" +#include "centralserver.h" +#include "client_list.h" + +#include "get_clientinfo.h" + +extern pthread_mutex_t client_list_mutex; + +/* from commandline.c */ +extern pid_t restart_orig_pid; + + + +/** + * Allow a client access through the firewall by adding a rule in the firewall to MARK the user's packets with the proper + * rule by providing his IP and MAC address + * @param ip IP address to allow + * @param mac MAC address to allow + * @param fw_connection_state fw_connection_state Tag + * @return Return code of the command + */ +int +fw_allow(const char *ip, const char *mac, int fw_connection_state) +{ + debug(LOG_DEBUG, "Allowing %s %s with fw_connection_state %d", ip, mac, fw_connection_state); + + return iptables_fw_access(FW_ACCESS_ALLOW, ip, mac, fw_connection_state); +} + +/** + * @brief Deny a client access through the firewall by removing the rule in the firewall that was fw_connection_stateging the user's traffic + * @param ip IP address to deny + * @param mac MAC address to deny + * @param fw_connection_state fw_connection_state Tag + * @return Return code of the command + */ +int +fw_deny(const char *ip, const char *mac, int fw_connection_state) +{ + debug(LOG_DEBUG, "Denying %s %s with fw_connection_state %d", ip, mac, fw_connection_state); + + return iptables_fw_access(FW_ACCESS_DENY, ip, mac, fw_connection_state); +} + +/* XXX DCY */ +/** + * Get an IP's MAC address from the ARP cache. + * Go through all the entries in /proc/net/arp until we find the requested + * IP address and return the MAC address bound to it. + * @todo Make this function portable (using shell scripts?) + */ +char * +arp_get(const char *req_ip) +{ + FILE *proc; + char ip[16]; + char mac[18]; + char * reply = NULL; + + if (!(proc = fopen("/proc/net/arp", "r"))) { + return NULL; + } + + /* Skip first line */ + while (!feof(proc) && fgetc(proc) != '\n'); + + /* Find ip, copy mac in reply */ + reply = NULL; + while (!feof(proc) && (fscanf(proc, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %*s", ip, mac) == 2)) { + if (strcmp(ip, req_ip) == 0) { + reply = safe_strdup(mac); + break; + } + } + + fclose(proc); + + return reply; +} + +/** Initialize the firewall rules + */ +int +fw_init(void) +{ + int flags, oneopt = 1, zeroopt = 0; + int result = 0; + t_client * client = NULL; + + debug(LOG_INFO, "Creating ICMP socket"); + if ((icmp_fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1 || + (flags = fcntl(icmp_fd, F_GETFL, 0)) == -1 || + fcntl(icmp_fd, F_SETFL, flags | O_NONBLOCK) == -1 || + setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) || + setsockopt(icmp_fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1) { + debug(LOG_ERR, "Cannot create ICMP raw socket."); + return 0; + } + + debug(LOG_INFO, "Initializing Firewall"); + result = iptables_fw_init(); + + if (restart_orig_pid) { + debug(LOG_INFO, "Restoring firewall rules for clients inherited from parent"); + LOCK_CLIENT_LIST(); + client = client_get_first_client(); + while (client) { + fw_allow(client->ip, client->mac, client->fw_connection_state); + client = client->next; + } + UNLOCK_CLIENT_LIST(); + } + + return result; +} + +/** Remove all auth server firewall whitelist rules + */ +void +fw_clear_authservers(void) +{ + debug(LOG_INFO, "Clearing the authservers list"); + iptables_fw_clear_authservers(); +} + +/** Add the necessary firewall rules to whitelist the authservers + */ +void +fw_set_authservers(void) +{ + debug(LOG_INFO, "Setting the authservers list"); + iptables_fw_set_authservers(); +} + +/** Remove the firewall rules + * This is used when we do a clean shutdown of WiFiDog. + * @return Return code of the fw.destroy script + */ +int +fw_destroy(void) +{ + if (icmp_fd != 0) { + debug(LOG_INFO, "Closing ICMP socket"); + close(icmp_fd); + } + + debug(LOG_INFO, "Removing Firewall rules"); + return iptables_fw_destroy(); +} + +/**Probably a misnomer, this function actually refreshes the entire client list's traffic counter, re-authenticates every client with the central server and update's the central servers traffic counters and notifies it if a client has logged-out. + * @todo Make this function smaller and use sub-fonctions + */ +void +fw_sync_with_authserver(void) +{ + t_authresponse authresponse; + char *token, *ip, *mac; + t_client *p1, *p2; + unsigned long long incoming, outgoing; + s_config *config = config_get_config(); + + if (-1 == iptables_fw_counters_update()) { + debug(LOG_ERR, "Could not get counters from firewall!"); + return; + } + set_client_auth_flag(); + LOCK_CLIENT_LIST(); + + for (p1 = p2 = client_get_first_client(); NULL != p1; p1 = p2) { + p2 = p1->next; + + ip = safe_strdup(p1->ip); + token = safe_strdup(p1->token); + mac = safe_strdup(p1->mac); + outgoing = p1->counters.outgoing; + incoming = p1->counters.incoming; + + UNLOCK_CLIENT_LIST(); + /* Ping the client, if he responds it'll keep activity on the link. + * However, if the firewall blocks it, it will not help. The suggested + * way to deal witht his is to keep the DHCP lease time extremely + * short: Shorter than config->checkinterval * config->clienttimeout */ + icmp_ping(ip); + /* Update the counters on the remote server only if we have an auth server */ + if (config->auth_servers != NULL) { + auth_server_request(&authresponse, REQUEST_TYPE_COUNTERS, ip, mac, token, incoming, outgoing); + } + LOCK_CLIENT_LIST(); + + if (!(p1 = client_list_find(ip, mac))) { + debug(LOG_ERR, "Node %s was freed while being re-validated!", ip); + } else { + time_t current_time=time(NULL); + debug(LOG_INFO, "Checking client %s for timeout: Last updated %ld (%ld seconds ago), timeout delay %ld seconds, current time %ld, ", + p1->ip, p1->counters.last_updated, current_time-p1->counters.last_updated, config->checkinterval * config->clienttimeout, current_time); + if (p1->counters.last_updated + + (config->checkinterval * config->clienttimeout) + <= current_time) { + /* Timing out user */ + debug(LOG_INFO, "%s - Inactive for more than %ld seconds, removing client and denying in firewall", + p1->ip, config->checkinterval * config->clienttimeout); + fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + client_list_delete(p1); + + /* Advertise the logout if we have an auth server */ + if (config->auth_servers != NULL) { + UNLOCK_CLIENT_LIST(); + auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token, 0, 0); + LOCK_CLIENT_LIST(); + } + } else { + /* + * This handles any change in + * the status this allows us + * to change the status of a + * user while he's connected + * + * Only run if we have an auth server + * configured! + */ + if (config->auth_servers != NULL) { + switch (authresponse.authcode) { + case AUTH_DENIED: + debug(LOG_NOTICE, "%s - Denied. Removing client and firewall rules", p1->ip); + fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + client_list_delete(p1); + break; + + case AUTH_VALIDATION_FAILED: + debug(LOG_NOTICE, "%s - Validation timeout, now denied. Removing client and firewall rules", p1->ip); + fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + client_list_delete(p1); + break; + + case AUTH_ALLOWED: + if (p1->fw_connection_state != FW_MARK_KNOWN) { + debug(LOG_INFO, "%s - Access has changed to allowed, refreshing firewall and clearing counters", p1->ip); + //WHY did we deny, then allow!?!? benoitg 2007-06-21 + //fw_deny(p1->ip, p1->mac, p1->fw_connection_state); + + if (p1->fw_connection_state != FW_MARK_PROBATION) { + p1->counters.incoming = p1->counters.outgoing = 0; + } + else { + //We don't want to clear counters if the user was in validation, it probably already transmitted data.. + debug(LOG_INFO, "%s - Skipped clearing counters after all, the user was previously in validation", p1->ip); + } + p1->fw_connection_state = FW_MARK_KNOWN; + fw_allow(p1->ip, p1->mac, p1->fw_connection_state); + } + break; + + case AUTH_VALIDATION: + /* + * Do nothing, user + * is in validation + * period + */ + debug(LOG_INFO, "%s - User in validation period", p1->ip); + break; + + case AUTH_ERROR: + debug(LOG_WARNING, "Error communicating with auth server - leaving %s as-is for now", p1->ip); + break; + + default: + debug(LOG_ERR, "I do not know about authentication code %d", authresponse.authcode); + break; + } + } + } + } + + free(token); + free(ip); + free(mac); + } + UNLOCK_CLIENT_LIST(); +} + +void +icmp_ping(const char *host) +{ + struct sockaddr_in saddr; +#if defined(__linux__) || defined(__NetBSD__) + struct { + struct ip ip; + struct icmp icmp; + } packet; +#endif + unsigned int i, j; + int opt = 2000; + unsigned short id = rand16(); + + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + inet_aton(host, &saddr.sin_addr); +#if defined(HAVE_SOCKADDR_SA_LEN) || defined(__NetBSD__) + saddr.sin_len = sizeof(struct sockaddr_in); +#endif + +#if defined(__linux__) || defined(__NetBSD__) + memset(&packet.icmp, 0, sizeof(packet.icmp)); + packet.icmp.icmp_type = ICMP_ECHO; + packet.icmp.icmp_id = id; + + for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++) + j += ((unsigned short *)&packet.icmp)[i]; + + while (j >> 16) + j = (j & 0xffff) + (j >> 16); + + packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j; + + if (setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == -1) + debug(LOG_ERR, "setsockopt(): %s", strerror(errno)); + + if (sendto(icmp_fd, (char *)&packet.icmp, sizeof(struct icmp), 0, + (const struct sockaddr *)&saddr, sizeof(saddr)) == -1) + debug(LOG_ERR, "sendto(): %s", strerror(errno)); + + opt = 1; + if (setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == -1) + debug(LOG_ERR, "setsockopt(): %s", strerror(errno)); +#endif + + return; +} + +unsigned short rand16(void) { + static int been_seeded = 0; + + if (!been_seeded) { + unsigned int seed = 0; + struct timeval now; + + /* not a very good seed but what the heck, it needs to be quickly acquired */ + gettimeofday(&now, NULL); + seed = now.tv_sec ^ now.tv_usec ^ (getpid() << 16); + + srand(seed); + been_seeded = 1; + } + + /* Some rand() implementations have less randomness in low bits + * than in high bits, so we only pay attention to the high ones. + * But most implementations don't touch the high bit, so we + * ignore that one. + **/ + return( (unsigned short) (rand() >> 15) ); +} diff --git a/src/firewall.h b/src/firewall.h new file mode 100755 index 00000000..45235b07 --- /dev/null +++ b/src/firewall.h @@ -0,0 +1,70 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file firewall.h + @brief Firewall update functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _FIREWALL_H_ +#define _FIREWALL_H_ + +int icmp_fd; + +/** Used by fw_iptables.c */ +typedef enum _t_fw_marks { + FW_MARK_PROBATION = 1, /**< @brief The client is in probation period and must be authenticated + @todo: VERIFY THAT THIS IS ACCURATE*/ + FW_MARK_KNOWN = 2, /**< @brief The client is known to the firewall */ + FW_MARK_LOCKED = 254 /**< @brief The client has been locked out */ +} t_fw_marks; + +/** @brief Initialize the firewall */ +int fw_init(void); + +/** @brief Clears the authservers list */ +void fw_clear_authservers(void); + +/** @brief Sets the authservers list */ +void fw_set_authservers(void); + +/** @brief Destroy the firewall */ +int fw_destroy(void); + +/** @brief Allow a user through the firewall*/ +int fw_allow(const char *ip, const char *mac, int profile); + +/** @brief Deny a client access through the firewall*/ +int fw_deny(const char *ip, const char *mac, int profile); + +/** @brief Refreshes the entire client list */ +void fw_sync_with_authserver(void); + +/** @brief Get an IP's MAC address from the ARP cache.*/ +char *arp_get(const char *req_ip); + +/** @brief ICMP Ping an IP */ +void icmp_ping(const char *host); + +/** @brief cheap random */ +unsigned short rand16(void); + +#endif /* _FIREWALL_H_ */ diff --git a/src/fw_iptables.c b/src/fw_iptables.c new file mode 100755 index 00000000..bda82ca3 --- /dev/null +++ b/src/fw_iptables.c @@ -0,0 +1,720 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @internal + @file fw_iptables.c + @brief Firewall iptables functions + @author Copyright (C) 2004 Philippe April + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "safe.h" +#include "conf.h" +#include "fw_iptables.h" +#include "firewall.h" +#include "debug.h" +#include "util.h" +#include "client_list.h" + +/*limeng*/ +#include + +static int iptables_do_command(const char *format, ...); +static char *iptables_compile(const char *, const char *, const t_firewall_rule *); +static void iptables_load_ruleset(const char *, const char *, const char *); + +extern pthread_mutex_t client_list_mutex; +extern pthread_mutex_t config_mutex; + +/** +Used to supress the error output of the firewall during destruction */ +static int fw_quiet = 0; + +/** @internal + * @brief Insert $ID$ with the gateway's id in a string. + * + * This function can replace the input string with a new one. It assumes + * the input string is dynamically allocted and can be free()ed safely. + * + * This function must be called with the CONFIG_LOCK held. + */ +static void +iptables_insert_gateway_id(char **input) +{ + char *token; + const s_config *config; + char *buffer; + + if (strstr(*input, "$ID$")==NULL) + return; + + + while ((token=strstr(*input, "$ID$"))!=NULL) + /* This string may look odd but it's standard POSIX and ISO C */ + memcpy(token, "%1$s", 4); + + config = config_get_config(); + safe_asprintf(&buffer, *input, config->gw_interface); + + free(*input); + *input=buffer; +} + +/** @internal + * */ +static int +iptables_do_command(const char *format, ...) +{ + va_list vlist; + char *fmt_cmd; + char *cmd; + int rc; + + va_start(vlist, format); + safe_vasprintf(&fmt_cmd, format, vlist); + va_end(vlist); + + safe_asprintf(&cmd, "iptables %s", fmt_cmd); + free(fmt_cmd); + + iptables_insert_gateway_id(&cmd); + + debug(LOG_DEBUG, "Executing command: %s", cmd); + + rc = execute(cmd, fw_quiet); + + if (rc!=0) { + // If quiet, do not display the error + if (fw_quiet == 0) + debug(LOG_ERR, "iptables command failed(%d): %s", rc, cmd); + else if (fw_quiet == 1) + debug(LOG_DEBUG, "iptables command failed(%d): %s", rc, cmd); + } + + free(cmd); + + return rc; +} + +/** + * @internal + * Compiles a struct definition of a firewall rule into a valid iptables + * command. + * @arg table Table containing the chain. + * @arg chain Chain that the command will be (-A)ppended to. + * @arg rule Definition of a rule into a struct, from conf.c. + */ + static char * +iptables_compile(const char * table, const char *chain, const t_firewall_rule *rule) +{ + char command[MAX_BUF], + *mode; + + memset(command, 0, MAX_BUF); + + switch (rule->target){ + case TARGET_DROP: + mode = safe_strdup("DROP"); + break; + case TARGET_REJECT: + mode = safe_strdup("REJECT"); + break; + case TARGET_ACCEPT: + mode = safe_strdup("ACCEPT"); + break; + case TARGET_LOG: + mode = safe_strdup("LOG"); + break; + case TARGET_ULOG: + mode = safe_strdup("ULOG"); + break; + } + + snprintf(command, sizeof(command), "-t %s -A %s ",table, chain); + if (rule->mask != NULL) { + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "-d %s ", rule->mask); + } + if (rule->protocol != NULL) { + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "-p %s ", rule->protocol); + } + if (rule->port != NULL) { + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "--dport %s ", rule->port); + } + snprintf((command + strlen(command)), (sizeof(command) - + strlen(command)), "-j %s", mode); + + free(mode); + + /* XXX The buffer command, an automatic variable, will get cleaned + * off of the stack when we return, so we strdup() it. */ + return(safe_strdup(command)); +} + +/** + * @internal + * Load all the rules in a rule set. + * @arg ruleset Name of the ruleset + * @arg table Table containing the chain. + * @arg chain IPTables chain the rules go into + */ + static void +iptables_load_ruleset(const char * table, const char *ruleset, const char *chain) +{ + t_firewall_rule *rule; + char *cmd; + + debug(LOG_DEBUG, "Load ruleset %s into table %s, chain %s", ruleset, table, chain); + + for (rule = get_ruleset(ruleset); rule != NULL; rule = rule->next) { + cmd = iptables_compile(table, chain, rule); + debug(LOG_DEBUG, "Loading rule \"%s\" into table %s, chain %s", cmd, table, chain); + iptables_do_command(cmd); + free(cmd); + } + + debug(LOG_DEBUG, "Ruleset %s loaded into table %s, chain %s", ruleset, table, chain); +} + + void +iptables_fw_clear_authservers(void) +{ + iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); +} + + void +iptables_fw_set_authservers(void) +{ + const s_config *config; + t_auth_serv *auth_server; + + config = config_get_config(); + + for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { + if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) { + iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); + } + } +} + +/** Initialize the firewall rules +*/ + int +iptables_fw_init(void) +{ + const s_config *config; + char * ext_interface = NULL; + int gw_port = 0; + t_trusted_mac *p; + t_white_list *p0; + t_black_list *p1; + t_untrusted_mac *p3; + int proxy_port; + fw_quiet = 0; + + LOCK_CONFIG(); + config = config_get_config(); + gw_port = config->gw_port; + if (config->external_interface) { + ext_interface = safe_strdup(config->external_interface); + } else { + ext_interface = get_ext_iface(); + } + + if (ext_interface == NULL) { + UNLOCK_CONFIG(); + debug(LOG_ERR, "FATAL: no external interface"); + return 0; + } + /* + * + * Everything in the MANGLE table + * + */ + + /* Create new chains */ + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED); + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING); + /* gaomingpan:Untrusted mac chains*/ + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_UNTRUSTED); + /* limeng */ + iptables_do_command("-t mangle -N " TABLE_WIFIDOG_BLACKLIST); + + /* Assign links and rules to these new chains */ + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, config->gw_interface);//this rule will be inserted before the prior one + iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, config->gw_interface); + + for (p = config->trustedmaclist; p != NULL; p = p->next) + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN); + + /*gaomingpan untrusted mac list*/ + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_UNTRUSTED, config->gw_interface); + for (p3 = config->untrustedmaclist; p3 != NULL; p3 = p3->next){ + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s --j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); + debug(LOG_INFO,"Untrusted mac: %s ",p3->mac); + } + /* limeng */ + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_BLACKLIST, config->gw_interface); + for (p1 = config->black_list; p1 != NULL; p1 = p1->next) + { + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); + } + + /* + * + * Everything in the NAT table + * + */ + + /* Create new chains */ + iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS); + /* limeng */ + iptables_do_command("-t nat -N " TABLE_WIFIDOG_WHITELIST); + + /* Assign links and rules to these new chains */ + iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, config->gw_address); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT"); + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET); + + if((proxy_port=config_get_config()->proxy_port) != 0){ + debug(LOG_DEBUG,"Proxy port set, setting proxy rule"); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_KNOWN, proxy_port); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_PROBATION, proxy_port); + } + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); + + iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port); + /* limeng */ + iptables_do_command("-t nat -I" TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + + /* + * + * Everything in the FILTER table + * + */ + + /* Create new chains */ + iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN); + iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN); + /* limeng */ + iptables_do_command("-t filter -N " TABLE_WIFIDOG_WHITELIST); + + /* Assign links and rules to these new chains */ + + /* Insert at the beginning */ + iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, config->gw_interface); + + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP"); + + /* XXX: Why this? it means that connections setup after authentication + stay open even after the connection is done... + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/ + + //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23 + //iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface); + + /* TCPMSS rule for PPPoE */ + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS); + iptables_fw_set_authservers(); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED); + iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL); + iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL); + iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION); + iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN); + iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN); + + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); + iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable"); + + /* limeng */ + iptables_do_command("-t filter -I" TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + + UNLOCK_CONFIG(); + return 1; +} + +void iptables_white_black_list_update(void) +{ + //static time_t timer_old; + //static time_t timer_new; + time_t sec; + struct tm * curTime; + sec = time(NULL); + curTime = localtime(&sec); + static int sec_old = 0; + + t_white_list *p0 = NULL; + t_black_list *p1 = NULL; + const s_config *config; + + if(curTime->tm_sec != sec_old) + { + sec_old = curTime->tm_sec; + + if(curTime->tm_sec == 0 && curTime->tm_min == 0 && curTime->tm_hour == 4) + { + LOCK_CONFIG(); + config = config_get_config(); + + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_BLACKLIST); + for (p1 = config->black_list; p1 != NULL; p1 = p1->next) + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); + + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t nat -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + + iptables_do_command("-t filter -F " TABLE_WIFIDOG_WHITELIST); + for (p0 = config->white_list; p0 != NULL; p0 = p0->next) + iptables_do_command("-t filter -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); + } + + UNLOCK_CONFIG(); + } +} + + +/** Remove the firewall rules + * This is used when we do a clean shutdown of WiFiDog and when it starts to make + * sure there are no rules left over + */ + int +iptables_fw_destroy(void) +{ + fw_quiet = 1; + + debug(LOG_DEBUG, "Destroying our iptables entries"); + + /* + * + * Everything in the MANGLE table + * + */ + debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED); + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_UNTRUSTED);/*gaomingpan: untrusted macs*/ + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); + iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING); + iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_BLACKLIST); + + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED); + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_UNTRUSTED); /*gaomingpan: untrusted macs*/ + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); + iptables_do_command("-t mangle -F " TABLE_WIFIDOG_BLACKLIST); + + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED); + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_UNTRUSTED); /*gaomingpan: untrusted macs*/ + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); + iptables_do_command("-t mangle -X " TABLE_WIFIDOG_BLACKLIST); + + /* + * + * Everything in the NAT table + * + */ + debug(LOG_DEBUG, "Destroying chains in the NAT table"); + iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t nat -F " TABLE_WIFIDOG_WHITELIST); + + iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t nat -X " TABLE_WIFIDOG_WHITELIST); + + /* + * + * Everything in the FILTER table + * + */ + debug(LOG_DEBUG, "Destroying chains in the FILTER table"); + iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t filter -F " TABLE_WIFIDOG_WHITELIST); + + iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); + iptables_do_command("-t filter -X " TABLE_WIFIDOG_WHITELIST); + + return 1; +} + +/* + * Helper for iptables_fw_destroy + * @param table The table to search + * @param chain The chain in that table to search + * @param mention A word to find and delete in rules in the given table+chain + */ +int +iptables_fw_destroy_mention( + const char * table, + const char * chain, + const char * mention + ) { + FILE *p = NULL; + char *command = NULL; + char *command2 = NULL; + char line[MAX_BUF]; + char rulenum[10]; + char *victim = safe_strdup(mention); + int deleted = 0; + + iptables_insert_gateway_id(&victim); + + debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", victim, table, chain); + + safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain); + iptables_insert_gateway_id(&command); + + if ((p = popen(command, "r"))) { + /* Skip first 2 lines */ + while (!feof(p) && fgetc(p) != '\n'); + while (!feof(p) && fgetc(p) != '\n'); + /* Loop over entries */ + while (fgets(line, sizeof(line), p)) { + /* Look for victim */ + if (strstr(line, victim)) { + /* Found victim - Get the rule number into rulenum*/ + if (sscanf(line, "%9[0-9]", rulenum) == 1) { + /* Delete the rule: */ + debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, victim); + safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); + iptables_do_command(command2); + free(command2); + deleted = 1; + /* Do not keep looping - the captured rulenums will no longer be accurate */ + break; + } + } + } + pclose(p); + } + + free(command); + free(victim); + + if (deleted) { + /* Recurse just in case there are more in the same table+chain */ + iptables_fw_destroy_mention(table, chain, mention); + } + + return (deleted); +} + +/** Set if a specific client has access through the firewall */ + int +iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag) +{ + int rc; + + fw_quiet = 0; + + switch(type) { + case FW_ACCESS_ALLOW: + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); + rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); + break; + case FW_ACCESS_DENY: + iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); + rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); + break; + default: + rc = -1; + break; + } + + return rc; +} + +/** Update the counters of all the clients in the client list */ + int +iptables_fw_counters_update(void) +{ + FILE *output; + char *script, + ip[16], + rc; + unsigned long long int counter; + t_client *p1; + struct in_addr tempaddr; + + /* Look for outgoing traffic */ + safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING); + iptables_insert_gateway_id(&script); + output = popen(script, "r"); + free(script); + if (!output) { + debug(LOG_ERR, "popen(): %s", strerror(errno)); + return -1; + } + + /* skip the first two lines */ + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (output && !(feof(output))) { + rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); + //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); + if (2 == rc && EOF != rc) { + /* Sanity*/ + if (!inet_aton(ip, &tempaddr)) { + debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); + continue; + } + debug(LOG_DEBUG, "Read outgoing traffic for %s: Bytes=%llu", ip, counter); + LOCK_CLIENT_LIST(); + if ((p1 = client_list_find_by_ip(ip))) { + if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { + p1->counters.outgoing = p1->counters.outgoing_history + counter; + p1->counters.last_updated = time(NULL); + debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes. Updated last_updated to %d", ip, counter, p1->counters.last_updated); + } + } else { + debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); + } + UNLOCK_CLIENT_LIST(); + } + } + pclose(output); + + /* Look for incoming traffic */ + safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING); + iptables_insert_gateway_id(&script); + output = popen(script, "r"); + free(script); + if (!output) { + debug(LOG_ERR, "popen(): %s", strerror(errno)); + return -1; + } + + /* skip the first two lines */ + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (('\n' != fgetc(output)) && !feof(output)) + ; + while (output && !(feof(output))) { + rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); + if (2 == rc && EOF != rc) { + /* Sanity*/ + if (!inet_aton(ip, &tempaddr)) { + debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); + continue; + } + debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter); + LOCK_CLIENT_LIST(); + if ((p1 = client_list_find_by_ip(ip))) { + if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { + p1->counters.incoming = p1->counters.incoming_history + counter; + debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); + } + } else { + debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); + debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); + iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); + } + UNLOCK_CLIENT_LIST(); + } + } + pclose(output); + + return 1; +} diff --git a/src/fw_iptables.h b/src/fw_iptables.h new file mode 100755 index 00000000..2e52ba0a --- /dev/null +++ b/src/fw_iptables.h @@ -0,0 +1,82 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file fw_iptables.h + @brief Firewall iptables functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _FW_IPTABLES_H_ +#define _FW_IPTABLES_H_ + +#include "firewall.h" + +/*@{*/ +/**Iptable table names used by WifiDog */ +#define TABLE_WIFIDOG_OUTGOING "WiFiDog_$ID$_Outgoing" +#define TABLE_WIFIDOG_WIFI_TO_INTERNET "WiFiDog_$ID$_WIFI2Internet" +#define TABLE_WIFIDOG_WIFI_TO_ROUTER "WiFiDog_$ID$_WIFI2Router" +#define TABLE_WIFIDOG_INCOMING "WiFiDog_$ID$_Incoming" +#define TABLE_WIFIDOG_AUTHSERVERS "WiFiDog_$ID$_AuthServers" +#define TABLE_WIFIDOG_GLOBAL "WiFiDog_$ID$_Global" +#define TABLE_WIFIDOG_VALIDATE "WiFiDog_$ID$_Validate" +#define TABLE_WIFIDOG_KNOWN "WiFiDog_$ID$_Known" +#define TABLE_WIFIDOG_UNKNOWN "WiFiDog_$ID$_Unknown" +#define TABLE_WIFIDOG_LOCKED "WiFiDog_$ID$_Locked" +#define TABLE_WIFIDOG_TRUSTED "WiFiDog_$ID$_Trusted" +/*gaomingpan*/ +#define TABLE_WIFIDOG_UNTRUSTED "WiFiDog_$ID$_Untrusted" +/* limeng */ +#define TABLE_WIFIDOG_WHITELIST "WiFiDog_$ID$_WhiteList" +#define TABLE_WIFIDOG_BLACKLIST "WiFiDog_$ID$_BlackList" + +/*@}*/ + +/** Used by iptables_fw_access to select if the client should be granted of denied access */ +typedef enum fw_access_t_ { + FW_ACCESS_ALLOW, + FW_ACCESS_DENY +} fw_access_t; + +/** @brief Initialize the firewall */ +int iptables_fw_init(void); +void iptables_white_black_list_update(void); + + +/** @brief Initializes the authservers table */ +void iptables_fw_set_authservers(void); + +/** @brief Clears the authservers table */ +void iptables_fw_clear_authservers(void); + +/** @brief Destroy the firewall */ +int iptables_fw_destroy(void); + +/** @brief Helper function for iptables_fw_destroy */ +int iptables_fw_destroy_mention( const char * table, const char * chain, const char * mention); + +/** @brief Define the access of a specific client */ +int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag); + +/** @brief All counters in the client list */ +int iptables_fw_counters_update(void); + +#endif /* _IPTABLES_H_ */ diff --git a/src/gateway.c b/src/gateway.c new file mode 100755 index 00000000..913a9e2b --- /dev/null +++ b/src/gateway.c @@ -0,0 +1,582 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free:Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @internal + @file gateway.c + @brief Main loop + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2004 Alexandre Carmel-Veilleux + */ + +#include +#include +#include +#include +#include +#include +#include + +/* for strerror() */ +#include + +/* for wait() */ +#include + +/* for unix socket communication*/ +#include +#include + +#include "common.h" +#include "httpd.h" +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "gateway.h" +#include "firewall.h" +#include "commandline.h" +#include "auth.h" +#include "http.h" +#include "client_list.h" +#include "wdctl_thread.h" +#include "ping_thread.h" +#include "httpd_thread.h" +#include "util.h" + + +#include "get_remote_shell.h" +#include "device_key.h" + +/** XXX Ugly hack + * We need to remember the thread IDs of threads that simulate wait with pthread_cond_timedwait + * so we can explicitly kill them in the termination handler + */ +static pthread_t tid_fw_counter = 0; +static pthread_t tid_ping = 0; + +/* The internal web server */ +httpd * webserver = NULL; + +/* from commandline.c */ +extern char ** restartargv; +extern pid_t restart_orig_pid; +t_client *firstclient; + +/* from client_list.c */ +extern pthread_mutex_t client_list_mutex; + +/* Time when wifidog started */ +time_t started_time = 0; + +/* Appends -x, the current PID, and NULL to restartargv + * see parse_commandline in commandline.c for details + * + * Why is restartargv global? Shouldn't it be at most static to commandline.c + * and this function static there? -Alex @ 8oct2006 + */ +void append_x_restartargv(void) { + int i; + + for (i=0; restartargv[i]; i++); + + restartargv[i++] = safe_strdup("-x"); + safe_asprintf(&(restartargv[i++]), "%d", getpid()); +} + +/* @internal + * @brief During gateway restart, connects to the parent process via the internal socket + * Downloads from it the active client list + */ +void get_clients_from_parent(void) { + int sock; + struct sockaddr_un sa_un; + s_config * config = NULL; + char linebuffer[MAX_BUF]; + int len = 0; + char *running1 = NULL; + char *running2 = NULL; + char *token1 = NULL; + char *token2 = NULL; + char onechar; + char *command = NULL; + char *key = NULL; + char *value = NULL; + t_client * client = NULL; + t_client * lastclient = NULL; + + config = config_get_config(); + + debug(LOG_INFO, "Connecting to parent to download clients"); + + /* Connect to socket */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + memset(&sa_un, 0, sizeof(sa_un)); + sa_un.sun_family = AF_UNIX; + strncpy(sa_un.sun_path, config->internal_sock, (sizeof(sa_un.sun_path) - 1)); + + if (connect(sock, (struct sockaddr *)&sa_un, strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { + debug(LOG_ERR, "Failed to connect to parent (%s) - client list not downloaded", strerror(errno)); + return; + } + + debug(LOG_INFO, "Connected to parent. Downloading clients"); + + LOCK_CLIENT_LIST(); + + command = NULL; + memset(linebuffer, 0, sizeof(linebuffer)); + len = 0; + client = NULL; + /* Get line by line */ + while (read(sock, &onechar, 1) == 1) { + if (onechar == '\n') { + /* End of line */ + onechar = '\0'; + } + linebuffer[len++] = onechar; + + if (!onechar) { + /* We have a complete entry in linebuffer - parse it */ + debug(LOG_DEBUG, "Received from parent: [%s]", linebuffer); + running1 = linebuffer; + while ((token1 = strsep(&running1, "|")) != NULL) { + if (!command) { + /* The first token is the command */ + command = token1; + } + else { + /* Token1 has something like "foo=bar" */ + running2 = token1; + key = value = NULL; + while ((token2 = strsep(&running2, "=")) != NULL) { + if (!key) { + key = token2; + } + else if (!value) { + value = token2; + } + } + } + + if (strcmp(command, "CLIENT") == 0) { + /* This line has info about a client in the client list */ + if (!client) { + /* Create a new client struct */ + client = safe_malloc(sizeof(t_client)); + memset(client, 0, sizeof(t_client)); + } + } + + if (key && value) { + if (strcmp(command, "CLIENT") == 0) { + /* Assign the key into the appropriate slot in the connection structure */ + if (strcmp(key, "ip") == 0) { + client->ip = safe_strdup(value); + } + else if (strcmp(key, "mac") == 0) { + client->mac = safe_strdup(value); + } + else if (strcmp(key, "token") == 0) { + client->token = safe_strdup(value); + } + else if (strcmp(key, "fw_connection_state") == 0) { + client->fw_connection_state = atoi(value); + } + else if (strcmp(key, "fd") == 0) { + client->fd = atoi(value); + } + else if (strcmp(key, "counters_incoming") == 0) { + client->counters.incoming_history = atoll(value); + client->counters.incoming = client->counters.incoming_history; + } + else if (strcmp(key, "counters_outgoing") == 0) { + client->counters.outgoing_history = atoll(value); + client->counters.outgoing = client->counters.outgoing_history; + } + else if (strcmp(key, "counters_last_updated") == 0) { + client->counters.last_updated = atol(value); + }/*get record_time from parents*/ + else if (strcmp(key, "record_time") == 0) { + client->record_time = atol(value); + } + else { + debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); + } + } + } + } + + /* End of parsing this command */ + if (client) { + /* Add this client to the client list */ + if (!firstclient) { + firstclient = client; + lastclient = firstclient; + } + else { + lastclient->next = client; + lastclient = client; + } + } + + /* Clean up */ + command = NULL; + memset(linebuffer, 0, sizeof(linebuffer)); + len = 0; + client = NULL; + } + } + + UNLOCK_CLIENT_LIST(); + debug(LOG_INFO, "Client list downloaded successfully from parent"); + + close(sock); +} + +/**@internal + * @brief Handles SIGCHLD signals to avoid zombie processes + * + * When a child process exits, it causes a SIGCHLD to be sent to the + * process. This handler catches it and reaps the child process so it + * can exit. Otherwise we'd get zombie processes. + */ +void +sigchld_handler(int s) +{ + int status; + pid_t rc; + + debug(LOG_DEBUG, "Handler for SIGCHLD called. Trying to reap a child"); + + rc = waitpid(-1, &status, WNOHANG); + + debug(LOG_DEBUG, "Handler for SIGCHLD reaped child PID %d", rc); +} + +/** Exits cleanly after cleaning up the firewall. + * Use this function anytime you need to exit after firewall initialization */ +void +termination_handler(int s) +{ + static pthread_mutex_t sigterm_mutex = PTHREAD_MUTEX_INITIALIZER; + + debug(LOG_INFO, "Handler for termination caught signal %d", s); + + /* Makes sure we only call fw_destroy() once. */ + if (pthread_mutex_trylock(&sigterm_mutex)) { + debug(LOG_INFO, "Another thread already began global termination handler. I'm exiting"); + pthread_exit(NULL); + } + else { + debug(LOG_INFO, "Cleaning up and exiting"); + } + + debug(LOG_INFO, "Flushing firewall rules..."); + fw_destroy(); + + /* XXX Hack + * Aparently pthread_cond_timedwait under openwrt prevents signals (and therefore + * termination handler) from happening so we need to explicitly kill the threads + * that use that + */ + if (tid_fw_counter) { + debug(LOG_INFO, "Explicitly killing the fw_counter thread"); + pthread_kill(tid_fw_counter, SIGKILL); + } + if (tid_ping) { + debug(LOG_INFO, "Explicitly killing the ping thread"); + pthread_kill(tid_ping, SIGKILL); + } + + debug(LOG_NOTICE, "Exiting..."); + exit(s == 0 ? 1 : 0); +} + +/** @internal + * Registers all the signal handlers + */ +static void +init_signals(void) +{ + struct sigaction sa; + + debug(LOG_DEBUG, "Initializing signal handlers"); + + sa.sa_handler = sigchld_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + if (sigaction(SIGCHLD, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + /* Trap SIGPIPE */ + /* This is done so that when libhttpd does a socket operation on + * a disconnected socket (i.e.: Broken Pipes) we catch the signal + * and do nothing. The alternative is to exit. SIGPIPE are harmless + * if not desirable. + */ + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + sa.sa_handler = termination_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + + /* Trap SIGTERM */ + if (sigaction(SIGTERM, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + /* Trap SIGQUIT */ + if (sigaction(SIGQUIT, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } + + /* Trap SIGINT */ + if (sigaction(SIGINT, &sa, NULL) == -1) { + debug(LOG_ERR, "sigaction(): %s", strerror(errno)); + exit(1); + } +} + +/**@internal + * Main execution loop + */ +static void +main_loop(void) +{ + int result; + pthread_t tid; + s_config *config = config_get_config(); + request *r; + void **params; + + /* Set the time when wifidog started */ + if (!started_time) { + debug(LOG_INFO, "Setting started_time"); + started_time = time(NULL); + } + else if (started_time < MINIMUM_STARTED_TIME) { + debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); + started_time = time(NULL); + } + + /* If we don't have the Gateway IP address, get it. Can't fail. */ + if (!config->gw_address) { + debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); + if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { + debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); + exit(1); + } + debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); + } + + /* If we don't have the Gateway ID, construct it from the internal MAC address. + * "Can't fail" so exit() if the impossible happens. */ + if (!config->gw_id) { + debug(LOG_DEBUG, "Finding MAC address of %s", config->gw_interface); + if ((config->gw_id = get_iface_mac(config->gw_interface)) == NULL) { + debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); + exit(1); + } + debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_id); + } + + /* Initializes the web server */ + debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); + if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { + debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); + exit(1); + } + + /**** init my post url config *****/ + if(0 != init_post_http_url_config() ) + { + debug(LOG_ERR, "ERROR: Failed to initialize init_post_http_url_config"); + //exit(1); + } + /*init device key*/ + if(0 != init_device_key()) + { + debug(LOG_ERR,"ERROR:Failed to initalize device key."); + } + /*********************************/ + + debug(LOG_DEBUG, "Assigning callbacks to web server"); + httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog); + httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog); + httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about); + httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status); + httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth); + + httpdAddC404Content(webserver, http_callback_404); + + /* Reset the firewall (if WiFiDog crashed) */ + fw_destroy(); + /* Then initialize it */ + if (!fw_init()) { + debug(LOG_ERR, "FATAL: Failed to initialize firewall"); + exit(1); + } + + /* Start clean up thread */ + result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting"); + termination_handler(0); + } + pthread_detach(tid_fw_counter); + + /* Start control thread */ + result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); + termination_handler(0); + } + pthread_detach(tid); + + /* Start heartbeat thread */ + result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting"); + termination_handler(0); + } + pthread_detach(tid_ping); + + debug(LOG_NOTICE, "Waiting for connections"); + while(1) { + r = httpdGetConnection(webserver, NULL); + + /* We can't convert this to a switch because there might be + * values that are not -1, 0 or 1. */ + if (webserver->lastError == -1) { + /* Interrupted system call */ + continue; /* restart loop */ + } + else if (webserver->lastError < -1) { + /* + * FIXME + * An error occurred - should we abort? + * reboot the device ? + */ + debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); + termination_handler(0); + } + else if (r != NULL) { + /* + * We got a connection + * + * We should create another thread + */ + debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); + /* The void**'s are a simulation of the normal C + * function calling sequence. */ + params = safe_malloc(2 * sizeof(void *)); + *params = webserver; + *(params + 1) = r; + + result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); + termination_handler(0); + } + pthread_detach(tid); + } + else { + /* webserver->lastError should be 2 */ + /* XXX We failed an ACL.... No handling because + * we don't set any... */ + } + + /* limeng */ + iptables_white_black_list_update(); + } + + /* never reached */ +} + +/** Reads the configuration file and then starts the main loop */ +int main(int argc, char **argv) { + + s_config *config = config_get_config(); + config_init(); + + parse_commandline(argc, argv); + + /* Initialize the config */ + config_read(config->configfile); + config_validate(); + + /* Initializes the linked list of connected clients */ + client_list_init(); + + /* Init the signals to catch chld/quit/etc */ + init_signals(); + + + if (restart_orig_pid) { + /* + * We were restarted and our parent is waiting for us to talk to it over the socket + */ + get_clients_from_parent(); + + /* + * At this point the parent will start destroying itself and the firewall. Let it finish it's job before we continue + */ + while (kill(restart_orig_pid, 0) != -1) { + debug(LOG_INFO, "Waiting for parent PID %d to die before continuing loading", restart_orig_pid); + sleep(1); + } + + debug(LOG_INFO, "Parent PID %d seems to be dead. Continuing loading."); + } + + if (config->daemon) { + + debug(LOG_INFO, "Forking into background"); + + switch(safe_fork()) { + case 0: /* child */ + setsid(); + append_x_restartargv(); + main_loop(); + break; + + default: /* parent */ + exit(0); + break; + } + } + else { + append_x_restartargv(); + main_loop(); + } + + return(0); /* never reached */ +} + + + diff --git a/src/gateway.h b/src/gateway.h new file mode 100755 index 00000000..264de2c7 --- /dev/null +++ b/src/gateway.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file gateway.h + @brief Main loop + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _GATEWAY_H_ +#define _GATEWAY_H_ + +/** @brief exits cleanly and clear the firewall rules. */ +void termination_handler(int s); + +#endif /* _GATEWAY_H_ */ diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c new file mode 100644 index 00000000..8c1dcef0 --- /dev/null +++ b/src/get_clientinfo.c @@ -0,0 +1,443 @@ +/* + * get_clientinfo.c + * + * Created on: Jul 13, 2015 + * Author: GaomingPan + */ + + +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "debug.h" +#include "conf.h" +#include "client_list.h" +#include "../config.h" + + +#include "shell_command.h" +#include "get_clientinfo.h" + + +static t_clientinfo *first_client_info = NULL; + +static char client_auth_flag[7]; + +/* @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:void + * @RETURN_VALUE:zero is success,others is error. + * @Note: after this function be called and you got some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int collect_client_info() +{ + FILE *fp, + *fp_shell, + *fp_upspeed, + *fp_downspeed; + + char info_buf[1024], + chain_test[64], + ip[18]; + + int speed; + + char *ptr, + *token; + + t_clientinfo *p1, + *p2, + *p3; + int i = 0; + + memset(info_buf,0,1024); + first_client_info = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == first_client_info) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + printf("ERROR: at collect_client_info(), malloc error.\n"); + return -1; + } + first_client_info->next = NULL; + + p1 = first_client_info; + p2 = p1; + + fp = popen(CMD_GET_CLIENT_LIST,"r"); + + if(NULL == fp) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),popen error."); + printf("ERROR: at collect_client_info(),popen error.\n"); + return -2; + } + + while(NULL != fgets(info_buf,1024,fp)) + { + + if(NULL == p1) + { + p1 = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == p1) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + + printf("ERROR: at collect_client_info(), malloc error.\n"); + pclose(fp); + return -3; + } + p2->next = p1; + p2 = p1; + p1->next = NULL; + + }//if + + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(40); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error.\n"); + printf("ERROR: at collect_client_info(), malloc error.\n"); + pclose(fp); + return -4; + } + strcpy(token,ptr); + if(1 == i) + { + strcpy(p1->client_mac,token); + free(token); + continue; + } + if(2 == i) + { + strcpy(p1->client_ip,token); + free(token); + continue; + } + if(3 == i) + { + strcpy(p1->host_name,token); + free(token); + break; + } + }//for + p1 = p1->next; + i = 0; + memset(info_buf,0,1024); + }//while + + pclose(fp); + + + /* get speed files + * */ + memset(chain_test,0,64); + fp_shell = popen(CMD_MAKE_SPEED_FILE,"r"); + if(NULL == fp_shell) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); + printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); + return -5; + } + fread(chain_test,64,1,fp_shell); + pclose(fp_shell); + + + /* do some clean up,if it needs. + * */ + int ret; + ret = clean_more_chain(); + if(0 != ret) + { + debug(LOG_ERR,"ERROR: clean_more_chain() return value:%d\n",ret); + printf("ERROR: clean_more_chain() return value:%d\n",ret); + } + + + /* get up speed + * */ + fp_upspeed = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp_upspeed) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_upseed error."); + printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); + return -6; + } + memset(info_buf,0,1024); + memset(ip,0,18); + i = 0; + while(NULL != fgets(info_buf,1024,fp_upspeed)) + { + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(20); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + printf("ERROR: at collect_client_info(), malloc error.\n"); + fclose(fp_upspeed); + return -7; + } + strcpy(token,ptr); + if(i == 1) + { + strcpy(ip,token); + free(token); + continue; + } + if(i == 2) + { + speed = atoi(token); + free(token); + p3 = get_client_info_by_ip(ip); + if(NULL != p3) + { + p3->go_speed = speed; + } + memset(ip,0,18); + i = 0; + break; + } + }//for + }//while + fclose(fp_upspeed); + + + /* get the down speed + * */ + fp_downspeed = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp_downspeed) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_downspeed error."); + printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); + return -8; + } + memset(info_buf,0,1024); + memset(ip,0,18); + i = 0; + while(NULL != fgets(info_buf,1024,fp_downspeed)) + { + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(40); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); + printf("ERROR: at collect_client_info(), malloc error.\n"); + fclose(fp_downspeed); + return -9; + } + strcpy(token,ptr); + if(i == 1) + { + strcpy(ip,token); + free(token); + continue; + } + if(i == 2) + { + speed = atoi(token); + free(token); + p3 = get_client_info_by_ip(ip); + if(NULL != p3) + { + p3->come_speed = speed; + } + memset(ip,0,18); + i = 0; + break; + } + } + }//while + fclose(fp_downspeed); + + return 0; +} + + +/* @breif After the function collect_client_info() called,should call this function to + * clean up. + * @PARAMETER:void + * @RETURN_VALUE:void + * @Note: function collect_client_info() and this function just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +void clean_client_info() +{ + t_clientinfo *p1, + *p2; + + p1 = first_client_info; + p2 = p1->next; + + while(NULL != p1) + { + free(p1); + p1 = p2; + if(NULL != p2) + p2 = p2->next; + } +} + + + +/* @breif find the element from the client_info list by mac. + * @PARAMETER:[const char *mac],the pointer point to by mac. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_mac(const char *mac) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p) + { + if(strcmp(mac,p->client_mac) == 0) + { + return p; + } + p = p->next; + } + return NULL; +} + + + +/* @breif find the element from the client_info list by ip. + * @PARAMETER:[const char *ip],the pointer point to by ip. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_ip(const char *ip) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p) + { + if(strcmp(ip,p->client_ip) == 0) + { + return p; + } + p = p->next; + } + return NULL; +} + + + +long get_online_time(const char *ip,const char *mac) +{ + t_client *ptr; + long online_time = 0; + + ptr = client_list_find(ip,mac); + + if(NULL!= ptr) + { + online_time = time(NULL) - ptr->record_time; + } + + return online_time; +} + + + +int clean_more_chain() +{ + FILE *fp; + + char chain_test[10]; + + int chain_num = 0, + m = 0, + failed_count = 0; + + + memset(chain_test,0,10); + fp = popen(CMD_GET_CHAIN_NUM,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); + printf("ERROR: at collect_client_info(),popen for fp error.\n"); + return -1; + } + pclose(fp); + + fp = fopen("/tmp/client.speed.chain.num","r"); + if(NULL == fp) + { + debug(LOG_ERR,"ERROR: fopen() /tmp/client.speed.chain.num\n"); + printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); + return -2; + } + while(NULL != fgets(chain_test,10,fp)) + { + m = atoi(chain_test); + + if(m > chain_num) + chain_num = m; + } + fclose(fp); + + while( --chain_num > 0) + { + + fp = popen(CMD_CLEAN_SPEED_CHAIN,"r"); + if(NULL != fp) + { + pclose(fp); + debug(LOG_INFO,"INFO: clean iptables chain"); + printf("INFO: clean iptables chain\n"); + } + else + { + failed_count++; + debug(LOG_ERR,"ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)"); + printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); + } + } + + return failed_count; +} + + + +char *get_client_auth_flag() +{ + return client_auth_flag; +} + + + + +void set_client_auth_flag() +{ + // rand()%(max - min + 1) + min + int i; + for(i = 0;i<6;i++) + client_auth_flag[i] = rand()%(90 - 65 + 1) + 65; + + client_auth_flag[6] = 0; +} + + diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h new file mode 100644 index 00000000..12d592c8 --- /dev/null +++ b/src/get_clientinfo.h @@ -0,0 +1,89 @@ +/* + * get_clientinfo.h + * + * Created on: Jul 13, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_GET_CLIENTINFO_H_ +#define SRC_GET_CLIENTINFO_H_ + + +#define CLIENT_HOST_NAME_LEN 40 +#define CLIENT_MAC_ADDRESS_LEN 18 +#define CLIENT_IP_ADDRESS_LEN 16 + +#define UP_SPEED_FILE "/tmp/client.up.speed" +#define DOWN_SPEED_FILE "/tmp/client.down.speed" + + +/*@breif the sturct for client_info list + * */ +typedef struct _t_clientinfo{ + + char client_mac[CLIENT_MAC_ADDRESS_LEN]; + char client_ip[CLIENT_IP_ADDRESS_LEN]; + char host_name[CLIENT_HOST_NAME_LEN]; + int go_speed; + int come_speed; + struct _t_clientinfo *next; + +} t_clientinfo; + + +/* @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:void + * @RETURN_VALUE:zero is success,others is error. + * @Note: after this function be called and you get some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int collect_client_info(); + + +/* @breif After the function collect_client_info() called,should call this function to + * clean up. + * @PARAMETER:void + * @RETURN_VALUE:void + * @Note: function collect_client_info() and this function just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +void clean_client_info(); + + +/* @breif find the element from the client_info list by mac. + * @PARAMETER:[const char *mac],the pointer point to by mac. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_mac(const char *mac); + + +/* @breif find the element from the client_info list by ip. + * @PARAMETER:[const char *ip],the pointer point to by ip. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_ip(const char *ip); + + +long get_online_time(const char *ip,const char *mac); + + +int clean_more_chain(); + + +char *get_client_auth_flag(); + +void set_client_auth_flag(); + + +#endif /* SRC_GET_CLIENTINFO_H_ */ + + + + diff --git a/src/get_devinfo.c b/src/get_devinfo.c new file mode 100644 index 00000000..d6358f75 --- /dev/null +++ b/src/get_devinfo.c @@ -0,0 +1,459 @@ +/* + * get_devinfo.c + * + * Created on: Jul 9, 2015 + * Author: GaomingPan + */ +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include + + +#include "util.h" +#include "debug.h" +#include "conf.h" +#include "client_list.h" +#include "../config.h" + + +#include "shell_command.h" +#include "get_devinfo.h" + +extern pthread_mutex_t client_list_mutex; + +static t_devinfo devinfo; +static t_cpuuse cpuuse; + +t_devinfo *get_devinfo(void) +{ + + if(get_apmac(devinfo.gw_mac)) + { + debug(LOG_ERR,"MyDEBUG:get get_apmac error!"); + } + + if(get_devssid(devinfo.gw_ssid)) + { + debug(LOG_ERR,"MyDEBUG:get ssid error!"); + } + if(get_dogversion(devinfo.dog_version)) + { + debug(LOG_ERR,"MyDEBUG: get_dogversion error!"); + } + if(get_wanip(devinfo.wan_ip)) + { + debug(LOG_ERR,"MyDEBUG: get_wanip error!\n"); + } + + devinfo.cur_conn = get_curconn(); + devinfo.dev_conn = get_devconn(); + + devinfo.cpu_use = get_cpuuse(CPU_LOAD); + + if(get_wanbps(&devinfo.go_speed,&devinfo.come_speed)) + { + debug(LOG_ERR,"MyDEBUG: get_speed error!"); + } + if(get_trafficCount(&devinfo.outgoing,&devinfo.incoming)) + { + debug(LOG_ERR,"MyDEBUG: get_traffic error!\n"); + } + + return &devinfo; +} + +/* @breif get wireless ssid,based on uci command. + * @PARAMETER: [char *ssid]:the char pointer for save the ssid. + * @RETURN_VALUE: zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_devssid(char *ssid) +{ + FILE *fp; + memset(ssid,0,DEV_SSID_NAME_LEN); + fp = popen(CMD_GET_WIRELESS_SSID,"r"); + if(NULL == fp) + { + debug(LOG_ERR," get_devssid error!"); + sprintf(ssid,"%s","null"); + return -1; + } + fread(ssid,DEV_SSID_NAME_LEN,1,fp); + pclose(fp); + + int i = DEV_SSID_NAME_LEN - 1; + for(;i > 0;i--) + { + if(0x0a == ssid[i]) + { + ssid[i] = 0; + break; + } + } + return 0; +} + + +/* @breif get wifidog version + * @PARAMETER:[char *dogversion]:the char pointer for save the version + * @RETURN_VALUE:always return zero + * GaomingPan lonely-test:no + * */ +int get_dogversion(char *dogversion) +{ + memset(dogversion,0,DEV_DOG_VERSION_LEN); + sprintf(dogversion,"%s",VERSION); + return 0; +} + +/* @breif get wan interface ip,based on uci command. + * @PARAMETER:[char *wanip]:the char pointer for save the wan ip + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_wanip(char *wanip) +{ + FILE *fp; + memset(wanip,0,DEV_WAN_IP_LEN); + fp = popen(CMD_GET_WAN_IP,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_wanip error!"); + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(wanip,DEV_WAN_IP_LEN - 1,1,fp); + pclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i > 0;i--) + { + if(0x0a == wanip[i]) + { + wanip[i] = 0; + break; + } + } + + return 0; +} + + + +/* @breif get ap mac address,based on uci command. + * @PARAMETER:[char *apmac]:the char pointer for save the mac + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_apmac(char *apmac) +{ + FILE *fp; + int i; + memset(apmac,0,DEV_MAC_ADDR_LEN); + fp = popen(CMD_GET_AP_MAC,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_apmac() popen error."); + sprintf(apmac,"%s","00-00-00-00-00-00"); + return -1; + } + fread(apmac,DEV_MAC_ADDR_LEN - 1,1,fp); + pclose(fp); + + for(i = 0; i< DEV_MAC_ADDR_LEN; i++) + { + if(':' == apmac[i]) + apmac[i] = '-'; + if(0x0a == apmac[i]) + apmac[i] = 0; + } + + return 0; +} + + +/* @breif get number of client + * @PARAMETER:none + * @RETURN_VALUE:the number of current connected client + * GaomingPan lonely-test:no + * */ +int get_curconn(void) +{ + int count; + t_client *first; + + LOCK_CLIENT_LIST(); + + first = client_get_first_client(); + if (first == NULL) { + count = 0; + } else { + count = 1; + while (first->next != NULL) { + first = first->next; + count++; + } + } + + UNLOCK_CLIENT_LIST(); + + return count; +} + + +/* @breif get number of client who connect to the device + * @PARAMETER:none + * @RETURN_VALUE:the number of connected client + * GaomingPan lonely-test:no + * */ +int get_devconn(void) +{ + FILE *fp; + char buf[10]; + memset(buf,0,10); + fp = popen("awk \'END{print NR}\' $(uci get dhcp.@dnsmasq[0].leasefile)","r"); + if(NULL == fp) + { + debug(LOG_ERR,"ERROR popen error, at get_devconn."); + return -1; + } + if(0 == fread(buf,1,10,fp)) + { + pclose(fp); + return 0; + } + pclose(fp); + return (atoi(buf)); +} + + +/* @breif get cpu use infomation,based on shell command. + * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @RETURN_VALUE:the number of current percent of CPU use. + * GaomingPan lonely-test:yes + * */ +int get_cpuuse(int type) +{ + char num[4]; + int use, + i; + FILE *fp; + + memset(num,0,4); + for(i = 0;i < 15;i++) + memset(cpuuse.use_info[i],0,8); + + fp = popen(CMD_GET_CPU_USE,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_cpuuse error!"); + return -1; + } + fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], + cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], + cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], + cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], + cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] + ); + pclose(fp); + +// for(;i<15;i++) +// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); + + switch(type){ + case CPU_USER: + cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; + use = atoi(cpuuse.use_info[CPU_USER]); + break; + case CPU_SYS: + cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SYS]); + break; + case CPU_NIC: + cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; + use = atoi(cpuuse.use_info[CPU_NIC]); + break; + case CPU_IDLE: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_LOAD: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_IO: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IO]); + break; + case CPU_IRQ: + cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IRQ]); + break; + case CPU_SIRQ: + cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SIRQ]); + break; + default: + use = -1; + break; + } + + return use; +} + + +/* @breif get wan interface traffic,based on shell command. + * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_trafficCount(long *outgo,long *income) +{ + FILE *fp; + char ifname[DEV_IFNAME_LEN]; + memset(ifname,0,DEV_IFNAME_LEN); + + fp = popen(CMD_GET_WAN_IFNAME,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"get_trafficCount() popen error."); + *outgo = -1L; + *income = -1L; + return -1; + } + fread(ifname,DEV_IFNAME_LEN-1,1,fp); + pclose(fp); + + int j; + for(j = 0;j < DEV_IFNAME_LEN;j++) + { + if(0x0a == ifname[j]) + { + ifname[j] = 0; + break; + } + } + + int nDevLen = strlen(ifname); + if (nDevLen < 1 || nDevLen > DEV_IFNAME_LEN - 1) + { + debug(LOG_ERR,"get_trafficCount(),dev length too long."); + *outgo = -1L; + *income = -1L; + return -2; + } + int fd = open("/proc/net/dev", O_RDONLY | O_EXCL); + if (-1 == fd) + { + debug(LOG_ERR,"get_trafficCount(),open /proc/net/dev failed ,maybe file not exists!"); + *outgo = -1L; + *income = -1L; + return -3; + } + + char buf[1024*2]; + lseek(fd, 0L, SEEK_SET); + int nBytes = read(fd, buf, sizeof(buf)-1); + close(fd); + if (-1 == nBytes) + { + debug(LOG_ERR,"get_trafficCount(),read bytes error."); + *outgo = -1L; + *income = -1L; + return -4; + } + buf[nBytes] = '\0'; + + //è¿”å›ç¬¬ä¸€æ¬¡æŒ‡å‘ifnameä½ç½®ç„指针 + char* pDev = strstr(buf, ifname); + if (NULL == pDev) + { + debug(LOG_ERR,"get_trafficCount(),don't find dev %s", ifname); + *outgo = -1L; + *income = -1L; + return -5; + } + char *p; + char *ifconfig_value; + int i = 0; + long rx2_tx10[2]; + /*å»é™¤ç©ºæ ¼ï¼Œåˆ¶è¡¨ç¬¦ï¼Œæ¢è¡Œç¬¦ç­‰ä¸éœ€è¦ç„字段*/ + for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) + { + i++; + ifconfig_value = (char*)malloc(30); + if(NULL == ifconfig_value) + { + debug(LOG_ERR,"get_trafficCount(),malloc error."); + *outgo = -1L; + *income = -1L; + return -6; + } + strcpy(ifconfig_value, p); + /*得到ç„字符串中ç„ç¬¬äºŒä¸ªå­—æ®µæ˜¯æ¥æ”¶æµé‡*/ + if(i == 2) + { + rx2_tx10[0] = atoll(ifconfig_value); + } + /*得到ç„字符串中ç„第å个字段是å‘逿µé‡*/ + if(i == 10) + { + rx2_tx10[1] = atoll(ifconfig_value); + break; + } + free(ifconfig_value); + } + free(ifconfig_value); + + *income = rx2_tx10[0]; + *outgo = rx2_tx10[1]; + + return 0; +} + + +/* @breif get wan interface speed,based on shell command. + * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. + * @RETURN_VALUE:zero is success,others is error. + * @NOTE: this function will take a one second to wait data update,so,it's just waste time. + * GaomingPan lonely-test:yes + * */ +int get_wanbps(int *go,int *come) +{ + unsigned long long outgo = 0, + income = 0; + unsigned long long outgo1 = 0, + income1 = 0; + int ret = 0; + + ret = get_trafficCount(&outgo,&income); + + if(ret) + { + debug(LOG_ERR,"1 at get_wanbps(), get_trafficCount() error return code = %d",ret); + return -1; + } + + sleep(1); + + ret = get_trafficCount(&outgo1,&income1); + if(ret) + { + debug(LOG_ERR,"2 at get_wanbps(), get_trafficCount() error return code = %d",ret); + return -2; + } + + *go = (int)(outgo1 - outgo); + *come = (int)(income1 - income); + + return 0; +} diff --git a/src/get_devinfo.h b/src/get_devinfo.h new file mode 100644 index 00000000..1af715e3 --- /dev/null +++ b/src/get_devinfo.h @@ -0,0 +1,119 @@ +/* + * get_devinfo.h + * + * Created on: Jul 9, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_GET_DEVINFO_H_ +#define SRC_GET_DEVINFO_H_ + +#define DEV_MAC_ADDR_LEN 18 +#define DEV_SSID_NAME_LEN 20 +#define DEV_DOG_VERSION_LEN 20 +#define DEV_WAN_IP_LEN 16 +#define DEV_IFNAME_LEN 11 + + +#define CPU_USER 1 +#define CPU_SYS 3 +#define CPU_NIC 5 +#define CPU_IDLE 7 +#define CPU_IO 9 +#define CPU_IRQ 11 +#define CPU_SIRQ 13 +#define CPU_LOAD 16 + +/*@ breif a struct hold information for ap*/ +typedef struct _t_devinfo{ + char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address + char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid + char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. + char wan_ip[DEV_WAN_IP_LEN]; // ap wan interface ip + int cur_conn; // number of current connection client + int dev_conn; // number of connection in the device,maybe some has no authentication. + int cpu_use; // percent of use CPU + int go_speed; // wan interface go out speed + int come_speed; // wan interface come in speed + long incoming; // + long outgoing; // +}t_devinfo; + + + +typedef struct _t_cpuuse{ + char use_info[15][8]; +}t_cpuuse; + + +t_devinfo *get_devinfo(void); + +/* @breif get wireless ssid,based on uci command. + * @PARAMETER: [char *ssid]:the char pointer for save the ssid. + * @RETURN_VALUE: zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_devssid(char *ssid); + +/* @breif get wifidog version + * @PARAMETER:[char *dogversion]:the char pointer for save the version + * @RETURN_VALUE:always return zero + * GaomingPan lonely-test:no + * */ +int get_dogversion(char *dogversion); + + +/* @breif get wan interface ip,based on uci command. + * @PARAMETER:[char *wanip]:the char pointer for save the wan ip + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_wanip(char *wanip); + +/* @breif get ap mac address,based on uci command. + * @PARAMETER:[char *apmac]:the char pointer for save the mac + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_apmac(char *apmac); + +/* @breif get number of client + * @PARAMETER:none + * @RETURN_VALUE:the number of current connected client + * GaomingPan lonely-test:no + * */ +int get_curconn(void); + + +/* @breif get number of client who connect to the device + * @PARAMETER:none + * @RETURN_VALUE:the number of connected client + * GaomingPan lonely-test:no + * */ +int get_devconn(void); + +/* @breif get cpu use infomation,based on shell command + * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @RETURN_VALUE:the number of current percent of CPU use. + * GaomingPan lonely-test:yes + * */ +int get_cpuuse(int type); + + +/* @breif get wan interface speed,based on shell command. + * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_wanbps(int *go,int *come); + + +/* @breif get wan interface traffic,based on shell command. + * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_trafficCount(long *outgo,long *income); + + +#endif /* SRC_GET_DEVINFO_H_ */ diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c new file mode 100644 index 00000000..5d67787a --- /dev/null +++ b/src/get_remote_shell.c @@ -0,0 +1,213 @@ +/* + * get_remote_shell.c + * + * Created on: Jul 14, 2015 + * Author: GaomingPan + */ + + +#include +#include +#include +#include + +#include "debug.h" + +#include "get_remote_shell.h" + + + +static char remote_shell_cmd[ REMOTE_SHELL_COMMAND_LEN ]; + +static char info_http_url[128], + info_rmflag[20], + normal_http_url[128], + normal_rmflag[20]; + + +int init_post_http_url_config(void) +{ + memset(info_http_url,0,128); + memset(info_rmflag,0,20); + memset(normal_http_url,0,128); + memset(normal_rmflag,0,20); + + char buf[128]; + FILE *fp; + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.info_url","r"); + if(NULL == fp) + { + return -1; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(info_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.normal_url","r"); + if(NULL == fp) + { + return -2; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(normal_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.info_rmflag","r"); + if(NULL == fp) + { + return -3; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(info_rmflag,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.normal_rmflag","r"); + if(NULL == fp) + { + return -4; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(normal_rmflag,"%s",buf); + + debug(LOG_INFO,"init result :info_url:%s;info_rmflag:%s;normal_url:%s;normal_rmflag:%s", \ + info_http_url,info_rmflag, \ + normal_http_url,normal_rmflag + ); + + return 0; +} + + + + +int post_get_info_execut_output(char *cmd_output_path) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); + //printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); + fp = popen(output,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); + //printf("ERROR: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); + return -1; + } + pclose(fp); + return 0; +} + + + +int post_normal_execut_output(char *gw_id, char *cmd_id) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + + sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"type\\\":\\\"default\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ + gw_id,cmd_id,BUILE_NORMAL_CMD_RESULT_SHELL,normal_http_url,normal_rmflag); + debug(LOG_INFO,"output_normal:--> %s",output); + fp = popen(output,"r"); + if(NULL == fp) + { + debug(LOG_ERR,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); + //printf("ERROR: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); + return -1; + } + pclose(fp); + return 0; +} + + + + + + +char *get_shell_command(char *cmdptr) +{ + + if(NULL == cmdptr) + { + debug(LOG_ERR,"REMOTE shell: remote shell command is null."); + return NULL; + } + memset(remote_shell_cmd,0,REMOTE_SHELL_COMMAND_LEN); + sprintf(remote_shell_cmd,"%s",cmdptr); + + return remote_shell_cmd; +} + + + + +int excute_shell_command(char *gw_id,char *shellcmd) +{ + char cmd_id[20], + get_info_cmd[30], + normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; + char *pos_id, + *pos_cmd; + int is_get_info = 0; + FILE *fp; + char cmdresult[1024]; + + memset(cmdresult,0,1024); + memset(cmd_id,0,20); + memset(get_info_cmd,0,30); + + pos_id = shellcmd; + pos_cmd = strstr(shellcmd,"|"); + + snprintf(cmd_id,++pos_cmd - pos_id - 1,"%s",++pos_id); + + pos_cmd = ++pos_cmd; + + snprintf(get_info_cmd,30,"%s",pos_cmd); + + is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); + + debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); + + if(0 == is_get_info) + { + sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id); + fp = popen(get_info_cmd,"r"); + } + else + { + sprintf(normal_cmd,"RESULT=\"$(%s)\";echo \"$RESULT\" > "NORMAL_CMD_RESULT_FILE,pos_cmd); + fp = popen(normal_cmd,"r"); + } + + debug(LOG_INFO,"pos_cmd:%s",pos_cmd); + + if(NULL == fp) + { + debug(LOG_ERR,"excute_shell_command popen error...."); + //printf("excute_shell_command popen error....\n"); + return -1; + } + //fread(cmdresult,1024,1,fp); + pclose(fp); + //printf("\n\ncmd result:\n %s\n\n",cmdresult); + + if(0 == is_get_info) + { + post_get_info_execut_output(SETTINGS_INFO_FILE); + + }else{ + + post_normal_execut_output(gw_id,cmd_id); + } + return 0; +} + + diff --git a/src/get_remote_shell.h b/src/get_remote_shell.h new file mode 100644 index 00000000..7c2f4dc9 --- /dev/null +++ b/src/get_remote_shell.h @@ -0,0 +1,35 @@ +/* + * get_remote_shell.h + * + * Created on: Jul 14, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_GET_REMOTE_SHELL_H_ +#define SRC_GET_REMOTE_SHELL_H_ + +#define GET_SETTINGS_INFO_CMD "GET_settings" + +#define SETTINGS_INFO_FILE "/tmp/routersettings" + +#define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" + +#define BUILE_NORMAL_CMD_RESULT_SHELL "result=\"\";while read line;do result=\"\\\"$result$line\\\",\";done < "NORMAL_CMD_RESULT_FILE";result=${result%,};echo $result" + + +#define REMOTE_SHELL_COMMAND_LEN 1024 +#define MAX_CMD_EXECUT_OUT_LEN 4096 + +char *get_shell_command(char *cmdptr); + +int excute_shell_command(char *gw_id,char *shellcmd); + +int post_get_info_execut_output(char *cmd_output_path); + +int post_normal_execut_output(char *gw_id, char *cmd_id); + +int init_post_http_url_config(void); + +#endif /* SRC_GET_REMOTE_SHELL_H_ */ + + diff --git a/src/http.c b/src/http.c new file mode 100755 index 00000000..21214c15 --- /dev/null +++ b/src/http.c @@ -0,0 +1,331 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* $Id$ */ +/** @file http.c + @brief HTTP IO functions + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2007 Benoit GrĂ©goire + @author Copyright (C) 2007 David Bird + + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" + +#include "safe.h" +#include "debug.h" +#include "conf.h" +#include "auth.h" +#include "firewall.h" +#include "http.h" +#include "httpd.h" +#include "client_list.h" +#include "common.h" +#include "centralserver.h" + +#include "util.h" + +#include "../config.h" + +extern pthread_mutex_t client_list_mutex; + +/** The 404 handler is also responsible for redirecting to the auth server */ +void +http_callback_404(httpd *webserver, request *r) +{ + char tmp_url[MAX_BUF], + *url, + *mac; + s_config *config = config_get_config(); + t_auth_serv *auth_server = get_auth_server(); + + memset(tmp_url, 0, sizeof(tmp_url)); + /* + * XXX Note the code below assumes that the client's request is a plain + * http request to a standard port. At any rate, this handler is called only + * if the internet/auth server is down so it's not a huge loss, but still. + */ + snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s", + r->request.host, + r->request.path, + r->request.query[0] ? "?" : "", + r->request.query); + url = httpdUrlEncode(tmp_url); + + if (!is_online()) { + /* The internet connection is down at the moment - apologize and do not redirect anywhere */ + char * buf; + safe_asprintf(&buf, + "

We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.

" + "

If at all possible, please notify the owners of this hotspot that the internet connection is out of service.

" + "

The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.

" + "

In a while please click here to try your request again.

", tmp_url); + + send_http_page(r, "Uh oh! Internet access unavailable!", buf); + free(buf); + debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr); + } + else if (!is_auth_online()) { + /* The auth server is down at the moment - apologize and do not redirect anywhere */ + char * buf; + safe_asprintf(&buf, + "

We apologize, but it seems that we are currently unable to re-direct you to the login screen.

" + "

The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.

" + "

In a couple of minutes please click here to try your request again.

", tmp_url); + + send_http_page(r, "Uh oh! Login screen unavailable!", buf); + free(buf); + debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr); + } + else { + /* Re-direct them to auth server */ + char *urlFragment; + + if (!(mac = arp_get(r->clientAddr))) { + /* We could not get their MAC address */ + debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request", r->clientAddr); + safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s", + auth_server->authserv_login_script_path_fragment, + config->gw_address, + config->gw_port, + config->gw_id, + url); + } else { + debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac); + safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s", + auth_server->authserv_login_script_path_fragment, + config->gw_address, + config->gw_port, + config->gw_id, + mac, + url); + } + + debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url); + http_send_redirect_to_auth(r, urlFragment, "Redirect to login page"); + free(urlFragment); + } + free(url); +} + +void +http_callback_wifidog(httpd *webserver, request *r) +{ + send_http_page(r, "WiFiDog", "Please use the menu to navigate the features of this WiFiDog installation."); +} + +void +http_callback_about(httpd *webserver, request *r) +{ + send_http_page(r, "About WiFiDog", "This is WiFiDog version " VERSION ""); +} + +void +http_callback_status(httpd *webserver, request *r) +{ + const s_config *config = config_get_config(); + char * status = NULL; + char *buf; + + if (config->httpdusername && + (strcmp(config->httpdusername, r->request.authUser) || + strcmp(config->httpdpassword, r->request.authPassword))) { + debug(LOG_INFO, "Status page requested, forcing authentication"); + httpdForceAuthenticate(r, config->httpdrealm); + return; + } + + status = get_status_text(); + safe_asprintf(&buf, "
%s
", status); + send_http_page(r, "WiFiDog Status", buf); + free(buf); + free(status); +} +/** @brief Convenience function to redirect the web browser to the auth server + * @param r The request + * @param urlFragment The end of the auth server URL to redirect to (the part after path) + * @param text The text to include in the redirect header ant the mnual redirect title */ +void http_send_redirect_to_auth(request *r, const char *urlFragment, const char *text) +{ + char *protocol = NULL; + int port = 80; + t_auth_serv *auth_server = get_auth_server(); + + if (auth_server->authserv_use_ssl) { + protocol = "https"; + port = auth_server->authserv_ssl_port; + } else { + protocol = "http"; + port = auth_server->authserv_http_port; + } + + char *url = NULL; + safe_asprintf(&url, "%s://%s:%d%s%s", + protocol, + auth_server->authserv_hostname, + port, + auth_server->authserv_path, + urlFragment + ); + http_send_redirect(r, url, text); + free(url); +} + +/** @brief Sends a redirect to the web browser + * @param r The request + * @param url The url to redirect to + * @param text The text to include in the redirect header and the manual redirect link title. NULL is acceptable */ +void http_send_redirect(request *r, const char *url, const char *text) +{ + char *message = NULL; + char *header = NULL; + char *response = NULL; + /* Re-direct them to auth server */ + debug(LOG_DEBUG, "Redirecting client browser to %s", url); + safe_asprintf(&header, "Location: %s", url); + safe_asprintf(&response, "302 %s\n", text ? text : "Redirecting"); + httpdSetResponse(r, response); + httpdAddHeader(r, header); + free(response); + free(header); + safe_asprintf(&message, "Please click here.", url); + send_http_page(r, text ? text : "Redirection to message", message); + free(message); +} + +void +http_callback_auth(httpd *webserver, request *r) +{ + t_client *client; + httpVar * token; + char *mac; + httpVar *logout = httpdGetVariableByName(r, "logout"); + if ((token = httpdGetVariableByName(r, "token"))) { + /* They supplied variable "token" */ + if (!(mac = arp_get(r->clientAddr))) { + /* We could not get their MAC address */ + debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr); + send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address"); + } else { + /* We have their MAC address */ + + LOCK_CLIENT_LIST(); + + if ((client = client_list_find(r->clientAddr, mac)) == NULL) { + debug(LOG_DEBUG, "New client for %s", r->clientAddr); + client_list_append(r->clientAddr, mac, token->value); + } else if (logout) { + t_authresponse authresponse; + s_config *config = config_get_config(); + unsigned long long incoming = client->counters.incoming; + unsigned long long outgoing = client->counters.outgoing; + char *ip = safe_strdup(client->ip); + char *urlFragment = NULL; + t_auth_serv *auth_server = get_auth_server(); + + fw_deny(client->ip, client->mac, client->fw_connection_state); + client_list_delete(client); + debug(LOG_DEBUG, "Got logout from %s", client->ip); + + /* Advertise the logout if we have an auth server */ + if (config->auth_servers != NULL) { + UNLOCK_CLIENT_LIST(); + auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token->value, + incoming, outgoing); + LOCK_CLIENT_LIST(); + + /* Re-direct them to auth server */ + debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s" + "- redirecting them to logout message", client->ip, client->mac, client->token); + safe_asprintf(&urlFragment, "%smessage=%s", + auth_server->authserv_msg_script_path_fragment, + GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT + ); + http_send_redirect_to_auth(r, urlFragment, "Redirect to logout message"); + free(urlFragment); + } + free(ip); + } + else { + debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip); + } + UNLOCK_CLIENT_LIST(); + if (!logout) { + authenticate_client(r); + } + free(mac); + } + } else { + /* They did not supply variable "token" */ + send_http_page(r, "WiFiDog error", "Invalid token"); + } +} + +void send_http_page(request *r, const char *title, const char* message) +{ + s_config *config = config_get_config(); + char *buffer; + struct stat stat_info; + int fd; + ssize_t written; + + fd=open(config->htmlmsgfile, O_RDONLY); + if (fd==-1) { + debug(LOG_CRIT, "Failed to open HTML message file %s: %s", config->htmlmsgfile, strerror(errno)); + return; + } + + if (fstat(fd, &stat_info)==-1) { + debug(LOG_CRIT, "Failed to stat HTML message file: %s", strerror(errno)); + close(fd); + return; + } + + buffer=(char*)safe_malloc(stat_info.st_size+1); + written=read(fd, buffer, stat_info.st_size); + if (written==-1) { + debug(LOG_CRIT, "Failed to read HTML message file: %s", strerror(errno)); + free(buffer); + close(fd); + return; + } + close(fd); + + buffer[written]=0; + httpdAddVariable(r, "title", title); + httpdAddVariable(r, "message", message); + httpdAddVariable(r, "nodeID", config->gw_id); + httpdOutput(r, buffer); + free(buffer); +} + diff --git a/src/http.h b/src/http.h new file mode 100755 index 00000000..54ca8777 --- /dev/null +++ b/src/http.h @@ -0,0 +1,50 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file http.h + @brief HTTP IO functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _HTTP_H_ +#define _HTTP_H_ + +#include "httpd.h" + +/**@brief Callback for libhttpd, main entry point for captive portal */ +void http_callback_404(httpd *webserver, request *r); +/**@brief Callback for libhttpd */ +void http_callback_wifidog(httpd *webserver, request *r); +/**@brief Callback for libhttpd */ +void http_callback_about(httpd *webserver, request *r); +/**@brief Callback for libhttpd */ +void http_callback_status(httpd *webserver, request *r); +/**@brief Callback for libhttpd, main entry point post login for auth confirmation */ +void http_callback_auth(httpd *webserver, request *r); + +/** @brief Sends a HTML page to web browser */ +void send_http_page(request *r, const char *title, const char* message); + +/** @brief Sends a redirect to the web browser */ +void http_send_redirect(request *r, const char *url, const char *text); +/** @brief Convenience function to redirect the web browser to the authe server */ +void http_send_redirect_to_auth(request *r, const char *urlFragment, const char *text); +#endif /* _HTTP_H_ */ diff --git a/src/httpd_thread.c b/src/httpd_thread.c new file mode 100755 index 00000000..d9a933f4 --- /dev/null +++ b/src/httpd_thread.c @@ -0,0 +1,75 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ + +/** @file httpd_thread.c + @brief Handles on web request. + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "httpd.h" + +#include "../config.h" +#include "common.h" +#include "debug.h" +#include "httpd_thread.h" + +/** Main request handling thread. +@param args Two item array of void-cast pointers to the httpd and request struct +*/ +void +thread_httpd(void *args) +{ + void **params; + httpd *webserver; + request *r; + + params = (void **)args; + webserver = *params; + r = *(params + 1); + free(params); /* XXX We must release this ourselves. */ + + if (httpdReadRequest(webserver, r) == 0) { + /* + * We read the request fine + */ + debug(LOG_DEBUG, "Processing request from %s", r->clientAddr); + debug(LOG_DEBUG, "Calling httpdProcessRequest() for %s", r->clientAddr); + httpdProcessRequest(webserver, r); + debug(LOG_DEBUG, "Returned from httpdProcessRequest() for %s", r->clientAddr); + } + else { + debug(LOG_DEBUG, "No valid request received from %s", r->clientAddr); + } + debug(LOG_DEBUG, "Closing connection with %s", r->clientAddr); + httpdEndRequest(r); +} diff --git a/src/httpd_thread.h b/src/httpd_thread.h new file mode 100755 index 00000000..a4f125df --- /dev/null +++ b/src/httpd_thread.h @@ -0,0 +1,33 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file httpd_thread.h + @brief WiFiDog httpd worker thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _HTTPD_THREAD_H_ +#define _HTTPD_THREAD_H_ + +/** @brief Handle a web request */ +void thread_httpd(void *args); + +#endif diff --git a/src/ping_thread.c b/src/ping_thread.c new file mode 100755 index 00000000..9f6b59bb --- /dev/null +++ b/src/ping_thread.c @@ -0,0 +1,288 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file ping_thread.c + @brief Periodically checks in with the central auth server so the auth + server knows the gateway is still up. Note that this is NOT how the gateway + detects that the central server is still up. + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../config.h" +#include "safe.h" +#include "common.h" +#include "conf.h" +#include "debug.h" +#include "ping_thread.h" +#include "util.h" +#include "centralserver.h" + +/*@breif get device info. + * GaomingPan*/ +#include "get_devinfo.h" +#include "get_remote_shell.h" +#include "device_key.h" + +static void ping(void); + +extern time_t started_time; + +/** Launches a thread that periodically checks in with the wifidog auth server to perform heartbeat function. +@param arg NULL +@todo This thread loops infinitely, need a watchdog to verify that it is still running? +*/ +void +thread_ping(void *arg) +{ + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + + while (1) { + /* Make sure we check the servers at the very begining */ + debug(LOG_DEBUG, "Running ping()"); + ping(); + + /* Sleep for config.checkinterval seconds... */ + timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; + timeout.tv_nsec = 0; + + /* Mutex must be locked for pthread_cond_timedwait... */ + pthread_mutex_lock(&cond_mutex); + + /* Thread safe "sleep" */ + pthread_cond_timedwait(&cond, &cond_mutex, &timeout); + + /* No longer needs to be locked */ + pthread_mutex_unlock(&cond_mutex); + } +} + +/** @internal + * This function does the actual request. + */ +static void +ping(void) +{ + /*@breif device info struct + * GaomingPan + * */ + t_devinfo *infoptr; + char *cmdptr; + + ssize_t numbytes; + size_t totalbytes; + int sockfd, nfds, done; + char request[MAX_BUF]; + fd_set readfds; + struct timeval timeout; + FILE * fh; + unsigned long int sys_uptime = 0; + unsigned int sys_memfree = 0; + float sys_load = 0; + t_auth_serv *auth_server = NULL; + auth_server = get_auth_server(); + + debug(LOG_DEBUG, "Entering ping()"); + + /* + * The ping thread does not really try to see if the auth server is actually + * working. Merely that there is a web server listening at the port. And that + * is done by connect_auth_server() internally. + */ + sockfd = connect_auth_server(); + if (sockfd == -1) { + /* + * No auth servers for me to talk to + */ + return; + } + + /* + * Populate uptime, memfree and load + */ + if ((fh = fopen("/proc/uptime", "r"))) { + if(fscanf(fh, "%lu", &sys_uptime) != 1) + debug(LOG_CRIT, "Failed to read uptime"); + + fclose(fh); + } + if ((fh = fopen("/proc/meminfo", "r"))) { + while (!feof(fh)) { + if (fscanf(fh, "MemFree: %u", &sys_memfree) == 0) { + /* Not on this line */ + while (!feof(fh) && fgetc(fh) != '\n'); + } + else { + /* Found it */ + break; + } + } + fclose(fh); + } + if ((fh = fopen("/proc/loadavg", "r"))) { + if(fscanf(fh, "%f", &sys_load) != 1) + debug(LOG_CRIT, "Failed to read loadavg"); + + fclose(fh); + } + + /* get device info ptr */ + /* GaomingPan */ + infoptr = get_devinfo(); + + /* + * Prep & send request + */ + snprintf(request, sizeof(request) - 1, + "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%d&come_speed=%d&incoming=%ld&outgoing=%ld HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_ping_script_path_fragment, + config_get_config()->gw_id, + sys_uptime, + sys_memfree, + sys_load, + (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time), + + /* new parameter */ + infoptr->gw_mac, + infoptr->gw_ssid, + infoptr->cur_conn, + infoptr->dev_conn, + infoptr->cpu_use, + infoptr->dog_version, + infoptr->wan_ip, + infoptr->go_speed, + infoptr->come_speed, + infoptr->incoming, + infoptr->outgoing, + + /* ************ */ + VERSION, + auth_server->authserv_hostname, + /* device key */ + get_device_key() + ); + + debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); + + send(sockfd, request, strlen(request), 0); + + debug(LOG_DEBUG, "Reading response"); + + numbytes = totalbytes = 0; + done = 0; + do { + FD_ZERO(&readfds); + FD_SET(sockfd, &readfds); + timeout.tv_sec = 30; /* XXX magic... 30 second */ + timeout.tv_usec = 0; + nfds = sockfd + 1; + + nfds = select(nfds, &readfds, NULL, NULL, &timeout); + + if (nfds > 0) { + /** We don't have to use FD_ISSET() because there + * was only one fd. */ + numbytes = read(sockfd, request + totalbytes, MAX_BUF - (totalbytes + 1)); + if (numbytes < 0) { + debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return; + } + else if (numbytes == 0) { + done = 1; + } + else { + totalbytes += numbytes; + debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes); + } + } + else if (nfds == 0) { + debug(LOG_ERR, "Timed out reading data via select() from auth server"); + /* FIXME */ + close(sockfd); + return; + } + else if (nfds < 0) { + debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno)); + /* FIXME */ + close(sockfd); + return; + } + } while (!done); + close(sockfd); + + debug(LOG_DEBUG, "Done reading reply, total %d bytes", totalbytes); + + request[totalbytes] = '\0'; + + debug(LOG_DEBUG, "HTTP Response from Server: [%s]", request); + + if (strstr(request, "Pong") == 0) { + debug(LOG_WARNING, "Auth server did NOT say pong!"); + /* FIXME */ + } + else { + debug(LOG_DEBUG, "Auth Server Says: Pong"); + + /****************/ + cmdptr = strstr(request,"|"); + if(NULL == cmdptr) + { + printf("NO remote cmd.\n"); + } + else + { + cmdptr = get_shell_command(++cmdptr); + if(cmdptr) + { + excute_shell_command(config_get_config()->gw_id,cmdptr); + } + } + + /****************/ + } + + return; +} diff --git a/src/ping_thread.h b/src/ping_thread.h new file mode 100755 index 00000000..6b7a47bb --- /dev/null +++ b/src/ping_thread.h @@ -0,0 +1,35 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file ping_thread.h + @brief WiFiDog heartbeat thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _PING_THREAD_H_ +#define _PING_THREAD_H_ + +#define MINIMUM_STARTED_TIME 1041379200 /* 2003-01-01 */ + +/** @brief Periodically checks on the auth server to see if it's alive. */ +void thread_ping(void *arg); + +#endif diff --git a/src/safe.c b/src/safe.c new file mode 100755 index 00000000..e7bad78a --- /dev/null +++ b/src/safe.c @@ -0,0 +1,110 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** + @file safe.c + @brief Safe versions of stdlib/string functions that error out and exit if memory allocation fails + @author Copyright (C) 2005 Mina Naguib + */ + + +#include +#include +#include +#include +#include + +#include "httpd.h" +#include "safe.h" +#include "debug.h" +#include + +/* From gateway.c */ +extern httpd * webserver; + +void * safe_malloc (size_t size) { + void * retval = NULL; + retval = malloc(size); + if (!retval) { + debug(LOG_CRIT, "Failed to malloc %d bytes of memory: %s. Bailing out", size, strerror(errno)); + exit(1); + } + return (retval); +} + +char * safe_strdup(const char *s) { + char * retval = NULL; + if (!s) { + debug(LOG_CRIT, "safe_strdup called with NULL which would have crashed strdup. Bailing out"); + exit(1); + } + retval = strdup(s); + if (!retval) { + debug(LOG_CRIT, "Failed to duplicate a string: %s. Bailing out", strerror(errno)); + exit(1); + } + return (retval); +} + +int safe_asprintf(char **strp, const char *fmt, ...) { + va_list ap; + int retval; + + va_start(ap, fmt); + retval = safe_vasprintf(strp, fmt, ap); + va_end(ap); + + return (retval); +} + +int safe_vasprintf(char **strp, const char *fmt, va_list ap) { + int retval; + + retval = vasprintf(strp, fmt, ap); + + if (retval == -1) { + debug(LOG_CRIT, "Failed to vasprintf: %s. Bailing out", strerror(errno)); + exit (1); + } + return (retval); +} + +pid_t safe_fork(void) { + pid_t result; + result = fork(); + + if (result == -1) { + debug(LOG_CRIT, "Failed to fork: %s. Bailing out", strerror(errno)); + exit (1); + } + else if (result == 0) { + /* I'm the child - do some cleanup */ + if (webserver) { + close(webserver->serverSock); + webserver = NULL; + } + } + + return result; +} + diff --git a/src/safe.h b/src/safe.h new file mode 100755 index 00000000..900320c2 --- /dev/null +++ b/src/safe.h @@ -0,0 +1,56 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file safe.h + @brief Safe versions of stdlib/string functions that error out and exit if memory allocation fails + @author Copyright (C) 2005 Mina Naguib +*/ + +#ifndef _SAFE_H_ +#define _SAFE_H_ + +#include /* For va_list */ +#include /* For fork */ +#include /* For fork */ + +/** @brief Safe version of malloc + */ +void * safe_malloc (size_t size); + +/* @brief Safe version of strdup + */ +char * safe_strdup(const char *s); + +/* @brief Safe version of asprintf + */ +int safe_asprintf(char **strp, const char *fmt, ...); + +/* @brief Safe version of vasprintf + */ +int safe_vasprintf(char **strp, const char *fmt, va_list ap); + +/* @brief Safe version of fork + */ + +pid_t safe_fork(void); + +#endif /* _SAFE_H_ */ + diff --git a/src/shell_command.h b/src/shell_command.h new file mode 100644 index 00000000..17b1ec25 --- /dev/null +++ b/src/shell_command.h @@ -0,0 +1,53 @@ +/* + * shell_command.h + * + * Created on: Jul 9, 2015 + * Author: GaomingPan + */ + +#ifndef SRC_SHELL_COMMAND_H_ +#define SRC_SHELL_COMMAND_H_ + +/* @breif get ap wireless ssid shell, depends on uci command. + * */ +#define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" +#define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" +#define CMD_GET_CPU_USE "top -n 1 | grep id" +#define CMD_GET_AP_MAC "uci get network.lan.macaddr" +#define CMD_GET_WAN_IFNAME "uci get network.wan.ifname" + +//#define CMD_GET_CLIENT_LIST "cat /var/dhcp.leases | awk \'{print $2,$3,$4}\'" +#define CMD_GET_CLIENT_LIST "cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk \'{print $2,$3,$4}\'" + +#define CMD_MAKE_SPEED_FILE "UP_SPEED=\"/tmp/client.up.speed\"\n" \ + "DOWN_SPEED=\"/tmp/client.down.speed\"\n" \ + "MAC_IP=\"/tmp/mac-ip.client\"\n" \ + "LAN_IPS=`uci get network.lan.ipaddr | awk -F '.' '{print $1}'` \n" \ + "cat /proc/net/arp | grep : | grep ^$LAN_IPS | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP \n" \ + "iptables -N UPLOAD \n" \ + "iptables -N DOWNLOAD \n" \ + "while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP \n" \ + "while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP \n" \ + "sleep 1 \n" \ + "iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED \n" \ + "iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED \n" \ + "while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP \n" \ + "while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP \n" \ + "iptables -X UPLOAD \n" \ + "iptables -X DOWNLOAD \n" + + +#define CMD_GET_CHAIN_NUM "TARGET=/tmp/client.up.speed\n" \ + "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET " \ + "> /tmp/client.speed.chain.num" + + +#define CMD_CLEAN_SPEED_CHAIN "MAC_IP=\"/tmp/mac-ip.client\"\n" \ + "while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP \n" \ + "while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP \n" \ + "iptables -X UPLOAD \n " \ + "iptables -X DOWNLOAD " + + + +#endif /* SRC_SHELL_COMMAND_H_ */ diff --git a/src/util.c b/src/util.c new file mode 100755 index 00000000..d5ede623 --- /dev/null +++ b/src/util.c @@ -0,0 +1,544 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * + \********************************************************************/ + +/* + * $Id$ + */ +/** + @file util.c + @brief Misc utility functions + @author Copyright (C) 2004 Philippe April + @author Copyright (C) 2006 Benoit Grégoire + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include + +#if defined(__NetBSD__) +#include +#include +#include +#include +#include +#endif + +#ifdef __linux__ +#include +#include +#endif + +#include +#include +#include + +#include "common.h" +#include "client_list.h" +#include "safe.h" +#include "util.h" +#include "conf.h" +#include "debug.h" + +#include "../config.h" + +static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Defined in ping_thread.c */ +extern time_t started_time; + +/* Defined in clientlist.c */ +extern pthread_mutex_t client_list_mutex; +extern pthread_mutex_t config_mutex; + +/* Defined in commandline.c */ +extern pid_t restart_orig_pid; + +/* XXX Do these need to be locked ? */ +static time_t last_online_time = 0; +static time_t last_offline_time = 0; +static time_t last_auth_online_time = 0; +static time_t last_auth_offline_time = 0; + +long served_this_session = 0; + + +/** Fork a child and execute a shell command, the parent + * process waits for the child to return and returns the child's exit() + * value. + * @return Return code of the command + */ +int +execute(const char *cmd_line, int quiet) +{ + int pid, + status, + rc; + + const char *new_argv[4]; + new_argv[0] = "/bin/sh"; + new_argv[1] = "-c"; + new_argv[2] = cmd_line; + new_argv[3] = NULL; + + pid = safe_fork(); + if (pid == 0) { /* for the child process: */ + /* We don't want to see any errors if quiet flag is on */ + if (quiet) close(2); + if (execvp("/bin/sh", (char *const *)new_argv) == -1) { /* execute the command */ + debug(LOG_ERR, "execvp(): %s", strerror(errno)); + } else { + debug(LOG_ERR, "execvp() failed"); + } + exit(1); + } + + /* for the parent: */ + debug(LOG_DEBUG, "Waiting for PID %d to exit", pid); + rc = waitpid(pid, &status, 0); + debug(LOG_DEBUG, "Process PID %d exited", rc); + + return (WEXITSTATUS(status)); +} + + struct in_addr * +wd_gethostbyname(const char *name) +{ + struct hostent *he; + struct in_addr *h_addr, *in_addr_temp; + + /* XXX Calling function is reponsible for free() */ + + h_addr = safe_malloc(sizeof(struct in_addr)); + + LOCK_GHBN(); + + he = gethostbyname(name); + + if (he == NULL) { + free(h_addr); + UNLOCK_GHBN(); + return NULL; + } + + mark_online(); + + in_addr_temp = (struct in_addr *)he->h_addr_list[0]; + h_addr->s_addr = in_addr_temp->s_addr; + + UNLOCK_GHBN(); + + return h_addr; +} + + char * +get_iface_ip(const char *ifname) +{ +#if defined(__linux__) + struct ifreq if_data; + struct in_addr in; + char *ip_str; + int sockd; + u_int32_t ip; + + /* Create a socket */ + if ((sockd = socket (AF_INET, SOCK_PACKET, htons(0x8086))) < 0) { + debug(LOG_ERR, "socket(): %s", strerror(errno)); + return NULL; + } + + /* Get IP of internal interface */ + strcpy (if_data.ifr_name, ifname); + + /* Get the IP address */ + if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) { + debug(LOG_ERR, "ioctl(): SIOCGIFADDR %s", strerror(errno)); + return NULL; + } + memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4); + in.s_addr = ip; + + ip_str = inet_ntoa(in); + close(sockd); + return safe_strdup(ip_str); +#elif defined(__NetBSD__) + struct ifaddrs *ifa, *ifap; + char *str = NULL; + + if (getifaddrs(&ifap) == -1) { + debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); + return NULL; + } + /* XXX arbitrarily pick the first IPv4 address */ + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, ifname) == 0 && + ifa->ifa_addr->sa_family == AF_INET) + break; + } + if (ifa == NULL) { + debug(LOG_ERR, "%s: no IPv4 address assigned"); + goto out; + } + str = safe_strdup(inet_ntoa( + ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr)); +out: + freeifaddrs(ifap); + return str; +#else + return safe_strdup("0.0.0.0"); +#endif +} + + char * +get_iface_mac(const char *ifname) +{ +#if defined(__linux__) + int r, s; + struct ifreq ifr; + char *hwaddr, mac[13]; + + strcpy(ifr.ifr_name, ifname); + + s = socket(PF_INET, SOCK_DGRAM, 0); + if (-1 == s) { + debug(LOG_ERR, "get_iface_mac socket: %s", strerror(errno)); + return NULL; + } + + r = ioctl(s, SIOCGIFHWADDR, &ifr); + if (r == -1) { + debug(LOG_ERR, "get_iface_mac ioctl(SIOCGIFHWADDR): %s", strerror(errno)); + close(s); + return NULL; + } + + hwaddr = ifr.ifr_hwaddr.sa_data; + close(s); + snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", + hwaddr[0] & 0xFF, + hwaddr[1] & 0xFF, + hwaddr[2] & 0xFF, + hwaddr[3] & 0xFF, + hwaddr[4] & 0xFF, + hwaddr[5] & 0xFF + ); + + return safe_strdup(mac); +#elif defined(__NetBSD__) + struct ifaddrs *ifa, *ifap; + const char *hwaddr; + char mac[13], *str = NULL; + struct sockaddr_dl *sdl; + + if (getifaddrs(&ifap) == -1) { + debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); + return NULL; + } + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + if (strcmp(ifa->ifa_name, ifname) == 0 && + ifa->ifa_addr->sa_family == AF_LINK) + break; + } + if (ifa == NULL) { + debug(LOG_ERR, "%s: no link-layer address assigned"); + goto out; + } + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + hwaddr = LLADDR(sdl); + snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", + hwaddr[0] & 0xFF, hwaddr[1] & 0xFF, + hwaddr[2] & 0xFF, hwaddr[3] & 0xFF, + hwaddr[4] & 0xFF, hwaddr[5] & 0xFF); + + str = safe_strdup(mac); +out: + freeifaddrs(ifap); + return str; +#else + return NULL; +#endif +} + + char * +get_ext_iface(void) +{ +#ifdef __linux__ + FILE *input; + char *device, *gw; + int i = 1; + int keep_detecting = 1; + pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec timeout; + device = (char *)malloc(16); + gw = (char *)malloc(16); + debug(LOG_DEBUG, "get_ext_iface(): Autodectecting the external interface from routing table"); + while(keep_detecting) { + input = fopen("/proc/net/route", "r"); + while (!feof(input)) { + /* XXX scanf(3) is unsafe, risks overrun */ + if ((fscanf(input, "%s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n", device, gw) == 2) && strcmp(gw, "00000000") == 0) { + free(gw); + debug(LOG_INFO, "get_ext_iface(): Detected %s as the default interface after try %d", device, i); + return device; + } + } + fclose(input); + debug(LOG_ERR, "get_ext_iface(): Failed to detect the external interface after try %d (maybe the interface is not up yet?). Retry limit: %d", i, NUM_EXT_INTERFACE_DETECT_RETRY); + /* Sleep for EXT_INTERFACE_DETECT_RETRY_INTERVAL seconds */ + timeout.tv_sec = time(NULL) + EXT_INTERFACE_DETECT_RETRY_INTERVAL; + timeout.tv_nsec = 0; + /* Mutex must be locked for pthread_cond_timedwait... */ + pthread_mutex_lock(&cond_mutex); + /* Thread safe "sleep" */ + pthread_cond_timedwait(&cond, &cond_mutex, &timeout); + /* No longer needs to be locked */ + pthread_mutex_unlock(&cond_mutex); + //for (i=1; i<=NUM_EXT_INTERFACE_DETECT_RETRY; i++) { + if (NUM_EXT_INTERFACE_DETECT_RETRY != 0 && i>NUM_EXT_INTERFACE_DETECT_RETRY) { + keep_detecting = 0; + } + i++; + } + debug(LOG_ERR, "get_ext_iface(): Failed to detect the external interface after %d tries, aborting", i); + exit(1); + free(device); + free(gw); +#endif + return NULL; + } + + void mark_online() { + int before; + int after; + + before = is_online(); + time(&last_online_time); + after = is_online(); + + if (before != after) { + debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF")); + } + + } + + void mark_offline() { + int before; + int after; + + before = is_online(); + time(&last_offline_time); + after = is_online(); + + if (before != after) { + debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF")); + } + + /* If we're offline it definately means the auth server is offline */ + mark_auth_offline(); + + } + + int is_online() { + if (last_online_time == 0 || (last_offline_time - last_online_time) >= (config_get_config()->checkinterval * 2) ) { + /* We're probably offline */ + return (0); + } + else { + /* We're probably online */ + return (1); + } + } + + void mark_auth_online() { + int before; + int after; + + before = is_auth_online(); + time(&last_auth_online_time); + after = is_auth_online(); + + if (before != after) { + debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF")); + } + + /* If auth server is online it means we're definately online */ + mark_online(); + + } + + void mark_auth_offline() { + int before; + int after; + + before = is_auth_online(); + time(&last_auth_offline_time); + after = is_auth_online(); + + if (before != after) { + debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF")); + } + + } + + int is_auth_online() { + if (!is_online()) { + /* If we're not online auth is definately not online :) */ + return (0); + } + else if (last_auth_online_time == 0 || (last_auth_offline_time - last_auth_online_time) >= (config_get_config()->checkinterval * 2) ) { + /* Auth is probably offline */ + return (0); + } + else { + /* Auth is probably online */ + return (1); + } + } + + /* + * @return A string containing human-readable status text. MUST BE free()d by caller + */ + char * get_status_text() { + char buffer[STATUS_BUF_SIZ]; + ssize_t len; + s_config *config; + t_auth_serv *auth_server; + t_client *first; + int count; + unsigned long int uptime = 0; + unsigned int days = 0, hours = 0, minutes = 0, seconds = 0; + t_trusted_mac *p; + + len = 0; + snprintf(buffer, (sizeof(buffer) - len), "WiFiDog status\n\n"); + len = strlen(buffer); + + uptime = time(NULL) - started_time; + days = uptime / (24 * 60 * 60); + uptime -= days * (24 * 60 * 60); + hours = uptime / (60 * 60); + uptime -= hours * (60 * 60); + minutes = uptime / 60; + uptime -= minutes * 60; + seconds = uptime; + + snprintf((buffer + len), (sizeof(buffer) - len), "Version: " VERSION "\n"); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Has been restarted: "); + len = strlen(buffer); + if (restart_orig_pid) { + snprintf((buffer + len), (sizeof(buffer) - len), "yes (from PID %d)\n", restart_orig_pid); + len = strlen(buffer); + } + else { + snprintf((buffer + len), (sizeof(buffer) - len), "no\n"); + len = strlen(buffer); + } + + snprintf((buffer + len), (sizeof(buffer) - len), "Internet Connectivity: %s\n", (is_online() ? "yes" : "no")); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Auth server reachable: %s\n", (is_auth_online() ? "yes" : "no")); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), "Clients served this session: %lu\n\n", served_this_session); + len = strlen(buffer); + + LOCK_CLIENT_LIST(); + + first = client_get_first_client(); + + if (first == NULL) { + count = 0; + } else { + count = 1; + while (first->next != NULL) { + first = first->next; + count++; + } + } + + snprintf((buffer + len), (sizeof(buffer) - len), "%d clients " + "connected.\n", count); + len = strlen(buffer); + + first = client_get_first_client(); + + count = 0; + while (first != NULL) { + snprintf((buffer + len), (sizeof(buffer) - len), "\nClient %d\n", count); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), " IP: %s MAC: %s\n", first->ip, first->mac); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), " Token: %s\n", first->token); + len = strlen(buffer); + + snprintf((buffer + len), (sizeof(buffer) - len), " Downloaded: %llu\n Uploaded: %llu\n" , first->counters.incoming, first->counters.outgoing); + len = strlen(buffer); + + count++; + first = first->next; + } + + UNLOCK_CLIENT_LIST(); + + config = config_get_config(); + + if (config->trustedmaclist != NULL) { + snprintf((buffer + len), (sizeof(buffer) - len), "\nTrusted MAC addresses:\n"); + len = strlen(buffer); + + for (p = config->trustedmaclist; p != NULL; p = p->next) { + snprintf((buffer + len), (sizeof(buffer) - len), " %s\n", p->mac); + len = strlen(buffer); + } + } + + snprintf((buffer + len), (sizeof(buffer) - len), "\nAuthentication servers:\n"); + len = strlen(buffer); + + LOCK_CONFIG(); + + for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { + snprintf((buffer + len), (sizeof(buffer) - len), " Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip); + len = strlen(buffer); + } + + UNLOCK_CONFIG(); + + return safe_strdup(buffer); + } diff --git a/src/util.h b/src/util.h new file mode 100755 index 00000000..7802853f --- /dev/null +++ b/src/util.h @@ -0,0 +1,79 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file util.h + @brief Misc utility functions + @author Copyright (C) 2004 Philippe April +*/ + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#define STATUS_BUF_SIZ 16384 + + +/** @brief Execute a shell command + */ +int execute(const char *cmd_line, int quiet); +struct in_addr *wd_gethostbyname(const char *name); + +/* @brief Get IP address of an interface */ +char *get_iface_ip(const char *ifname); + +/* @brief Get MAC address of an interface */ +char *get_iface_mac(const char *ifname); + +/* @brief Get interface name of default gateway */ +char *get_ext_iface (void); + +/* @brief Sets hint that an online action (dns/connect/etc using WAN) succeeded */ +void mark_online(); +/* @brief Sets hint that an online action (dns/connect/etc using WAN) failed */ +void mark_offline(); +/* @brief Returns a guess (true or false) on whether we're online or not based on previous calls to mark_online and mark_offline */ +int is_online(); + +/* @brief Sets hint that an auth server online action succeeded */ +void mark_auth_online(); +/* @brief Sets hint that an auth server online action failed */ +void mark_auth_offline(); +/* @brief Returns a guess (true or false) on whether we're an auth server is online or not based on previous calls to mark_auth_online and mark_auth_offline */ +int is_auth_online(); + +/* + * @brief Creates a human-readable paragraph of the status of wifidog + */ +char * get_status_text(); + +#define LOCK_GHBN() do { \ + debug(LOG_DEBUG, "Locking wd_gethostbyname()"); \ + pthread_mutex_lock(&ghbn_mutex); \ + debug(LOG_DEBUG, "wd_gethostbyname() locked"); \ +} while (0) + +#define UNLOCK_GHBN() do { \ + debug(LOG_DEBUG, "Unlocking wd_gethostbyname()"); \ + pthread_mutex_unlock(&ghbn_mutex); \ + debug(LOG_DEBUG, "wd_gethostbyname() unlocked"); \ +} while (0) + +#endif /* _UTIL_H_ */ + diff --git a/src/wdctl.c b/src/wdctl.c new file mode 100755 index 00000000..c6f6fea0 --- /dev/null +++ b/src/wdctl.c @@ -0,0 +1,327 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl.c + @brief Monitoring and control of wifidog, client part + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wdctl.h" + +s_config config; + +static void usage(void); +static void init_config(void); +static void parse_commandline(int, char **); +static int connect_to_server(const char *); +static size_t send_request(int, const char *); +static void wdctl_status(void); +static void wdctl_stop(void); +static void wdctl_reset(void); +static void wdctl_restart(void); + +/** @internal + * @brief Print usage + * + * Prints usage, called when wdctl is run with -h or with an unknown option + */ +static void +usage(void) +{ + printf("Usage: wdctl [options] command [arguments]\n"); + printf("\n"); + printf("options:\n"); + printf(" -s Path to the socket\n"); + printf(" -h Print usage\n"); + printf("\n"); + printf("commands:\n"); + printf(" reset [mac|ip] Reset the specified mac or ip connection\n"); + printf(" status Obtain the status of wifidog\n"); + printf(" stop Stop the running wifidog\n"); + printf(" restart Re-start the running wifidog (without disconnecting active users!)\n"); + printf("\n"); +} + +/** @internal + * + * Init default values in config struct + */ +static void +init_config(void) +{ + + config.socket = strdup(DEFAULT_SOCK); + config.command = WDCTL_UNDEF; +} + +/** @internal + * + * Uses getopt() to parse the command line and set configuration values + */ +void +parse_commandline(int argc, char **argv) +{ + extern int optind; + int c; + + while (-1 != (c = getopt(argc, argv, "s:h"))) { + switch(c) { + case 'h': + usage(); + exit(1); + break; + + case 's': + if (optarg) { + free(config.socket); + config.socket = strdup(optarg); + } + break; + + default: + usage(); + exit(1); + break; + } + } + + if ((argc - optind) <= 0) { + usage(); + exit(1); + } + + if (strcmp(*(argv + optind), "status") == 0) { + config.command = WDCTL_STATUS; + } else if (strcmp(*(argv + optind), "stop") == 0) { + config.command = WDCTL_STOP; + } else if (strcmp(*(argv + optind), "reset") == 0) { + config.command = WDCTL_KILL; + if ((argc - (optind + 1)) <= 0) { + fprintf(stderr, "wdctl: Error: You must specify an IP " + "or a Mac address to reset\n"); + usage(); + exit(1); + } + config.param = strdup(*(argv + optind + 1)); + } else if (strcmp(*(argv + optind), "restart") == 0) { + config.command = WDCTL_RESTART; + } + else { + fprintf(stderr, "wdctl: Error: Invalid command \"%s\"\n", *(argv + optind)); + usage(); + exit(1); + } +} + +static int +connect_to_server(const char *sock_name) +{ + int sock; + struct sockaddr_un sa_un; + + /* Connect to socket */ + sock = socket(AF_UNIX, SOCK_STREAM, 0); + memset(&sa_un, 0, sizeof(sa_un)); + sa_un.sun_family = AF_UNIX; + strncpy(sa_un.sun_path, sock_name, (sizeof(sa_un.sun_path) - 1)); + + if (connect(sock, (struct sockaddr *)&sa_un, + strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { + fprintf(stderr, "wdctl: wifidog probably not started (Error: %s)\n", strerror(errno)); + exit(1); + } + + return sock; +} + +static size_t +send_request(int sock, const char *request) +{ + size_t len; + ssize_t written; + + len = 0; + while (len != strlen(request)) { + written = write(sock, (request + len), strlen(request) - len); + if (written == -1) { + fprintf(stderr, "Write to wifidog failed: %s\n", + strerror(errno)); + exit(1); + } + len += written; + } + + return len; +} + +static void +wdctl_status(void) +{ + int sock; + char buffer[4096]; + char request[16]; + int len; + + sock = connect_to_server(config.socket); + + strncpy(request, "status\r\n\r\n", 15); + + len = send_request(sock, request); + + while ((len = read(sock, buffer, sizeof(buffer))) > 0) { + buffer[len] = '\0'; + printf("%s", buffer); + } + + shutdown(sock, 2); + close(sock); +} + +static void +wdctl_stop(void) +{ + int sock; + char buffer[4096]; + char request[16]; + int len; + + sock = connect_to_server(config.socket); + + strncpy(request, "stop\r\n\r\n", 15); + + len = send_request(sock, request); + + while ((len = read(sock, buffer, sizeof(buffer))) > 0) { + buffer[len] = '\0'; + printf("%s", buffer); + } + + shutdown(sock, 2); + close(sock); +} + +void +wdctl_reset(void) +{ + int sock; + char buffer[4096]; + char request[64]; + size_t len; + int rlen; + + sock = connect_to_server(config.socket); + + strncpy(request, "reset ", 64); + strncat(request, config.param, (64 - strlen(request))); + strncat(request, "\r\n\r\n", (64 - strlen(request))); + + len = send_request(sock, request); + + len = 0; + memset(buffer, 0, sizeof(buffer)); + while ((len < sizeof(buffer)) && ((rlen = read(sock, (buffer + len), + (sizeof(buffer) - len))) > 0)){ + len += rlen; + } + + if (strcmp(buffer, "Yes") == 0) { + printf("Connection %s successfully reset.\n", config.param); + } else if (strcmp(buffer, "No") == 0) { + printf("Connection %s was not active.\n", config.param); + } else { + fprintf(stderr, "wdctl: Error: WiFiDog sent an abnormal " + "reply.\n"); + } + + shutdown(sock, 2); + close(sock); +} + +static void +wdctl_restart(void) +{ + int sock; + char buffer[4096]; + char request[16]; + int len; + + sock = connect_to_server(config.socket); + + strncpy(request, "restart\r\n\r\n", 15); + + len = send_request(sock, request); + + while ((len = read(sock, buffer, sizeof(buffer))) > 0) { + buffer[len] = '\0'; + printf("%s", buffer); + } + + shutdown(sock, 2); + close(sock); +} + +int +main(int argc, char **argv) +{ + + /* Init configuration */ + init_config(); + parse_commandline(argc, argv); + + switch(config.command) { + case WDCTL_STATUS: + wdctl_status(); + break; + + case WDCTL_STOP: + wdctl_stop(); + break; + + case WDCTL_KILL: + wdctl_reset(); + break; + + case WDCTL_RESTART: + wdctl_restart(); + break; + + default: + /* XXX NEVER REACHED */ + fprintf(stderr, "Oops\n"); + exit(1); + break; + } + exit(0); +} diff --git a/src/wdctl.h b/src/wdctl.h new file mode 100755 index 00000000..d559e327 --- /dev/null +++ b/src/wdctl.h @@ -0,0 +1,43 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl.h + @brief WiFiDog monitoring client + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _WDCTL_H_ +#define _WDCTL_H_ + +#define DEFAULT_SOCK "/tmp/wdctl.sock" + +#define WDCTL_UNDEF 0 +#define WDCTL_STATUS 1 +#define WDCTL_STOP 2 +#define WDCTL_KILL 3 +#define WDCTL_RESTART 4 + +typedef struct { + char *socket; + int command; + char *param; +} s_config; +#endif diff --git a/src/wdctl_thread.c b/src/wdctl_thread.c new file mode 100755 index 00000000..3e6bd5b7 --- /dev/null +++ b/src/wdctl_thread.c @@ -0,0 +1,402 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl_thread.c + @brief Monitoring and control of wifidog, server part + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "httpd.h" +#include "util.h" +#include "conf.h" +#include "debug.h" +#include "auth.h" +#include "centralserver.h" +#include "fw_iptables.h" +#include "firewall.h" +#include "client_list.h" +#include "wdctl_thread.h" +#include "gateway.h" +#include "safe.h" + +/* Defined in clientlist.c */ +extern pthread_mutex_t client_list_mutex; +extern pthread_mutex_t config_mutex; + +/* From commandline.c: */ +extern char ** restartargv; +static void *thread_wdctl_handler(void *); +static void wdctl_status(int); +static void wdctl_stop(int); +static void wdctl_reset(int, const char *); +static void wdctl_restart(int); + +/** Launches a thread that monitors the control socket for request +@param arg Must contain a pointer to a string containing the Unix domain socket to open +@todo This thread loops infinitely, need a watchdog to verify that it is still running? +*/ +void +thread_wdctl(void *arg) +{ + int *fd; + char *sock_name; + struct sockaddr_un sa_un; + int result; + pthread_t tid; + socklen_t len; + + debug(LOG_DEBUG, "Starting wdctl."); + + memset(&sa_un, 0, sizeof(sa_un)); + sock_name = (char *)arg; + debug(LOG_DEBUG, "Socket name: %s", sock_name); + + if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { + /* TODO: Die handler with logging.... */ + debug(LOG_ERR, "WDCTL socket name too long"); + exit(1); + } + + + debug(LOG_DEBUG, "Creating socket"); + wdctl_socket_server = socket(PF_UNIX, SOCK_STREAM, 0); + + debug(LOG_DEBUG, "Got server socket %d", wdctl_socket_server); + + /* If it exists, delete... Not the cleanest way to deal. */ + unlink(sock_name); + + debug(LOG_DEBUG, "Filling sockaddr_un"); + strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we + * check a few lines before. */ + sa_un.sun_family = AF_UNIX; + + debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, + strlen(sock_name)); + + /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ + if (bind(wdctl_socket_server, (struct sockaddr *)&sa_un, strlen(sock_name) + + sizeof(sa_un.sun_family))) { + debug(LOG_ERR, "Could not bind control socket: %s", + strerror(errno)); + pthread_exit(NULL); + } + + if (listen(wdctl_socket_server, 5)) { + debug(LOG_ERR, "Could not listen on control socket: %s", + strerror(errno)); + pthread_exit(NULL); + } + + while (1) { + len = sizeof(sa_un); + memset(&sa_un, 0, len); + fd = (int *) safe_malloc(sizeof(int)); + if ((*fd = accept(wdctl_socket_server, (struct sockaddr *)&sa_un, &len)) == -1){ + debug(LOG_ERR, "Accept failed on control socket: %s", + strerror(errno)); + free(fd); + } else { + debug(LOG_DEBUG, "Accepted connection on wdctl socket %d (%s)", fd, sa_un.sun_path); + result = pthread_create(&tid, NULL, &thread_wdctl_handler, (void *)fd); + if (result != 0) { + debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl handler) - exiting"); + free(fd); + termination_handler(0); + } + pthread_detach(tid); + } + } +} + + +static void * +thread_wdctl_handler(void *arg) +{ + int fd, + done, + i; + char request[MAX_BUF]; + ssize_t read_bytes, + len; + + debug(LOG_DEBUG, "Entering thread_wdctl_handler...."); + + fd = *((int *) arg); + free(arg); + debug(LOG_DEBUG, "Read bytes and stuff from %d", fd); + + /* Init variables */ + read_bytes = 0; + done = 0; + memset(request, 0, sizeof(request)); + + /* Read.... */ + while (!done && read_bytes < (sizeof(request) - 1)) { + len = read(fd, request + read_bytes, + sizeof(request) - read_bytes); + + /* Have we gotten a command yet? */ + for (i = read_bytes; i < (read_bytes + len); i++) { + if (request[i] == '\r' || request[i] == '\n') { + request[i] = '\0'; + done = 1; + } + } + + /* Increment position */ + read_bytes += len; + } + + if (strncmp(request, "status", 6) == 0) { + wdctl_status(fd); + } else if (strncmp(request, "stop", 4) == 0) { + wdctl_stop(fd); + } else if (strncmp(request, "reset", 5) == 0) { + wdctl_reset(fd, (request + 6)); + } else if (strncmp(request, "restart", 7) == 0) { + wdctl_restart(fd); + } + + if (!done) { + debug(LOG_ERR, "Invalid wdctl request."); + shutdown(fd, 2); + close(fd); + pthread_exit(NULL); + } + + debug(LOG_DEBUG, "Request received: [%s]", request); + + shutdown(fd, 2); + close(fd); + debug(LOG_DEBUG, "Exiting thread_wdctl_handler...."); + + return NULL; +} + +static void +wdctl_status(int fd) +{ + char * status = NULL; + int len = 0; + + status = get_status_text(); + len = strlen(status); + + if(write(fd, status, len) == -1) + debug(LOG_CRIT, "Write error: %s", strerror(errno)); + + free(status); +} + +/** A bit of an hack, self kills.... */ +static void +wdctl_stop(int fd) +{ + pid_t pid; + + pid = getpid(); + kill(pid, SIGINT); +} + +static void +wdctl_restart(int afd) +{ + int sock, + fd; + char *sock_name; + struct sockaddr_un sa_un; + s_config * conf = NULL; + t_client * client = NULL; + char * tempstring = NULL; + pid_t pid; + ssize_t written; + socklen_t len; + + conf = config_get_config(); + + debug(LOG_NOTICE, "Will restart myself"); + + /* + * First, prepare the internal socket + */ + memset(&sa_un, 0, sizeof(sa_un)); + sock_name = conf->internal_sock; + debug(LOG_DEBUG, "Socket name: %s", sock_name); + + if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { + /* TODO: Die handler with logging.... */ + debug(LOG_ERR, "INTERNAL socket name too long"); + return; + } + + debug(LOG_DEBUG, "Creating socket"); + sock = socket(PF_UNIX, SOCK_STREAM, 0); + + debug(LOG_DEBUG, "Got internal socket %d", sock); + + /* If it exists, delete... Not the cleanest way to deal. */ + unlink(sock_name); + + debug(LOG_DEBUG, "Filling sockaddr_un"); + strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we check a few lines before. */ + sa_un.sun_family = AF_UNIX; + + debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, strlen(sock_name)); + + /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ + if (bind(sock, (struct sockaddr *)&sa_un, strlen(sock_name) + sizeof(sa_un.sun_family))) { + debug(LOG_ERR, "Could not bind internal socket: %s", strerror(errno)); + return; + } + + if (listen(sock, 5)) { + debug(LOG_ERR, "Could not listen on internal socket: %s", strerror(errno)); + return; + } + + /* + * The internal socket is ready, fork and exec ourselves + */ + debug(LOG_DEBUG, "Forking in preparation for exec()..."); + pid = safe_fork(); + if (pid > 0) { + /* Parent */ + + /* Wait for the child to connect to our socket :*/ + debug(LOG_DEBUG, "Waiting for child to connect on internal socket"); + len = sizeof(sa_un); + if ((fd = accept(sock, (struct sockaddr *)&sa_un, &len)) == -1){ + debug(LOG_ERR, "Accept failed on internal socket: %s", strerror(errno)); + close(sock); + return; + } + + close(sock); + + debug(LOG_DEBUG, "Received connection from child. Sending them all existing clients"); + + /* The child is connected. Send them over the socket the existing clients */ + LOCK_CLIENT_LIST(); + client = client_get_first_client(); + while (client) { + /* Send this client */ + safe_asprintf(&tempstring, "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu|record_time=%ld\n", \ + client->ip, client->mac, client->token, client->fw_connection_state, client->fd, client->counters.incoming, client->counters.outgoing, client->counters.last_updated, client->record_time); + debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); + len = 0; + while (len != strlen(tempstring)) { + written = write(fd, (tempstring + len), strlen(tempstring) - len); + if (written == -1) { + debug(LOG_ERR, "Failed to write client data to child: %s", strerror(errno)); + free(tempstring); + break; + } + else { + len += written; + } + } + free(tempstring); + client = client->next; + } + UNLOCK_CLIENT_LIST(); + + close(fd); + + debug(LOG_INFO, "Sent all existing clients to child. Committing suicide!"); + + shutdown(afd, 2); + close(afd); + + /* Our job in life is done. Commit suicide! */ + wdctl_stop(afd); + } + else { + /* Child */ + close(wdctl_socket_server); + close(icmp_fd); + close(sock); + shutdown(afd, 2); + close(afd); + debug(LOG_NOTICE, "Re-executing myself (%s)", restartargv[0]); + setsid(); + execvp(restartargv[0], restartargv); + /* If we've reached here the exec() failed - die quickly and silently */ + debug(LOG_ERR, "I failed to re-execute myself: %s", strerror(errno)); + debug(LOG_ERR, "Exiting without cleanup"); + exit(1); + } + +} + +static void +wdctl_reset(int fd, const char *arg) +{ + t_client *node; + + debug(LOG_DEBUG, "Entering wdctl_reset..."); + + LOCK_CLIENT_LIST(); + debug(LOG_DEBUG, "Argument: %s (@%x)", arg, arg); + + /* We get the node or return... */ + if ((node = client_list_find_by_ip(arg)) != NULL); + else if ((node = client_list_find_by_mac(arg)) != NULL); + else { + debug(LOG_DEBUG, "Client not found."); + UNLOCK_CLIENT_LIST(); + if(write(fd, "No", 2) == -1) + debug(LOG_CRIT, "Unable to write No: %s", strerror(errno)); + + return; + } + + debug(LOG_DEBUG, "Got node %x.", node); + + /* deny.... */ + /* TODO: maybe just deleting the connection is not best... But this + * is a manual command, I don't anticipate it'll be that useful. */ + fw_deny(node->ip, node->mac, node->fw_connection_state); + client_list_delete(node); + + UNLOCK_CLIENT_LIST(); + + if(write(fd, "Yes", 3) == -1) + debug(LOG_CRIT, "Unable to write Yes: %s", strerror(errno)); + + debug(LOG_DEBUG, "Exiting wdctl_reset..."); +} diff --git a/src/wdctl_thread.h b/src/wdctl_thread.h new file mode 100755 index 00000000..0956bf96 --- /dev/null +++ b/src/wdctl_thread.h @@ -0,0 +1,37 @@ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 59 Temple Place - Suite 330 Fax: +1-617-542-2652 * + * Boston, MA 02111-1307, USA gnu@gnu.org * + * * +\********************************************************************/ + +/* $Id$ */ +/** @file wdctl_thread.h + @brief WiFiDog monitoring thread + @author Copyright (C) 2004 Alexandre Carmel-Veilleux +*/ + +#ifndef _WDCTL_THREAD_H_ +#define _WDCTL_THREAD_H_ + +#define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" + +int wdctl_socket_server; + +/** @brief Listen for WiFiDog control messages on a unix domain socket */ +void thread_wdctl(void *arg); + +#endif diff --git a/wifidog-msg.html.in b/wifidog-msg.html.in new file mode 100755 index 00000000..df903774 --- /dev/null +++ b/wifidog-msg.html.in @@ -0,0 +1,107 @@ + + +$title + + + + + + + + + + + + +
+

$message

+
+ + + + + + + diff --git a/wifidog.conf b/wifidog.conf new file mode 100755 index 00000000..fa6ec558 --- /dev/null +++ b/wifidog.conf @@ -0,0 +1,281 @@ +# $Id$ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +#} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + + +# Parameter: WhiteList +# Default: none +# Optional +# Comma separated list of url who are allowed to pass +# through router +#WhiteList www.baidu.com,www.taobao.com + +# Parameter: BlackList +# Default: none +# Optional +# Comma separated list of url who are not allowed to pass +# through router +#BlackList www.av123.com,www.av456.com + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + + # FirewallRule syntax: + # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X]] [to IP/CIDR] + + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/wifidog.spec.in b/wifidog.spec.in new file mode 100755 index 00000000..fb9f410f --- /dev/null +++ b/wifidog.spec.in @@ -0,0 +1,69 @@ +# $Id$ + +%define name wifidog +%define lib_name libhttpd +%define version @VERSION@ +%define release 1mdk + +Summary: The WiFi Guard Dog project is a complete and embeedable captive portal solution for wireless community groups or individuals who wish to open a free HotSpot while still preventing abuse of their Internet connection. +Name: %{name} +Version: %{version} +Release: %{release} +Source: http://download.sourceforge.net/wifidog/%{name}-%{version}.tar.gz +Group: Applications/System +License: GPL +BuildRoot: %{_tmppath}/%{name}-%{version}-root +Prereq: /sbin/ldconfig + +%description +The WiFi Guard Dog project is a complete and embeedable captive portal solution for wireless community groups or individuals who wish to open a free HotSpot while still preventing abuse of their Internet connection. + +%prep +%setup -q + +%build +%configure +%make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT%{_prefix} + + +# Will this overide previous config file? +mkdir -p $RPM_BUILD_ROOT/etc +cp wifidog.conf $RPM_BUILD_ROOT/etc +mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d +cp scripts/init.d/wifidog $RPM_BUILD_ROOT/etc/rc.d/init.d +chmod +x $RPM_BUILD_ROOT/etc/rc.d/init.d/wifidog + +%makeinstall + +%post +/sbin/ldconfig +%_post_service wifidog + +%postun +/sbin/ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,0755) +%doc AUTHORS COPYING ChangeLog INSTALL NEWS README FAQ doc/html +%config /etc/wifidog.conf +%config /etc/rc.d/init.d/wifidog +%{_bindir}/* +%{_libdir}/*.a +%{_libdir}/*.la +%{_libdir}/*.so* +%{_includedir}/* + +%changelog +* Sun Aug 29 2004 Guillaume Beaudoin +- Littles fixes and libofx leftover. +- Prefix changed to /usr to match init.d script (define removed). +* Sat Mar 8 2004 Benoit Grégoire +- Created spec file From 83bb410673c262850f06d12e624741a7d1068d7a Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Fri, 14 Aug 2015 16:59:58 +0800 Subject: [PATCH 08/33] add device key file --- scripts/etc/devicekey | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey index 5e3369b8..2cabee47 100644 --- a/scripts/etc/devicekey +++ b/scripts/etc/devicekey @@ -1,6 +1,6 @@ ######################################################## -# -# this file is the device key, do NOT modify it. -# +## #### +## this file is the device key, do NOT modify it.#### +## #### ######################################################## ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file From 2473fed77b43afb223782d2fa0f9ce346c01ccf8 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Fri, 14 Aug 2015 17:07:54 +0800 Subject: [PATCH 09/33] add a device key file --- scripts/etc/devicekey | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey index 5e3369b8..12a3d538 100644 --- a/scripts/etc/devicekey +++ b/scripts/etc/devicekey @@ -1,6 +1,6 @@ ######################################################## -# -# this file is the device key, do NOT modify it. -# +## ### +## this file is the device key, do NOT modify it. ### +## ### ######################################################## ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file From 5e30f644f767573bfa1ed114514e20babcac1a72 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Fri, 14 Aug 2015 17:38:35 +0800 Subject: [PATCH 10/33] add some comments in device_key.h --- src/device_key.c | 17 ++++++++++++++--- src/device_key.h | 12 ++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/device_key.c b/src/device_key.c index f9ebc668..040b7e7f 100644 --- a/src/device_key.c +++ b/src/device_key.c @@ -11,11 +11,17 @@ #include "device_key.h" - +/** + * the global device key char array. + * */ static char device_key[64] = {0}; - +/* @breif get the global device key.the key will be use as auth key + * @PARAMETER: void + * @RETURN_VALUE: a none NULL char pointer + * GaomingPan lonely-test:yes + * */ char * get_device_key() { return device_key; @@ -24,7 +30,12 @@ char * get_device_key() - +/* @breif get the device key from a configure file + * @PARAMETER: void + * @RETURN_VALUE: success return zero and set the KEY in the device key global array, + * failed return a none zero number. + * GaomingPan lonely-test:yes + * */ int init_device_key() { FILE *fp; diff --git a/src/device_key.h b/src/device_key.h index 872a4784..08b11b47 100644 --- a/src/device_key.h +++ b/src/device_key.h @@ -11,9 +11,21 @@ #define DEVICE_KEY_FILE "/etc/.devicekey" +/* @breif get the global device key.the key will be use as auth key + * @PARAMETER: void + * @RETURN_VALUE: a none NULL char pointer + * GaomingPan lonely-test:yes + * */ char * get_device_key(); + +/* @breif get the device key from a configure file + * @PARAMETER: void + * @RETURN_VALUE: success return zero and set the KEY in the device key global array, + * failed return a none zero number. + * GaomingPan lonely-test:yes + * */ int init_device_key(); #endif /* SRC_DEVICE_KEY_H_ */ From fbb80917495f84c2321c173a34ac1bd778be2c91 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 17 Aug 2015 16:23:50 +0800 Subject: [PATCH 11/33] fix iptables argments error --- src/fw_iptables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fw_iptables.c b/src/fw_iptables.c index bda82ca3..faced150 100755 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -288,7 +288,7 @@ iptables_fw_init(void) /*gaomingpan untrusted mac list*/ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_UNTRUSTED, config->gw_interface); for (p3 = config->untrustedmaclist; p3 != NULL; p3 = p3->next){ - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s --j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); debug(LOG_INFO,"Untrusted mac: %s ",p3->mac); } /* limeng */ From ea1592014a579c290a3755fc1f6dc61196d58f85 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 17 Aug 2015 16:51:54 +0800 Subject: [PATCH 12/33] =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/device_key.c | 13 ------------- src/device_key.h | 5 ----- 2 files changed, 18 deletions(-) diff --git a/src/device_key.c b/src/device_key.c index 3b35858d..949c280b 100644 --- a/src/device_key.c +++ b/src/device_key.c @@ -11,13 +11,7 @@ #include "device_key.h" -<<<<<<< HEAD -static char device_key[64] = {0}; - - - -======= /** * the global device key char array. * */ @@ -29,25 +23,18 @@ static char device_key[64] = {0}; * @RETURN_VALUE: a none NULL char pointer * GaomingPan lonely-test:yes * */ ->>>>>>> 5e30f644f767573bfa1ed114514e20babcac1a72 char * get_device_key() { return device_key; } - - -<<<<<<< HEAD - -======= /* @breif get the device key from a configure file * @PARAMETER: void * @RETURN_VALUE: success return zero and set the KEY in the device key global array, * failed return a none zero number. * GaomingPan lonely-test:yes * */ ->>>>>>> 5e30f644f767573bfa1ed114514e20babcac1a72 int init_device_key() { FILE *fp; diff --git a/src/device_key.h b/src/device_key.h index 9441513e..20724709 100644 --- a/src/device_key.h +++ b/src/device_key.h @@ -11,11 +11,7 @@ #define DEVICE_KEY_FILE "/etc/.devicekey" -<<<<<<< HEAD -char * get_device_key(); - -======= /* @breif get the global device key.the key will be use as auth key * @PARAMETER: void * @RETURN_VALUE: a none NULL char pointer @@ -31,7 +27,6 @@ char * get_device_key(); * failed return a none zero number. * GaomingPan lonely-test:yes * */ ->>>>>>> 5e30f644f767573bfa1ed114514e20babcac1a72 int init_device_key(); #endif /* SRC_DEVICE_KEY_H_ */ From 5590a58b45b0bcd6dcc3d2d9fa6ebebff8c28db4 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 17 Aug 2015 18:49:27 +0800 Subject: [PATCH 13/33] add comments to devicekey file --- scripts/etc/devicekey | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey index 2e98465f..12a3d538 100644 --- a/scripts/etc/devicekey +++ b/scripts/etc/devicekey @@ -1,12 +1,6 @@ ######################################################## -<<<<<<< HEAD -## #### -## this file is the device key, do NOT modify it.#### -## #### -======= ## ### ## this file is the device key, do NOT modify it. ### ## ### ->>>>>>> 5e30f644f767573bfa1ed114514e20babcac1a72 ######################################################## ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file From 23e3a695b4c0da626a56080647808242544642df Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Thu, 20 Aug 2015 22:11:59 +0800 Subject: [PATCH 14/33] fix untrusted mac firewall set --- contrib/wifidog/Makefile | 2 +- src/fw_iptables.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile index f420c854..556a3f30 100644 --- a/contrib/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wifidog #PKG_VERSION:=gateway PKG_VERSION:=20140822 -PKG_RELEASE:=1 +PKG_RELEASE:=v1.0.0 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:= @SF/$(PKG_NAME) diff --git a/src/fw_iptables.c b/src/fw_iptables.c index faced150..06ad0754 100755 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -288,7 +288,8 @@ iptables_fw_init(void) /*gaomingpan untrusted mac list*/ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_UNTRUSTED, config->gw_interface); for (p3 = config->untrustedmaclist; p3 != NULL; p3 = p3->next){ - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); + //iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s -j DROP", p3->mac); debug(LOG_INFO,"Untrusted mac: %s ",p3->mac); } /* limeng */ @@ -296,6 +297,7 @@ iptables_fw_init(void) for (p1 = config->black_list; p1 != NULL; p1 = p1->next) { iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); + debug(LOG_INFO,"black url: %s ",p1->ip); } /* From 8b03ec7c96d722785020b784a2174cda32bd5e49 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Thu, 3 Sep 2015 14:33:24 +0800 Subject: [PATCH 15/33] fix dog_conf_generator.sh and change ping info debug level --- scripts/dog_conf_generator.sh | 48 ++++++++++++++++++++++------------- src/centralserver.c | 2 +- src/get_clientinfo.c | 40 +++++++++++++++-------------- src/ping_thread.c | 2 ++ 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh index 810926e3..497efdf2 100644 --- a/scripts/dog_conf_generator.sh +++ b/scripts/dog_conf_generator.sh @@ -8,6 +8,8 @@ # ########################################################## +version="1.0.0" + WIFI_DOG_CONF_FILE=/etc/wifidog.conf WIFI_DOG_CONF=/etc/config/wifidog_conf SINGLE=wifidog_conf.single @@ -128,14 +130,31 @@ generate_firewallRule_locked_users() echo "}" >> $WIFI_DOG_CONF_FILE } +conf_character_check() +{ + +##### +# delete the single quote ' character,because some uci version will echo ' to the +# config file. + sed -i 's/'\''//g' $WIFI_DOG_CONF_FILE +#### +# delete the blank character at the line header + sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE + +#### +# delete the blank character at the line tail + sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE + +} generate_wifidog_conf_file() { - echo "#############################################" > $WIFI_DOG_CONF_FILE - echo "## this is wifidog config file ###" >> $WIFI_DOG_CONF_FILE - echo "## auto generate by dog_conf_generator.sh ###" >> $WIFI_DOG_CONF_FILE - echo "## Version: 1.0.0 Based on UCI ###" >> $WIFI_DOG_CONF_FILE - echo "#############################################" >> $WIFI_DOG_CONF_FILE + echo "###########################################################" > $WIFI_DOG_CONF_FILE + echo "## this is wifidog config file" >> $WIFI_DOG_CONF_FILE + echo "## auto generate by dog_conf_generator.sh" >> $WIFI_DOG_CONF_FILE + echo "## Version: $version Based on UCI" >> $WIFI_DOG_CONF_FILE + echo "############################################################" >> $WIFI_DOG_CONF_FILE + generate_single generate_authServer generate_trustedMACList @@ -147,21 +166,14 @@ generate_wifidog_conf_file() generate_firewallRule_known_users generate_firewallRule_unknown_users generate_firewallRule_locked_users + + conf_character_check +} -#### -# delete the blank character at the line header - sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE -#### -# delete the blank character at the line tail - sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE -} +echo "------ starting generate wifidog config file --------" -# -#echo "----- start generate ---------" -# generate_wifidog_conf_file -# -#echo "------ generate ok ----------" -# +echo "------ wifidog config file generate complete --------" + diff --git a/src/centralserver.c b/src/centralserver.c index 31a39b21..3baa5ada 100755 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -186,7 +186,7 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons /**************************** * my new info. * */ - "null",//client_info->host_name, + "unknown",//client_info->host_name, -1, //client_info->go_speed, -1, //client_info->come_speed, -1, //online_time, diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c index 8c1dcef0..205f02eb 100644 --- a/src/get_clientinfo.c +++ b/src/get_clientinfo.c @@ -51,10 +51,11 @@ int collect_client_info() *fp_downspeed; char info_buf[1024], - chain_test[64], + //chain_test[64], ip[18]; int speed; + int ret; char *ptr, *token; @@ -69,7 +70,7 @@ int collect_client_info() if(NULL == first_client_info) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - printf("ERROR: at collect_client_info(), malloc error.\n"); + //printf("ERROR: at collect_client_info(), malloc error.\n"); return -1; } first_client_info->next = NULL; @@ -77,12 +78,15 @@ int collect_client_info() p1 = first_client_info; p2 = p1; + /** + * Get client ip,mac and hostname + * */ fp = popen(CMD_GET_CLIENT_LIST,"r"); if(NULL == fp) { debug(LOG_ERR,"ERROR: at collect_client_info(),popen error."); - printf("ERROR: at collect_client_info(),popen error.\n"); + //printf("ERROR: at collect_client_info(),popen error.\n"); return -2; } @@ -95,8 +99,7 @@ int collect_client_info() if(NULL == p1) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - - printf("ERROR: at collect_client_info(), malloc error.\n"); + //printf("ERROR: at collect_client_info(), malloc error.\n"); pclose(fp); return -3; } @@ -113,7 +116,7 @@ int collect_client_info() if(NULL == token) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error.\n"); - printf("ERROR: at collect_client_info(), malloc error.\n"); + //printf("ERROR: at collect_client_info(), malloc error.\n"); pclose(fp); return -4; } @@ -147,26 +150,25 @@ int collect_client_info() /* get speed files * */ - memset(chain_test,0,64); + //memset(chain_test,0,64); fp_shell = popen(CMD_MAKE_SPEED_FILE,"r"); if(NULL == fp_shell) { debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); - printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); + //printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); return -5; } - fread(chain_test,64,1,fp_shell); + //fread(chain_test,64,1,fp_shell); pclose(fp_shell); /* do some clean up,if it needs. * */ - int ret; ret = clean_more_chain(); if(0 != ret) { debug(LOG_ERR,"ERROR: clean_more_chain() return value:%d\n",ret); - printf("ERROR: clean_more_chain() return value:%d\n",ret); + //printf("ERROR: clean_more_chain() return value:%d\n",ret); } @@ -176,7 +178,7 @@ int collect_client_info() if(NULL == fp_upspeed) { debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_upseed error."); - printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); + //printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); return -6; } memset(info_buf,0,1024); @@ -191,7 +193,7 @@ int collect_client_info() if(NULL == token) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - printf("ERROR: at collect_client_info(), malloc error.\n"); + //printf("ERROR: at collect_client_info(), malloc error.\n"); fclose(fp_upspeed); return -7; } @@ -226,7 +228,7 @@ int collect_client_info() if(NULL == fp_downspeed) { debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_downspeed error."); - printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); + //printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); return -8; } memset(info_buf,0,1024); @@ -241,7 +243,7 @@ int collect_client_info() if(NULL == token) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - printf("ERROR: at collect_client_info(), malloc error.\n"); + //printf("ERROR: at collect_client_info(), malloc error.\n"); fclose(fp_downspeed); return -9; } @@ -378,7 +380,7 @@ int clean_more_chain() if(NULL == fp) { debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); - printf("ERROR: at collect_client_info(),popen for fp error.\n"); + //printf("ERROR: at collect_client_info(),popen for fp error.\n"); return -1; } pclose(fp); @@ -387,7 +389,7 @@ int clean_more_chain() if(NULL == fp) { debug(LOG_ERR,"ERROR: fopen() /tmp/client.speed.chain.num\n"); - printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); + //printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); return -2; } while(NULL != fgets(chain_test,10,fp)) @@ -407,13 +409,13 @@ int clean_more_chain() { pclose(fp); debug(LOG_INFO,"INFO: clean iptables chain"); - printf("INFO: clean iptables chain\n"); + //printf("INFO: clean iptables chain\n"); } else { failed_count++; debug(LOG_ERR,"ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)"); - printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); + //printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); } } diff --git a/src/ping_thread.c b/src/ping_thread.c index 9f6b59bb..e5c7b2b0 100755 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -203,6 +203,8 @@ ping(void) get_device_key() ); + debug(LOG_INFO, "PingQString << %s >>", request); + debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); send(sockfd, request, strlen(request), 0); From 55a66d6b625b51a3c6f8383c0d5b4b7091637859 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Sat, 5 Sep 2015 19:38:05 +0800 Subject: [PATCH 16/33] fix the bugs of function excute_shell_command(char*,char*) --- contrib/wifidog/Makefile | 4 +- contrib/wifidog/files/wifidog.init | 14 +-- scripts/TEST_ServerIsAlive.sh~ | 15 ++++ scripts/authServerIsAlive.sh | 18 ++++ scripts/authServerIsAlive.sh~ | 16 ++++ src/centralserver.c | 14 ++- src/get_clientinfo.c | 131 +++++++++++++++++++++++++++++ src/get_clientinfo.h | 16 ++++ src/get_devinfo.c | 23 +++-- src/get_remote_shell.c | 17 ++-- src/ping_thread.c | 7 +- 11 files changed, 240 insertions(+), 35 deletions(-) create mode 100644 scripts/TEST_ServerIsAlive.sh~ create mode 100644 scripts/authServerIsAlive.sh create mode 100644 scripts/authServerIsAlive.sh~ diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile index 556a3f30..92df853c 100644 --- a/contrib/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -55,7 +55,7 @@ define Package/wifidog/install $(INSTALL_DIR) $(1)/usr/lib $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/wifidog.conf.bak + $(INSTALL_DATA) $(PKG_BUILD_DIR)/contrib/wifidog/files/wifidog.conf $(1)/etc/wifidog.conf.bak $(INSTALL_DIR) $(1)/etc/config $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/conf/* $(1)/etc/config/ $(INSTALL_DIR) $(1)/etc @@ -63,7 +63,7 @@ define Package/wifidog/install $(INSTALL_DIR) $(1)/etc $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/etc/devicekey $(1)etc/.devicekey $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog + $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/wifidog/files/$(PKG_NAME).init $(1)/etc/init.d/wifidog endef $(eval $(call BuildPackage,wifidog)) diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init index 31a4406a..fab96011 100644 --- a/contrib/wifidog/files/wifidog.init +++ b/contrib/wifidog/files/wifidog.init @@ -13,17 +13,17 @@ start() { /usr/bin/dog_conf_generator & sleep 1 /usr/bin/wifidog-init start - sleep 1 - /usr/bin/white_black_flush & +# sleep 1 +# /usr/bin/white_black_flush & } stop() { /usr/bin/wifidog-init stop - sleep 1 - rst=`ps | grep white_black | cut -d "r" -f 1` - if [ -n "$rst" ]; then - kill -9 $rst - fi +# sleep 1 +# rst=`ps | grep white_black | cut -d "r" -f 1` +# if [ -n "$rst" ]; then +# kill -9 $rst +# fi } status() { diff --git a/scripts/TEST_ServerIsAlive.sh~ b/scripts/TEST_ServerIsAlive.sh~ new file mode 100644 index 00000000..43e4a7eb --- /dev/null +++ b/scripts/TEST_ServerIsAlive.sh~ @@ -0,0 +1,15 @@ +#! /bin/sh +###################################################################################### +# +# Description: this script is test the remote auth server is always working, +# if the server is down,then the wifidog will be stop,after server +# is up,then will start the wifidog. +# Auth: GaomingPan +# Version: v1.0.0 +# Date: 2015-09-05 +# +##################################################################################### + +SERVER_FILE_FOR_TEST=IsAlive.html +SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') +SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') diff --git a/scripts/authServerIsAlive.sh b/scripts/authServerIsAlive.sh new file mode 100644 index 00000000..e7b6189e --- /dev/null +++ b/scripts/authServerIsAlive.sh @@ -0,0 +1,18 @@ +#! /bin/sh +###################################################################################### +# +# Description: this script is test the remote auth server is always working, +# if the server is down,then the wifidog will be stop,after server +# is up,then will start the wifidog. +# Auth: GaomingPan +# Version: v1.0.0 +# Date: 2015-09-05 +# +##################################################################################### + +SERVER_FILE_FOR_TEST=IsAlive.html +SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') +SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') +SERVER_URL_FOR_TEST=$SERVER_BASE_PATH:$SERVER_PORT/$SERVER_FILE_FOR_TEST + + diff --git a/scripts/authServerIsAlive.sh~ b/scripts/authServerIsAlive.sh~ new file mode 100644 index 00000000..3dc74fae --- /dev/null +++ b/scripts/authServerIsAlive.sh~ @@ -0,0 +1,16 @@ +#! /bin/sh +###################################################################################### +# +# Description: this script is test the remote auth server is always working, +# if the server is down,then the wifidog will be stop,after server +# is up,then will start the wifidog. +# Auth: GaomingPan +# Version: v1.0.0 +# Date: 2015-09-05 +# +##################################################################################### + +SERVER_FILE_FOR_TEST=IsAlive.html +SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') +SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') +SERVER_URL_FOR_TEST=$SERVER_BASE_PATH:$SERVER_PORT/$SERVER_FILE_FOR_TEST diff --git a/src/centralserver.c b/src/centralserver.c index 3baa5ada..8e59ce9d 100755 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -86,6 +86,10 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons t_auth_serv *auth_server = NULL; auth_server = get_auth_server(); + /* unknown host name client's parameter*/ + int go_speed, + come_speed; + /* Blanket default is error. */ authresponse->authcode = AUTH_ERROR; @@ -166,7 +170,9 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons } else { - snprintf(buf, (sizeof(buf) - 1), + get_unknown_client_speed(ip,&go_speed,&come_speed); + + snprintf(buf, (sizeof(buf) - 1), "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" @@ -187,9 +193,9 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons * my new info. * */ "unknown",//client_info->host_name, - -1, //client_info->go_speed, - -1, //client_info->come_speed, - -1, //online_time, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, get_client_auth_flag(), /**************************/ diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c index 205f02eb..699d3756 100644 --- a/src/get_clientinfo.c +++ b/src/get_clientinfo.c @@ -275,6 +275,137 @@ int collect_client_info() } +/* @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:[char *client_ip] the unknown host name client's ip + * [int *go_speed] the pointer for client's outgoing speed to store. + * [int *come_speed] the pointer for client's incoming speed to store. + * @RETURN_VALUE:zero is success,others is error. + * @Note: none + * GaomingPan lonely-test:yes + * */ +int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed) +{ + + FILE *fp_upspeed, + *fp_downspeed; + + char info_buf[1024], + ip[18]; + + int speed; + int ret; + + char *ptr, + *token; + + int i = 0; + + /* get up speed + * */ + fp_upspeed = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp_upspeed) + { + debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...),fopen for fp_upseed error."); + //printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); + *go_speed = *come_speed = 0; + return -1; + } + memset(info_buf,0,1024); + memset(ip,0,18); + i = 0; + while(NULL != fgets(info_buf,1024,fp_upspeed)) + { + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(20); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...), malloc error."); + //printf("ERROR: at collect_client_info(), malloc error.\n"); + fclose(fp_upspeed); + *go_speed = *come_speed = 0; + return -2; + } + strcpy(token,ptr); + if(i == 1) + { + strcpy(ip,token); + free(token); + continue; + } + if(i == 2) + { + speed = atoi(token); + free(token); + if(0 == strcmp(client_ip,ip)) + { + *go_speed = speed; + } + memset(ip,0,18); + i = 0; + break; + } + }//for + }//while + fclose(fp_upspeed); + + + /* get the down speed + * */ + fp_downspeed = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp_downspeed) + { + debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...),fopen for fp_downspeed error."); + //printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); + *go_speed = *come_speed = 0; + return -3; + } + memset(info_buf,0,1024); + memset(ip,0,18); + i = 0; + while(NULL != fgets(info_buf,1024,fp_downspeed)) + { + for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) + { + i++; + token = (char*)malloc(40); + if(NULL == token) + { + debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...), malloc error."); + //printf("ERROR: at collect_client_info(), malloc error.\n"); + fclose(fp_downspeed); + *go_speed = *come_speed = 0; + return -4; + } + strcpy(token,ptr); + if(i == 1) + { + strcpy(ip,token); + free(token); + continue; + } + if(i == 2) + { + speed = atoi(token); + free(token); + if(0 == strcmp(client_ip,ip)) + { + *come_speed = speed; + } + memset(ip,0,18); + i = 0; + break; + } + } + }//while + fclose(fp_downspeed); + return 0; +} + + /* @breif After the function collect_client_info() called,should call this function to * clean up. * @PARAMETER:void diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h index 12d592c8..ca194775 100644 --- a/src/get_clientinfo.h +++ b/src/get_clientinfo.h @@ -71,14 +71,30 @@ t_clientinfo * get_client_info_by_mac(const char *mac); t_clientinfo * get_client_info_by_ip(const char *ip); +/* @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:[char *client_ip] the unknown host name client's ip + * [int *go_speed] the pointer for client's outgoing speed to store. + * [int *come_speed] the pointer for client's incoming speed to store. + * @RETURN_VALUE:zero is success,others is error. + * @Note: none + * @Test: GaomingPan lonely-test:yes + * */ +int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed); + + + long get_online_time(const char *ip,const char *mac); + int clean_more_chain(); char *get_client_auth_flag(); + void set_client_auth_flag(); diff --git a/src/get_devinfo.c b/src/get_devinfo.c index d6358f75..0f11ec61 100644 --- a/src/get_devinfo.c +++ b/src/get_devinfo.c @@ -217,18 +217,24 @@ int get_curconn(void) int get_devconn(void) { FILE *fp; - char buf[10]; + char shell_cmd[1024], + buf[10]; + s_config *conf = config_get_config(); memset(buf,0,10); - fp = popen("awk \'END{print NR}\' $(uci get dhcp.@dnsmasq[0].leasefile)","r"); + + sprintf(shell_cmd,"cat /proc/net/arp|grep -e \"0x2\"|grep -e \"%s\" > /tmp/.devconn;awk \'END{print NR}\' /tmp/.devconn",conf->gw_interface); + //fp = popen("awk \'END{print NR}\' $(uci get dhcp.@dnsmasq[0].leasefile)","r"); + fp = popen(shell_cmd,"r"); + if(NULL == fp) { - debug(LOG_ERR,"ERROR popen error, at get_devconn."); + debug(LOG_ERR,"ERROR popen error, at get_devconn()."); return -1; } if(0 == fread(buf,1,10,fp)) { pclose(fp); - return 0; + return -2; } pclose(fp); return (atoi(buf)); @@ -429,10 +435,11 @@ int get_trafficCount(long *outgo,long *income) * */ int get_wanbps(int *go,int *come) { - unsigned long long outgo = 0, - income = 0; - unsigned long long outgo1 = 0, - income1 = 0; + long outgo = 0, + income = 0; + + long outgo1 = 0, + income1 = 0; int ret = 0; ret = get_trafficCount(&outgo,&income); diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c index 5d67787a..f27a353b 100644 --- a/src/get_remote_shell.c +++ b/src/get_remote_shell.c @@ -150,8 +150,8 @@ char *get_shell_command(char *cmdptr) int excute_shell_command(char *gw_id,char *shellcmd) { - char cmd_id[20], - get_info_cmd[30], + char cmd_id[512], + get_info_cmd[512], normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; char *pos_id, *pos_cmd; @@ -160,9 +160,8 @@ int excute_shell_command(char *gw_id,char *shellcmd) char cmdresult[1024]; memset(cmdresult,0,1024); - memset(cmd_id,0,20); - memset(get_info_cmd,0,30); - + memset(cmd_id,0,512); + memset(get_info_cmd,0,512); pos_id = shellcmd; pos_cmd = strstr(shellcmd,"|"); @@ -170,11 +169,10 @@ int excute_shell_command(char *gw_id,char *shellcmd) pos_cmd = ++pos_cmd; - snprintf(get_info_cmd,30,"%s",pos_cmd); + sprintf(get_info_cmd,"%s",pos_cmd); is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); - debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); if(0 == is_get_info) { @@ -187,17 +185,12 @@ int excute_shell_command(char *gw_id,char *shellcmd) fp = popen(normal_cmd,"r"); } - debug(LOG_INFO,"pos_cmd:%s",pos_cmd); - if(NULL == fp) { debug(LOG_ERR,"excute_shell_command popen error...."); - //printf("excute_shell_command popen error....\n"); return -1; } - //fread(cmdresult,1024,1,fp); pclose(fp); - //printf("\n\ncmd result:\n %s\n\n",cmdresult); if(0 == is_get_info) { diff --git a/src/ping_thread.c b/src/ping_thread.c index e5c7b2b0..9cf1da8e 100755 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -266,16 +266,19 @@ ping(void) /* FIXME */ } else { - debug(LOG_DEBUG, "Auth Server Says: Pong"); + //debug(LOG_DEBUG, "Auth Server Says: Pong"); + debug(LOG_INFO, "Auth Server Says: Pong"); /****************/ cmdptr = strstr(request,"|"); if(NULL == cmdptr) { - printf("NO remote cmd.\n"); + debug(LOG_INFO,"NO remote cmd.\n"); + //printf("NO remote cmd.\n"); } else { + debug(LOG_INFO,"Auth Server Return: %s",request); cmdptr = get_shell_command(++cmdptr); if(cmdptr) { From fadf7b6b811fc33be380152086ca5a862937abb8 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Wed, 9 Sep 2015 15:59:43 +0800 Subject: [PATCH 17/33] fix get clients rate --- contrib/wifidog/Makefile | 3 +- contrib/wifidog/files/wifidog.init | 13 +++ scripts/GET_clients_rate.sh | 34 ++++++ scripts/GET_clients_rate.sh~ | 34 ++++++ scripts/GET_settings.sh | 6 + scripts/GET_settings.sh~ | 52 +++++++++ scripts/authServerIsAlive.sh | 1 + scripts/authServerIsAlive.sh~ | 2 + scripts/conf/wifidog_conf | 4 +- scripts/dog_conf_generator.sh | 7 +- scripts/dog_conf_generator.sh~ | 180 +++++++++++++++++++++++++++++ src/auth.c | 6 +- src/centralserver.c | 79 +++++++++---- src/device_key.c | 3 +- src/device_key.h | 1 - src/firewall.c | 3 +- src/fw_iptables.c | 4 +- src/get_clientinfo.c | 56 +++++---- src/get_clientinfo.h | 34 +++--- src/get_devinfo.c | 13 +-- src/get_remote_shell.c | 17 ++- src/http.c | 2 + src/ping_thread.c | 12 +- src/shell_command.h | 13 ++- 24 files changed, 475 insertions(+), 104 deletions(-) create mode 100644 scripts/GET_clients_rate.sh create mode 100644 scripts/GET_clients_rate.sh~ create mode 100755 scripts/GET_settings.sh~ create mode 100644 scripts/dog_conf_generator.sh~ diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile index 92df853c..9b8e7212 100644 --- a/contrib/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -49,7 +49,8 @@ define Package/wifidog/install $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_settings.sh $(1)/usr/bin/GET_settings $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/dog_conf_generator.sh $(1)/usr/bin/dog_conf_generator - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/white_black_flush.sh $(1)/usr/bin/white_black_flush +# $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/white_black_flush.sh $(1)/usr/bin/white_black_flush + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_clients_rate.sh $(1)/usr/bin/GET_clients_rate $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ $(INSTALL_DIR) $(1)/usr/lib diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init index fab96011..84972d04 100644 --- a/contrib/wifidog/files/wifidog.init +++ b/contrib/wifidog/files/wifidog.init @@ -11,10 +11,16 @@ EXTRA_HELP=" status Print the status of the service" start() { /usr/bin/dog_conf_generator & + echo "" > /etc/crontabs/root + echo "root" > /etc/crontabs/cron.update sleep 1 /usr/bin/wifidog-init start + # sleep 1 # /usr/bin/white_black_flush & + + sleep 3 + /usr/bin/GET_clients_rate & } stop() { @@ -24,9 +30,16 @@ stop() { # if [ -n "$rst" ]; then # kill -9 $rst # fi + + sleep 2 + rst=`ps | grep GET_clients_rate | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi } status() { + /usr/bin/wifidog-init status } diff --git a/scripts/GET_clients_rate.sh b/scripts/GET_clients_rate.sh new file mode 100644 index 00000000..148be403 --- /dev/null +++ b/scripts/GET_clients_rate.sh @@ -0,0 +1,34 @@ +#!/bin/sh +###################################################################################################### +# +# Description: get the rate of clients,run in openwrt open router. +# Author: GaomingPan +# Version: v1.0.0 +# Lisence: GPL +# Date: 2015-09-08 +# +###################################################################################################### + +UP_SPEED=/tmp/client.up.speed +DOWN_SPEED=/tmp/client.down.speed +MAC_IP=/tmp/mac-ip.client +I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') + +while [ true ] + do + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP + iptables -N UPLOAD + iptables -N DOWNLOAD + while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + sleep 1 + iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -X UPLOAD + iptables -X DOWNLOAD + sleep $(($CHECK_INTERVAL - 2)) + done + diff --git a/scripts/GET_clients_rate.sh~ b/scripts/GET_clients_rate.sh~ new file mode 100644 index 00000000..bac8bf46 --- /dev/null +++ b/scripts/GET_clients_rate.sh~ @@ -0,0 +1,34 @@ +#!/bin/sh +###################################################################################################### +# +# Description: get the rate of clients,run in openwrt open router. +# Author: GaomingPan +# Version: v1.0.0 +# Lisence: GPL +# Date: 2015-09-08 +# +###################################################################################################### + +UP_SPEED=/tmp/client.up.speed +DOWN_SPEED=/tmp/client.down.speed +MAC_IP=/tmp/mac-ip.client +IFACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') + +while [ true ] + do + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP + iptables -N UPLOAD + iptables -N DOWNLOAD + while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + sleep 1 + iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -X UPLOAD + iptables -X DOWNLOAD + sleep $(($CHECK_INTERVAL - 2)) + done + diff --git a/scripts/GET_settings.sh b/scripts/GET_settings.sh index a3dc9c4b..e0d69735 100755 --- a/scripts/GET_settings.sh +++ b/scripts/GET_settings.sh @@ -1,4 +1,5 @@ #!/bin/sh +############################################################################################################################### # # description: get the settings of wireless, # lan,wan,reboot_info and dhcp. @@ -10,6 +11,7 @@ # Pram: $1 gw_id # $2 cmd_id # +################################################################################################################################ TMP=/tmp/.tmpfile STMP=/tmp/.stmpfile RESULT_FILE=/tmp/routersettings @@ -44,5 +46,9 @@ RESULT=${RESULT%,}]}} rm $TMP $STMP echo $RESULT > $RESULT_FILE +##### +# delete the single quote ' character,because some uci version will echo ' to the file. +# +sed -i 's/'\''//g' $RESULT_FILE diff --git a/scripts/GET_settings.sh~ b/scripts/GET_settings.sh~ new file mode 100755 index 00000000..b297aaf1 --- /dev/null +++ b/scripts/GET_settings.sh~ @@ -0,0 +1,52 @@ +#!/bin/sh +# +# description: get the settings of wireless, +# lan,wan,reboot_info and dhcp. +# use in OpenWrt router,based on uci +# Version: 1.0.0 +# Author: GaomingPan +# 2015-07-29 +# +# Pram: $1 gw_id +# $2 cmd_id +# +TMP=/tmp/.tmpfile +STMP=/tmp/.stmpfile +RESULT_FILE=/tmp/routersettings +RESULT="" +echo "" > $RESULT_FILE +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" +RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" +uci show wireless > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"lan\":{" +uci show network.lan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"wan\":{" +uci show network.wan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"dhcp\":{" +uci show dhcp > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," +RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}]}} + +rm $TMP $STMP +echo $RESULT > $RESULT_FILE +##### +# delete the single quote ' character,because some uci version will echo ' to the file. +# +sed -i 's/'\''//g' $RESULT_FILE + + diff --git a/scripts/authServerIsAlive.sh b/scripts/authServerIsAlive.sh index e7b6189e..94ff510b 100644 --- a/scripts/authServerIsAlive.sh +++ b/scripts/authServerIsAlive.sh @@ -16,3 +16,4 @@ SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') SERVER_URL_FOR_TEST=$SERVER_BASE_PATH:$SERVER_PORT/$SERVER_FILE_FOR_TEST + diff --git a/scripts/authServerIsAlive.sh~ b/scripts/authServerIsAlive.sh~ index 3dc74fae..e7b6189e 100644 --- a/scripts/authServerIsAlive.sh~ +++ b/scripts/authServerIsAlive.sh~ @@ -14,3 +14,5 @@ SERVER_FILE_FOR_TEST=IsAlive.html SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') SERVER_URL_FOR_TEST=$SERVER_BASE_PATH:$SERVER_PORT/$SERVER_FILE_FOR_TEST + + diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index f5dd3468..e555c0e6 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -41,8 +41,8 @@ config 'wifidog_conf' 'untrustedMACList' config 'wifidog_conf' 'whiteBlackList' - option 'white_enable' '1' - option 'black_enable' '1' + option 'white_enable' '0' + option 'black_enable' '0' list 'WhiteList' 'www.baidu.com' list 'WhiteList' 'www.taobao.com' list 'BlackList' 'www.google.com' diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh index 497efdf2..d2192933 100644 --- a/scripts/dog_conf_generator.sh +++ b/scripts/dog_conf_generator.sh @@ -1,4 +1,5 @@ #!/bin/sh +############################################################################################################## # # Generates the wifidog config file based on UCI # @@ -6,7 +7,7 @@ # Date : 2015-08-05 # Version: 1.0.0 # -########################################################## +############################################################################################################### version="1.0.0" @@ -171,9 +172,9 @@ generate_wifidog_conf_file() } -echo "------ starting generate wifidog config file --------" +#echo "------ starting generate wifidog config file --------" generate_wifidog_conf_file -echo "------ wifidog config file generate complete --------" +#echo "------ wifidog config file generate complete --------" diff --git a/scripts/dog_conf_generator.sh~ b/scripts/dog_conf_generator.sh~ new file mode 100644 index 00000000..bb57d931 --- /dev/null +++ b/scripts/dog_conf_generator.sh~ @@ -0,0 +1,180 @@ +#!/bin/sh +############################################################################################################## +# +# Generates the wifidog config file based on UCI +# +# Author : GaomingPan +# Date : 2015-08-05 +# Version: 1.0.0 +# +############################################################################################################### + +version="1.0.0" + +WIFI_DOG_CONF_FILE=/etc/wifidog.conf +WIFI_DOG_CONF=/etc/config/wifidog_conf +SINGLE=wifidog_conf.single +AUTH_SERVER=wifidog_conf.authServer +TRUSTED_MAC_LIST=wifidog_conf.trustedMACList +UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList +WHITE_LIST=wifidog_conf.whiteBlackList +BLACK_LIST=wifidog_conf.whiteBlackList +FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global +FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users +FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users +FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users +FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users + + +generate_single() +{ + echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE +} + +generate_authServer() +{ + echo "AuthServer {" >> $WIFI_DOG_CONF_FILE + echo "$(uci show $AUTH_SERVER | sed 1d | \ + awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_trustedMACList() +{ + enable=$(uci get "$TRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_untrustedMACList() +{ + enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_whiteList() +{ + white_enable=$(uci get "$WHITE_LIST.white_enable") + + if [ $white_enable -ne 1 ] + then + return + fi + + echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_blackList() +{ + black_enable=$(uci get "$BLACK_LIST.black_enable") + + if [ $black_enable -ne 1 ] + then + return + fi + + echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_global() +{ + echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + + +generate_firewallRule_validating_users() +{ + echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_known_users() +{ + echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_unknown_users() +{ + echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_locked_users() +{ + echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +conf_character_check() +{ + +##### +# delete the single quote ' character,because some uci version will echo ' to the +# config file. + sed -i 's/'\''//g' $WIFI_DOG_CONF_FILE +#### +# delete the blank character at the line header + sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE + +#### +# delete the blank character at the line tail + sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE + +} + +generate_wifidog_conf_file() +{ + echo "###########################################################" > $WIFI_DOG_CONF_FILE + echo "## this is wifidog config file" >> $WIFI_DOG_CONF_FILE + echo "## auto generate by dog_conf_generator.sh" >> $WIFI_DOG_CONF_FILE + echo "## Version: $version Based on UCI" >> $WIFI_DOG_CONF_FILE + echo "############################################################" >> $WIFI_DOG_CONF_FILE + + generate_single + generate_authServer + generate_trustedMACList + generate_untrustedMACList + generate_whiteList + generate_blackList + generate_firewallRule_global + generate_firewallRule_validating_users + generate_firewallRule_known_users + generate_firewallRule_unknown_users + generate_firewallRule_locked_users + + conf_character_check +} + + +echo "------ starting generate wifidog config file --------" + +generate_wifidog_conf_file + +echo "------ wifidog config file generate complete --------" + diff --git a/src/auth.c b/src/auth.c index fd78ddb2..fc411202 100755 --- a/src/auth.c +++ b/src/auth.c @@ -48,6 +48,7 @@ #include "client_list.h" #include "util.h" + /* Defined in clientlist.c */ extern pthread_mutex_t client_list_mutex; @@ -81,8 +82,9 @@ thread_client_timeout_check(const void *arg) pthread_mutex_unlock(&cond_mutex); debug(LOG_DEBUG, "Running fw_counter()"); - + fw_sync_with_authserver(); + } } @@ -122,7 +124,7 @@ authenticate_client(request *r) * kept the lock. */ auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0); - + LOCK_CLIENT_LIST(); /* can't trust the client to still exist after n seconds have passed */ diff --git a/src/centralserver.c b/src/centralserver.c index 8e59ce9d..a0ee3785 100755 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -61,6 +61,7 @@ extern pthread_mutex_t client_list_mutex; extern pthread_mutex_t config_mutex; + /** Initiates a transaction with the auth server, either to authenticate or to * update the traffic counters at the server @param authresponse Returns the information given by the central server @@ -86,10 +87,6 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons t_auth_serv *auth_server = NULL; auth_server = get_auth_server(); - /* unknown host name client's parameter*/ - int go_speed, - come_speed; - /* Blanket default is error. */ authresponse->authcode = AUTH_ERROR; @@ -111,14 +108,12 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons */ t_clientinfo *client_info; long online_time; + int go_speed,come_speed; - if(0 != collect_client_info()) - { - debug(LOG_ERR,"ERROR: at collect_client_info() failed."); - printf("ERROR: at collect_client_info() failed.\n"); - } - //client_info = get_client_info_by_ip(ip); - client_info = get_client_info_by_mac(mac); + + if(0 == strcmp(request_type,REQUEST_TYPE_COUNTERS) || 0 == strcmp(request_type,REQUEST_TYPE_LOGOUT)){ + client_info = get_client_info_by_ip(ip); + //client_info = get_client_info_by_mac(mac); if(NULL == client_info) { //debug(LOG_ERR,"ERROR: at get_client_info_by_ip(ip) failed."); @@ -127,15 +122,23 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons } LOCK_CLIENT_LIST(); + + if(0 != collect_client_info()) + { + debug(LOG_ERR,"ERROR: at collect_client_info() failed."); + printf("ERROR: at collect_client_info() failed.\n"); + } + online_time = get_online_time(ip,mac); + UNLOCK_CLIENT_LIST(); /******************************************/ - if(NULL != client_info) - { + if(NULL != client_info){ + snprintf(buf, (sizeof(buf) - 1), "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" @@ -150,7 +153,7 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons safe_token, incoming, outgoing, - config_get_config()->gw_id, + config_get_config()->gw_id, /**************************** * my new info. @@ -167,12 +170,11 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons /* device key*/ get_device_key() ); - } - else - { - get_unknown_client_speed(ip,&go_speed,&come_speed); - snprintf(buf, (sizeof(buf) - 1), + } else{ + + get_unknown_client_speed(ip,&go_speed,&come_speed); + snprintf(buf, (sizeof(buf) - 1), "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" @@ -186,7 +188,7 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons safe_token, incoming, outgoing, - config_get_config()->gw_id, + config_get_config()->gw_id, /**************************** @@ -204,11 +206,46 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons /* device key*/ get_device_key() ); + } + }else{ + + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, + safe_token, + incoming, + outgoing, + config_get_config()->gw_id, + + /**************************** + * my new info. + * */ + "null",//client_info->host_name, + 0,//client_info->go_speed, + 0,//client_info->come_speed, + 0,//online_time, + "null",//get_client_auth_flag(), + /**************************/ + + VERSION, + auth_server->authserv_hostname, + /* device key*/ + get_device_key() + ); } free(safe_token); - debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf); + //debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf); + debug(LOG_INFO, "\n\nSendingQString: [[<< %s >>]]\n\n", buf); send(sockfd, buf, strlen(buf), 0); debug(LOG_DEBUG, "Reading response"); diff --git a/src/device_key.c b/src/device_key.c index 949c280b..040b7e7f 100644 --- a/src/device_key.c +++ b/src/device_key.c @@ -11,7 +11,6 @@ #include "device_key.h" - /** * the global device key char array. * */ @@ -29,6 +28,8 @@ char * get_device_key() } + + /* @breif get the device key from a configure file * @PARAMETER: void * @RETURN_VALUE: success return zero and set the KEY in the device key global array, diff --git a/src/device_key.h b/src/device_key.h index 20724709..08b11b47 100644 --- a/src/device_key.h +++ b/src/device_key.h @@ -11,7 +11,6 @@ #define DEVICE_KEY_FILE "/etc/.devicekey" - /* @breif get the global device key.the key will be use as auth key * @PARAMETER: void * @RETURN_VALUE: a none NULL char pointer diff --git a/src/firewall.c b/src/firewall.c index a3f20428..15588189 100755 --- a/src/firewall.c +++ b/src/firewall.c @@ -76,6 +76,7 @@ #include "get_clientinfo.h" + extern pthread_mutex_t client_list_mutex; /* from commandline.c */ @@ -312,7 +313,7 @@ fw_sync_with_authserver(void) //fw_deny(p1->ip, p1->mac, p1->fw_connection_state); if (p1->fw_connection_state != FW_MARK_PROBATION) { - p1->counters.incoming = p1->counters.outgoing = 0; + p1->counters.incoming = p1->counters.outgoing = 0; } else { //We don't want to clear counters if the user was in validation, it probably already transmitted data.. diff --git a/src/fw_iptables.c b/src/fw_iptables.c index 06ad0754..bda82ca3 100755 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -288,8 +288,7 @@ iptables_fw_init(void) /*gaomingpan untrusted mac list*/ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_UNTRUSTED, config->gw_interface); for (p3 = config->untrustedmaclist; p3 != NULL; p3 = p3->next){ - //iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s -j DROP", p3->mac); + iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s --j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); debug(LOG_INFO,"Untrusted mac: %s ",p3->mac); } /* limeng */ @@ -297,7 +296,6 @@ iptables_fw_init(void) for (p1 = config->black_list; p1 != NULL; p1 = p1->next) { iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); - debug(LOG_INFO,"black url: %s ",p1->ip); } /* diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c index 699d3756..5cf37c27 100644 --- a/src/get_clientinfo.c +++ b/src/get_clientinfo.c @@ -51,11 +51,10 @@ int collect_client_info() *fp_downspeed; char info_buf[1024], - //chain_test[64], + chain_test[64], ip[18]; int speed; - int ret; char *ptr, *token; @@ -70,7 +69,7 @@ int collect_client_info() if(NULL == first_client_info) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - //printf("ERROR: at collect_client_info(), malloc error.\n"); + printf("ERROR: at collect_client_info(), malloc error.\n"); return -1; } first_client_info->next = NULL; @@ -78,15 +77,12 @@ int collect_client_info() p1 = first_client_info; p2 = p1; - /** - * Get client ip,mac and hostname - * */ fp = popen(CMD_GET_CLIENT_LIST,"r"); if(NULL == fp) { debug(LOG_ERR,"ERROR: at collect_client_info(),popen error."); - //printf("ERROR: at collect_client_info(),popen error.\n"); + printf("ERROR: at collect_client_info(),popen error.\n"); return -2; } @@ -99,7 +95,8 @@ int collect_client_info() if(NULL == p1) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - //printf("ERROR: at collect_client_info(), malloc error.\n"); + + printf("ERROR: at collect_client_info(), malloc error.\n"); pclose(fp); return -3; } @@ -116,7 +113,7 @@ int collect_client_info() if(NULL == token) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error.\n"); - //printf("ERROR: at collect_client_info(), malloc error.\n"); + printf("ERROR: at collect_client_info(), malloc error.\n"); pclose(fp); return -4; } @@ -147,30 +144,31 @@ int collect_client_info() pclose(fp); - - /* get speed files - * */ - //memset(chain_test,0,64); +/********************* + /* make speed files + * * + memset(chain_test,0,64); fp_shell = popen(CMD_MAKE_SPEED_FILE,"r"); if(NULL == fp_shell) { debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); - //printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); + printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); return -5; } - //fread(chain_test,64,1,fp_shell); + fread(chain_test,64,1,fp_shell); pclose(fp_shell); /* do some clean up,if it needs. - * */ + * * + int ret; ret = clean_more_chain(); if(0 != ret) { debug(LOG_ERR,"ERROR: clean_more_chain() return value:%d\n",ret); - //printf("ERROR: clean_more_chain() return value:%d\n",ret); + printf("ERROR: clean_more_chain() return value:%d\n",ret); } - +****************************/ /* get up speed * */ @@ -178,7 +176,7 @@ int collect_client_info() if(NULL == fp_upspeed) { debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_upseed error."); - //printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); + printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); return -6; } memset(info_buf,0,1024); @@ -193,7 +191,7 @@ int collect_client_info() if(NULL == token) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - //printf("ERROR: at collect_client_info(), malloc error.\n"); + printf("ERROR: at collect_client_info(), malloc error.\n"); fclose(fp_upspeed); return -7; } @@ -228,7 +226,7 @@ int collect_client_info() if(NULL == fp_downspeed) { debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_downspeed error."); - //printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); + printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); return -8; } memset(info_buf,0,1024); @@ -243,7 +241,7 @@ int collect_client_info() if(NULL == token) { debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - //printf("ERROR: at collect_client_info(), malloc error.\n"); + printf("ERROR: at collect_client_info(), malloc error.\n"); fclose(fp_downspeed); return -9; } @@ -275,6 +273,7 @@ int collect_client_info() } + /* @breif get unknown host name client's income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell * command have to sleep 1 second to collect client speed. @@ -405,7 +404,6 @@ int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed) return 0; } - /* @breif After the function collect_client_info() called,should call this function to * clean up. * @PARAMETER:void @@ -494,7 +492,7 @@ long get_online_time(const char *ip,const char *mac) } - +/************************** int clean_more_chain() { FILE *fp; @@ -511,7 +509,7 @@ int clean_more_chain() if(NULL == fp) { debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); - //printf("ERROR: at collect_client_info(),popen for fp error.\n"); + printf("ERROR: at collect_client_info(),popen for fp error.\n"); return -1; } pclose(fp); @@ -520,7 +518,7 @@ int clean_more_chain() if(NULL == fp) { debug(LOG_ERR,"ERROR: fopen() /tmp/client.speed.chain.num\n"); - //printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); + printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); return -2; } while(NULL != fgets(chain_test,10,fp)) @@ -540,19 +538,19 @@ int clean_more_chain() { pclose(fp); debug(LOG_INFO,"INFO: clean iptables chain"); - //printf("INFO: clean iptables chain\n"); + printf("INFO: clean iptables chain\n"); } else { failed_count++; debug(LOG_ERR,"ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)"); - //printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); + printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); } } return failed_count; } - +*****************************************/ char *get_client_auth_flag() diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h index ca194775..ae32e752 100644 --- a/src/get_clientinfo.h +++ b/src/get_clientinfo.h @@ -43,6 +43,20 @@ typedef struct _t_clientinfo{ int collect_client_info(); +/* @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:[char *client_ip] the unknown host name client's ip + * [int *go_speed] the pointer for client's outgoing speed to store. + * [int *come_speed] the pointer for client's incoming speed to store. + * @RETURN_VALUE:zero is success,others is error. + * @Note: none + * GaomingPan lonely-test:yes + * */ +int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed); + + + /* @breif After the function collect_client_info() called,should call this function to * clean up. * @PARAMETER:void @@ -71,30 +85,14 @@ t_clientinfo * get_client_info_by_mac(const char *mac); t_clientinfo * get_client_info_by_ip(const char *ip); -/* @breif get unknown host name client's income speed and outgo speed,based on shell command. - * this functions take at least 1 second to run,because of execute the shell - * command have to sleep 1 second to collect client speed. - * @PARAMETER:[char *client_ip] the unknown host name client's ip - * [int *go_speed] the pointer for client's outgoing speed to store. - * [int *come_speed] the pointer for client's incoming speed to store. - * @RETURN_VALUE:zero is success,others is error. - * @Note: none - * @Test: GaomingPan lonely-test:yes - * */ -int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed); - - - long get_online_time(const char *ip,const char *mac); - - +/*** int clean_more_chain(); - +***/ char *get_client_auth_flag(); - void set_client_auth_flag(); diff --git a/src/get_devinfo.c b/src/get_devinfo.c index 0f11ec61..65fb4b32 100644 --- a/src/get_devinfo.c +++ b/src/get_devinfo.c @@ -222,7 +222,7 @@ int get_devconn(void) s_config *conf = config_get_config(); memset(buf,0,10); - sprintf(shell_cmd,"cat /proc/net/arp|grep -e \"0x2\"|grep -e \"%s\" > /tmp/.devconn;awk \'END{print NR}\' /tmp/.devconn",conf->gw_interface); + sprintf(shell_cmd,"cat /proc/net/arp|grep -e \"0x2\"|grep -e \"%s\" | awk \'!a[$4]++\'> /tmp/.devconn;awk \'END{print NR}\' /tmp/.devconn",conf->gw_interface); //fp = popen("awk \'END{print NR}\' $(uci get dhcp.@dnsmasq[0].leasefile)","r"); fp = popen(shell_cmd,"r"); @@ -234,7 +234,7 @@ int get_devconn(void) if(0 == fread(buf,1,10,fp)) { pclose(fp); - return -2; + return 0; } pclose(fp); return (atoi(buf)); @@ -435,11 +435,10 @@ int get_trafficCount(long *outgo,long *income) * */ int get_wanbps(int *go,int *come) { - long outgo = 0, - income = 0; - - long outgo1 = 0, - income1 = 0; + unsigned long long outgo = 0, + income = 0; + unsigned long long outgo1 = 0, + income1 = 0; int ret = 0; ret = get_trafficCount(&outgo,&income); diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c index f27a353b..5d67787a 100644 --- a/src/get_remote_shell.c +++ b/src/get_remote_shell.c @@ -150,8 +150,8 @@ char *get_shell_command(char *cmdptr) int excute_shell_command(char *gw_id,char *shellcmd) { - char cmd_id[512], - get_info_cmd[512], + char cmd_id[20], + get_info_cmd[30], normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; char *pos_id, *pos_cmd; @@ -160,8 +160,9 @@ int excute_shell_command(char *gw_id,char *shellcmd) char cmdresult[1024]; memset(cmdresult,0,1024); - memset(cmd_id,0,512); - memset(get_info_cmd,0,512); + memset(cmd_id,0,20); + memset(get_info_cmd,0,30); + pos_id = shellcmd; pos_cmd = strstr(shellcmd,"|"); @@ -169,10 +170,11 @@ int excute_shell_command(char *gw_id,char *shellcmd) pos_cmd = ++pos_cmd; - sprintf(get_info_cmd,"%s",pos_cmd); + snprintf(get_info_cmd,30,"%s",pos_cmd); is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); + debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); if(0 == is_get_info) { @@ -185,12 +187,17 @@ int excute_shell_command(char *gw_id,char *shellcmd) fp = popen(normal_cmd,"r"); } + debug(LOG_INFO,"pos_cmd:%s",pos_cmd); + if(NULL == fp) { debug(LOG_ERR,"excute_shell_command popen error...."); + //printf("excute_shell_command popen error....\n"); return -1; } + //fread(cmdresult,1024,1,fp); pclose(fp); + //printf("\n\ncmd result:\n %s\n\n",cmdresult); if(0 == is_get_info) { diff --git a/src/http.c b/src/http.c index 21214c15..1c201fcf 100755 --- a/src/http.c +++ b/src/http.c @@ -57,6 +57,8 @@ #include "../config.h" + + extern pthread_mutex_t client_list_mutex; /** The 404 handler is also responsible for redirecting to the auth server */ diff --git a/src/ping_thread.c b/src/ping_thread.c index 9cf1da8e..dc38d219 100755 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -203,9 +203,8 @@ ping(void) get_device_key() ); - debug(LOG_INFO, "PingQString << %s >>", request); - - debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); + //debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); + debug(LOG_INFO, "\n\nPingQString: [[<< %s >>]]\n\n", request); send(sockfd, request, strlen(request), 0); @@ -266,19 +265,16 @@ ping(void) /* FIXME */ } else { - //debug(LOG_DEBUG, "Auth Server Says: Pong"); - debug(LOG_INFO, "Auth Server Says: Pong"); + debug(LOG_DEBUG, "Auth Server Says: Pong"); /****************/ cmdptr = strstr(request,"|"); if(NULL == cmdptr) { - debug(LOG_INFO,"NO remote cmd.\n"); - //printf("NO remote cmd.\n"); + printf("NO remote cmd.\n"); } else { - debug(LOG_INFO,"Auth Server Return: %s",request); cmdptr = get_shell_command(++cmdptr); if(cmdptr) { diff --git a/src/shell_command.h b/src/shell_command.h index 17b1ec25..f0ed2c05 100644 --- a/src/shell_command.h +++ b/src/shell_command.h @@ -19,6 +19,7 @@ //#define CMD_GET_CLIENT_LIST "cat /var/dhcp.leases | awk \'{print $2,$3,$4}\'" #define CMD_GET_CLIENT_LIST "cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk \'{print $2,$3,$4}\'" +/************ #define CMD_MAKE_SPEED_FILE "UP_SPEED=\"/tmp/client.up.speed\"\n" \ "DOWN_SPEED=\"/tmp/client.down.speed\"\n" \ "MAC_IP=\"/tmp/mac-ip.client\"\n" \ @@ -36,10 +37,18 @@ "iptables -X UPLOAD \n" \ "iptables -X DOWNLOAD \n" - +/** #define CMD_GET_CHAIN_NUM "TARGET=/tmp/client.up.speed\n" \ "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET " \ "> /tmp/client.speed.chain.num" +** + +#define CMD_GET_CHAIN_NUM "TARGET_A=/tmp/client.up.speed\n" \ + "TARGET_B=/tmp/client.down.speed\n" \ + "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET_A " \ + "> /tmp/client.speed.chain.num\n" \ + "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET_B " \ + ">> /tmp/client.speed.chain.num" #define CMD_CLEAN_SPEED_CHAIN "MAC_IP=\"/tmp/mac-ip.client\"\n" \ @@ -48,6 +57,6 @@ "iptables -X UPLOAD \n " \ "iptables -X DOWNLOAD " - +******************/ #endif /* SRC_SHELL_COMMAND_H_ */ From bfe7efcb870a383b9a227ea4d79f4a8b19c605fd Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 14 Sep 2015 15:44:19 +0800 Subject: [PATCH 18/33] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=8F=82=E6=95=B0=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/wifidog/Makefile | 2 +- contrib/wifidog/files/wifidog.conf | 2 +- contrib/wifidog/files/wifidog.init | 6 +- scripts/DOG_monitor.sh | 152 +++++++++++++++++++++++++++++ scripts/DOG_monitor.sh~ | 151 ++++++++++++++++++++++++++++ scripts/GET_clients_rate.sh | 34 ------- scripts/GET_clients_rate.sh~ | 2 +- scripts/conf/wifidog_conf | 2 +- scripts/init.d/wifidog | 2 +- src/fw_iptables.c | 21 ++++ src/fw_iptables.h | 5 + src/gateway.c | 6 ++ src/get_devinfo.c | 149 ++++++++++++++++++++++------ src/get_devinfo.h | 19 ++-- src/ping_thread.c | 2 +- src/shell_command.h | 3 +- 16 files changed, 476 insertions(+), 82 deletions(-) create mode 100644 scripts/DOG_monitor.sh create mode 100644 scripts/DOG_monitor.sh~ delete mode 100644 scripts/GET_clients_rate.sh diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile index 9b8e7212..090a4a93 100644 --- a/contrib/wifidog/Makefile +++ b/contrib/wifidog/Makefile @@ -50,7 +50,7 @@ define Package/wifidog/install $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_settings.sh $(1)/usr/bin/GET_settings $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/dog_conf_generator.sh $(1)/usr/bin/dog_conf_generator # $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/white_black_flush.sh $(1)/usr/bin/white_black_flush - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_clients_rate.sh $(1)/usr/bin/GET_clients_rate + $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/DOG_monitor.sh $(1)/usr/bin/DOG_monitor $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ $(INSTALL_DIR) $(1)/usr/lib diff --git a/contrib/wifidog/files/wifidog.conf b/contrib/wifidog/files/wifidog.conf index fa6ec558..42e767c6 100644 --- a/contrib/wifidog/files/wifidog.conf +++ b/contrib/wifidog/files/wifidog.conf @@ -33,7 +33,7 @@ # and eth1, wlan0, ath0, etc. otherwise # You can get this interface with the ifconfig command and finding your wifi interface -GatewayInterface br-lan +# GatewayInterface br-lan # Parameter: GatewayAddress # Default: Find it from GatewayInterface diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init index 84972d04..2a6533aa 100644 --- a/contrib/wifidog/files/wifidog.init +++ b/contrib/wifidog/files/wifidog.init @@ -19,8 +19,8 @@ start() { # sleep 1 # /usr/bin/white_black_flush & - sleep 3 - /usr/bin/GET_clients_rate & + sleep 5 + /usr/bin/DOG_monitor & } stop() { @@ -32,7 +32,7 @@ stop() { # fi sleep 2 - rst=`ps | grep GET_clients_rate | cut -d "r" -f 1` + rst=`ps | grep DOG_monitor | cut -d "r" -f 1` if [ -n "$rst" ]; then kill -9 $rst fi diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh new file mode 100644 index 00000000..01428e8c --- /dev/null +++ b/scripts/DOG_monitor.sh @@ -0,0 +1,152 @@ +#!/bin/sh +########################################################### +## +## Description: this scripts generate the interface traffic +## count file and clients rate file for the +## wifidog daemon,and monitor the wifidog daemon, +## if the wifidog was down,it will be start again. +## This scripts based on UCI and iptables,run on +## OpenWrt routers. +## Author: GaomingPan +## Lisence: GPL +## Date: 2015-09-12 +## Version: v1.2.0 +## +############################################################ + +############################################################ +## +## Function: iface_data_file_generator +## Description: generate the file that contains: interface +## name,Receive bytes,Transmit bytes,Rx rate in +## a second and Tx rate in a second. +## FileContentsFormat: +## ifacename RxBytes TxBytes dRx dTx +## +############################################################ +IFACE_DATA=/tmp/iface-data +T_IFACE_DATA=/tmp/.t_iface-data +DEV_FILE=/proc/net/dev +TMP=/tmp/.ftmp +TMP_D=/tmp/.ftmpd + +iface_data_file_generator() +{ + echo > $IFACE_DATA + echo > $T_IFACE_DATA + echo > $TMP + echo > $TMP_D + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $T_IFACE_DATA + done < $TMP + sleep 1 + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $IFACE_DATA + done < $TMP + sed '/^$/d' $T_IFACE_DATA > $TMP + cat $TMP > $T_IFACE_DATA + sed '/^$/d' $IFACE_DATA > $TMP + cat $TMP > $IFACE_DATA + echo > $TMP + i=$(awk 'END{print NR}' $IFACE_DATA) + while [ $i -gt 0 ] + do + read line < $IFACE_DATA + rx1=$(echo $line | awk '{print $2}') + tx1=$(echo $line | awk '{print $3}') + read line < $T_IFACE_DATA + rx2=$(echo $line | awk '{print $2}') + tx2=$(echo $line | awk '{print $3}') + cat $IFACE_DATA|sed 1d > $TMP + cat $TMP > $IFACE_DATA + cat $T_IFACE_DATA|sed 1d > $TMP + cat $TMP > $T_IFACE_DATA + drx=$(($rx1 - $rx2)) + dtx=$(($tx1 - $tx2)) + echo "$line $drx $dtx" >> $TMP_D + i=$(($i - 1)) + done + cat $TMP_D > $IFACE_DATA + +} + +########################################################## +## +## Function: clients_RxTxRate_generator +## Description: this function generator the client rate file. +## +########################################################### +UP_SPEED=/tmp/client.up.speed +DOWN_SPEED=/tmp/client.down.speed +MAC_IP=/tmp/mac-ip.client +I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') + +clients_RxTxRate_generator() +{ + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP + iptables -N UPLOAD + iptables -N DOWNLOAD + while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + sleep 1 + iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -X UPLOAD + iptables -X DOWNLOAD +} + +################################################## +## +## Function: dog_daemon_monitor +## Description: monitor the wifidog daemon,if it +## was down,then start it. +## +################################################# +dog_daemon_monitor() +{ + pid=$(ps | grep wifidog | cut -d "r" -f 1) + + if [ -n "$pid" ] + then + return 1 + fi + + /usr/bin/wdctl stop > /dev/null + sleep 1 + /usr/bin/wifidog -d 1 & + + return 0 +} + +################################################## +## +## Function: man_loop +## Description: this is the mian function,do above +## things to refresh data. +## +################################################# +main_loop() +{ + while [ true ] + do + iface_data_file_generator + clients_RxTxRate_generator + dog_daemon_monitor + sleep $(($CHECK_INTERVAL - 3)) + done + } + +############################# +## +## now,do the loop +## +############################# +main_loop + diff --git a/scripts/DOG_monitor.sh~ b/scripts/DOG_monitor.sh~ new file mode 100644 index 00000000..565e03c0 --- /dev/null +++ b/scripts/DOG_monitor.sh~ @@ -0,0 +1,151 @@ +#!/bin/sh +########################################################### +## +## Description: this scripts generate the interface traffic +## count file and clients rate file for the +## wifidog daemon,and monitor the wifidog daemon, +## if the wifidog was down,it will be start again. +## This scripts based on UCI and iptables,run on +## OpenWrt routers. +## Author: GaomingPan +## Lisence: GPL +## Date: 2015-09-12 +## Version: v1.2.0 +## +############################################################ + +############################################################ +## +## Function: iface_data_file_generator +## Description: generate the file that contains: interface +## name,Receive bytes,Transmit bytes,Rx rate in +## a second and Tx rate in a second. +## FileContentsFormat: +## ifacename RxBytes TxBytes dRx dTx +## +############################################################ +IFACE_DATA=/tmp/iface-data +T_IFACE_DATA=/tmp/.t_iface-data +DEV_FILE=/proc/net/dev +TMP=/tmp/.ftmp +TMP_D=/tmp/.ftmpd + +iface_data_file_generator() +{ + echo > $IFACE_DATA + echo > $T_IFACE_DATA + echo > $TMP + echo > $TMP_D + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $T_IFACE_DATA + done < $TMP + sleep 1 + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $IFACE_DATA + done < $TMP + sed '/^$/d' $T_IFACE_DATA > $TMP + cat $TMP > $T_IFACE_DATA + sed '/^$/d' $IFACE_DATA > $TMP + cat $TMP > $IFACE_DATA + echo > $TMP + i=$(awk 'END{print NR}' $IFACE_DATA) + while [ $i -gt 0 ] + do + read line < $IFACE_DATA + rx1=$(echo $line | awk '{print $2}') + tx1=$(echo $line | awk '{print $3}') + read line < $T_IFACE_DATA + rx2=$(echo $line | awk '{print $2}') + tx2=$(echo $line | awk '{print $3}') + cat $IFACE_DATA|sed 1d > $TMP + cat $TMP > $IFACE_DATA + cat $T_IFACE_DATA|sed 1d > $TMP + cat $TMP > $T_IFACE_DATA + drx=$(($rx1 - $rx2)) + dtx=$(($tx1 - $tx2)) + echo "$line $drx $dtx" >> $TMP_D + i=$(($i - 1)) + done + cat $TMP_D > $IFACE_DATA + +} + +########################################################## +## +## Function: clients_RxTxRate_generator +## Description: this function generator the client rate file. +## +########################################################### +UP_SPEED=/tmp/client.up.speed +DOWN_SPEED=/tmp/client.down.speed +MAC_IP=/tmp/mac-ip.client +I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') + +clients_RxTxRate_generator() +{ + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP + iptables -N UPLOAD + iptables -N DOWNLOAD + while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + sleep 1 + iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -X UPLOAD + iptables -X DOWNLOAD +} + +################################################## +## +## Function: dog_daemon_monitor +## Description: monitor the wifidog daemon,if it +## was down,then start it. +## +################################################# +dog_daemon_monitor() +{ + pid=$(ps | grep wifidog | cut -d "r" -f 1) + + if [ -n "$pid" ] + then + return 1 + fi + + /usr/bin/wdctl stop > /dev/null + /usr/bin/wifidog -d 1 & + + return 0 +} + +################################################## +## +## Function: man_loop +## Description: this is the mian function,do above +## things to refresh data. +## +################################################# +main_loop() +{ + while [ true ] + do + iface_data_file_generator + clients_RxTxRate_generator + dog_daemon_monitor + sleep $(($CHECK_INTERVAL - 3)) + done + } + +############################# +## +## now,do the loop +## +############################# +main_loop + diff --git a/scripts/GET_clients_rate.sh b/scripts/GET_clients_rate.sh deleted file mode 100644 index 148be403..00000000 --- a/scripts/GET_clients_rate.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -###################################################################################################### -# -# Description: get the rate of clients,run in openwrt open router. -# Author: GaomingPan -# Version: v1.0.0 -# Lisence: GPL -# Date: 2015-09-08 -# -###################################################################################################### - -UP_SPEED=/tmp/client.up.speed -DOWN_SPEED=/tmp/client.down.speed -MAC_IP=/tmp/mac-ip.client -I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') -CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') - -while [ true ] - do - cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP - iptables -N UPLOAD - iptables -N DOWNLOAD - while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP - sleep 1 - iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED - iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED - while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP - iptables -X UPLOAD - iptables -X DOWNLOAD - sleep $(($CHECK_INTERVAL - 2)) - done - diff --git a/scripts/GET_clients_rate.sh~ b/scripts/GET_clients_rate.sh~ index bac8bf46..148be403 100644 --- a/scripts/GET_clients_rate.sh~ +++ b/scripts/GET_clients_rate.sh~ @@ -12,7 +12,7 @@ UP_SPEED=/tmp/client.up.speed DOWN_SPEED=/tmp/client.down.speed MAC_IP=/tmp/mac-ip.client -IFACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') while [ true ] diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index e555c0e6..1d85243d 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -10,7 +10,7 @@ config 'wifidog_conf' 'single' option gatewayPort '# GatewayPort 2060' option proxyPort '# ProxyPort 0' option httpdName '# HTTPDName WiFiDog' - option httpdMaxConn '# HTTPDMaxConn 120' + option httpdMaxConn '# HTTPDMaxConn 10' option httpdRealm '# HTTPDRealm WiFiDog' option httpdUserName '# HTTPDUserName admin' option httpdPassword '# HTTPDPassword secret' diff --git a/scripts/init.d/wifidog b/scripts/init.d/wifidog index f5447651..7c1ab87e 100755 --- a/scripts/init.d/wifidog +++ b/scripts/init.d/wifidog @@ -14,7 +14,7 @@ IPT=/usr/sbin/iptables WD_DIR=/usr/bin -OPTIONS="" +OPTIONS="-d 1" case "$1" in start) diff --git a/src/fw_iptables.c b/src/fw_iptables.c index bda82ca3..7ada59bb 100755 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -48,6 +48,8 @@ #include "util.h" #include "client_list.h" +//#include "get_devinfo.h" + /*limeng*/ #include @@ -58,6 +60,17 @@ static void iptables_load_ruleset(const char *, const char *, const char *); extern pthread_mutex_t client_list_mutex; extern pthread_mutex_t config_mutex; +static char dev_extern_iface[64]; + + +/** @brief Get extern interface + * this function use at get_devinfo.c*/ +char *get_dev_extern_iface() +{ + return dev_extern_iface; +} + + /** Used to supress the error output of the firewall during destruction */ static int fw_quiet = 0; @@ -253,8 +266,16 @@ iptables_fw_init(void) gw_port = config->gw_port; if (config->external_interface) { ext_interface = safe_strdup(config->external_interface); + + memset(dev_extern_iface,0,64); + sprintf(dev_extern_iface,"%s",ext_interface); + debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); } else { ext_interface = get_ext_iface(); + + memset(dev_extern_iface,0,64); + sprintf(dev_extern_iface,"%s",ext_interface); + debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); } if (ext_interface == NULL) { diff --git a/src/fw_iptables.h b/src/fw_iptables.h index 2e52ba0a..55f2be84 100755 --- a/src/fw_iptables.h +++ b/src/fw_iptables.h @@ -79,4 +79,9 @@ int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int ta /** @brief All counters in the client list */ int iptables_fw_counters_update(void); + +/** @brief Get extern interface + * this function use at get_devinfo.c*/ +char *get_dev_extern_iface(); + #endif /* _IPTABLES_H_ */ diff --git a/src/gateway.c b/src/gateway.c index 913a9e2b..301eb7d9 100755 --- a/src/gateway.c +++ b/src/gateway.c @@ -412,6 +412,7 @@ main_loop(void) exit(1); } + /**************************************************/ /**** init my post url config *****/ if(0 != init_post_http_url_config() ) { @@ -423,6 +424,11 @@ main_loop(void) { debug(LOG_ERR,"ERROR:Failed to initalize device key."); } + /*get ap mac*/ + if(0 != get_apmac(NULL)) + { + debug(LOG_ERR,"ERROR:Failed to get ap MAC."); + } /*********************************/ debug(LOG_DEBUG, "Assigning callbacks to web server"); diff --git a/src/get_devinfo.c b/src/get_devinfo.c index 65fb4b32..5c2635ed 100644 --- a/src/get_devinfo.c +++ b/src/get_devinfo.c @@ -21,6 +21,7 @@ #include "debug.h" #include "conf.h" #include "client_list.h" +#include "fw_iptables.h" #include "../config.h" @@ -32,22 +33,30 @@ extern pthread_mutex_t client_list_mutex; static t_devinfo devinfo; static t_cpuuse cpuuse; +static char apmac[DEV_MAC_ADDR_LEN]; + +//extern char *dev_extern_iface; + t_devinfo *get_devinfo(void) { - if(get_apmac(devinfo.gw_mac)) - { - debug(LOG_ERR,"MyDEBUG:get get_apmac error!"); - } + memcpy(devinfo.gw_mac,apmac,DEV_MAC_ADDR_LEN); + +// if(get_apmac(devinfo.gw_mac)) +// { +// debug(LOG_ERR,"MyDEBUG:get get_apmac error!"); +// } if(get_devssid(devinfo.gw_ssid)) { debug(LOG_ERR,"MyDEBUG:get ssid error!"); } + if(get_dogversion(devinfo.dog_version)) { debug(LOG_ERR,"MyDEBUG: get_dogversion error!"); } + if(get_wanip(devinfo.wan_ip)) { debug(LOG_ERR,"MyDEBUG: get_wanip error!\n"); @@ -62,7 +71,8 @@ t_devinfo *get_devinfo(void) { debug(LOG_ERR,"MyDEBUG: get_speed error!"); } - if(get_trafficCount(&devinfo.outgoing,&devinfo.incoming)) + + if(get_trafficCount(get_dev_extern_iface(),&devinfo.incoming,&devinfo.outgoing,NULL,NULL)) { debug(LOG_ERR,"MyDEBUG: get_traffic error!\n"); } @@ -153,11 +163,12 @@ int get_wanip(char *wanip) * @RETURN_VALUE:always zero is success,others is failed. * GaomingPan lonely-test:yes * */ -int get_apmac(char *apmac) +int get_apmac(char *mac) { FILE *fp; int i; memset(apmac,0,DEV_MAC_ADDR_LEN); + fp = popen(CMD_GET_AP_MAC,"r"); if(NULL == fp) { @@ -176,6 +187,9 @@ int get_apmac(char *apmac) apmac[i] = 0; } + if(NULL != mac) + mac = apmac; + return 0; } @@ -317,11 +331,86 @@ int get_cpuuse(int type) } -/* @breif get wan interface traffic,based on shell command. +/* @breif get wan interface traffic. * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. * @RETURN_VALUE:zero is success,others is error. * GaomingPan lonely-test:yes * */ + +int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate) +{ + FILE *fp; + char *iface, + *ptr; + char data[4096]; + struct stat statbuf; + int data_size; + int ret; + + unsigned int rx,tx; + unsigned long long out,in; + + + iface = iface_name; + if(NULL == iface){ + out = 0L; + in = 0L; + debug(LOG_ERR,"at get_trafficCount(...),ifce_name is NULL."); + ret = -1; + goto ERR; + } + + stat(IFACE_DATA_FILE,&statbuf); + data_size = statbuf.st_size; + + fp = fopen(IFACE_DATA_FILE,"r"); + if(NULL == fp){ + out = 0L; + in = 0L; + debug(LOG_ERR,"at get_trafficCount(...), fopen the IFACE_DATA_FILE error."); + ret = -2; + goto ERR; + } + fread(data,1,data_size,fp); + fclose(fp); + + ptr = strstr(data,iface); + if(NULL == ptr){ + out = 0L; + in = 0L; + debug(LOG_ERR,"at get_trafficCount(...), strstr(..) get iface position error."); + ret = -3; + goto ERR; + } + ret = sscanf(ptr,"%*s %llu %llu %u %u",&in,&out,&rx,&tx); + if(ret != 4) + goto ERR; + + if(NULL != outgo) + *outgo = out; + if(NULL != income) + *income = in; + if(NULL != rx_rate) + *rx_rate = rx; + if(NULL != tx_rate) + *tx_rate = tx; + + return 0; + +ERR: + if(NULL != outgo) + *outgo = 0; + if(NULL != income) + *income = 0; + if(NULL != rx_rate) + *rx_rate = 0; + if(NULL != tx_rate) + *tx_rate = 0; + + return ret; +} + +/**************************************************** int get_trafficCount(long *outgo,long *income) { FILE *fp; @@ -392,7 +481,7 @@ int get_trafficCount(long *outgo,long *income) char *ifconfig_value; int i = 0; long rx2_tx10[2]; - /*å»é™¤ç©ºæ ¼ï¼Œåˆ¶è¡¨ç¬¦ï¼Œæ¢è¡Œç¬¦ç­‰ä¸éœ€è¦ç„字段*/ + /*å»é™¤ç©ºæ ¼ï¼Œåˆ¶è¡¨ç¬¦ï¼Œæ¢è¡Œç¬¦ç­‰ä¸éœ€è¦ç„字段* for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) { i++; @@ -405,12 +494,12 @@ int get_trafficCount(long *outgo,long *income) return -6; } strcpy(ifconfig_value, p); - /*得到ç„字符串中ç„ç¬¬äºŒä¸ªå­—æ®µæ˜¯æ¥æ”¶æµé‡*/ + /*得到ç„字符串中ç„ç¬¬äºŒä¸ªå­—æ®µæ˜¯æ¥æ”¶æµé‡* if(i == 2) { rx2_tx10[0] = atoll(ifconfig_value); } - /*得到ç„字符串中ç„第å个字段是å‘逿µé‡*/ + /*得到ç„字符串中ç„第å个字段是å‘逿µé‡* if(i == 10) { rx2_tx10[1] = atoll(ifconfig_value); @@ -425,7 +514,7 @@ int get_trafficCount(long *outgo,long *income) return 0; } - +******************************************/ /* @breif get wan interface speed,based on shell command. * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. @@ -433,33 +522,31 @@ int get_trafficCount(long *outgo,long *income) * @NOTE: this function will take a one second to wait data update,so,it's just waste time. * GaomingPan lonely-test:yes * */ -int get_wanbps(int *go,int *come) +int get_wanbps(unsigned int *go,unsigned int *come) { - unsigned long long outgo = 0, - income = 0; - unsigned long long outgo1 = 0, - income1 = 0; + unsigned int tx,rx; int ret = 0; + char *iface; - ret = get_trafficCount(&outgo,&income); - - if(ret) - { - debug(LOG_ERR,"1 at get_wanbps(), get_trafficCount() error return code = %d",ret); - return -1; + iface = get_dev_extern_iface();//config_get_config()->external_interface; + if(NULL == iface){ + debug(LOG_ERR,"at get_trafficCount(...), wifidog can't find the external_interface."); } - sleep(1); - - ret = get_trafficCount(&outgo1,&income1); - if(ret) - { - debug(LOG_ERR,"2 at get_wanbps(), get_trafficCount() error return code = %d",ret); - return -2; + ret = get_trafficCount(iface,NULL,NULL,&rx,&tx); + if(ret != 0){ + debug(LOG_ERR,"at get_wanbps(), get_trafficCount() error return code = %d",ret); + if(NULL != go) + *go = 0; + if(NULL != come) + *come = 0; + return -1; } - *go = (int)(outgo1 - outgo); - *come = (int)(income1 - income); + if(NULL != go) + *go = tx; + if(NULL != come) + *come = rx; return 0; } diff --git a/src/get_devinfo.h b/src/get_devinfo.h index 1af715e3..b39d0d04 100644 --- a/src/get_devinfo.h +++ b/src/get_devinfo.h @@ -14,6 +14,8 @@ #define DEV_WAN_IP_LEN 16 #define DEV_IFNAME_LEN 11 +#define IFACE_DATA_FILE "/tmp/iface-data" + #define CPU_USER 1 #define CPU_SYS 3 @@ -24,19 +26,22 @@ #define CPU_SIRQ 13 #define CPU_LOAD 16 + + + /*@ breif a struct hold information for ap*/ typedef struct _t_devinfo{ char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. - char wan_ip[DEV_WAN_IP_LEN]; // ap wan interface ip + char wan_ip[DEV_WAN_IP_LEN]; // ap's wan interface ip int cur_conn; // number of current connection client int dev_conn; // number of connection in the device,maybe some has no authentication. int cpu_use; // percent of use CPU - int go_speed; // wan interface go out speed - int come_speed; // wan interface come in speed - long incoming; // - long outgoing; // + unsigned int go_speed; // wan interface go out speed + unsigned int come_speed; // wan interface come in speed + unsigned long long incoming; // wan interface incoming bytes + unsigned long long outgoing; // wan interface outgoing bytes }t_devinfo; @@ -105,7 +110,7 @@ int get_cpuuse(int type); * @RETURN_VALUE:zero is success,others is error. * GaomingPan lonely-test:yes * */ -int get_wanbps(int *go,int *come); +int get_wanbps(unsigned int *go,unsigned int *come); /* @breif get wan interface traffic,based on shell command. @@ -113,7 +118,7 @@ int get_wanbps(int *go,int *come); * @RETURN_VALUE:zero is success,others is error. * GaomingPan lonely-test:yes * */ -int get_trafficCount(long *outgo,long *income); +int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate); #endif /* SRC_GET_DEVINFO_H_ */ diff --git a/src/ping_thread.c b/src/ping_thread.c index dc38d219..3cd0d73a 100755 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -170,7 +170,7 @@ ping(void) * Prep & send request */ snprintf(request, sizeof(request) - 1, - "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%d&come_speed=%d&incoming=%ld&outgoing=%ld HTTP/1.0\r\n" + "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%u&come_speed=%u&incoming=%llu&outgoing=%llu HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" "DeviceKey: %s\r\n" diff --git a/src/shell_command.h b/src/shell_command.h index f0ed2c05..11411962 100644 --- a/src/shell_command.h +++ b/src/shell_command.h @@ -14,7 +14,8 @@ #define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" #define CMD_GET_CPU_USE "top -n 1 | grep id" #define CMD_GET_AP_MAC "uci get network.lan.macaddr" -#define CMD_GET_WAN_IFNAME "uci get network.wan.ifname" + +//#define CMD_GET_WAN_IFNAME "uci get network.wan.ifname" //#define CMD_GET_CLIENT_LIST "cat /var/dhcp.leases | awk \'{print $2,$3,$4}\'" #define CMD_GET_CLIENT_LIST "cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk \'{print $2,$3,$4}\'" From f6b958440e8e2a0ca16563acadcd5c5c7afb4bd3 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Fri, 18 Sep 2015 11:18:34 +0800 Subject: [PATCH 19/33] I changed the get clients information method,and fix the memory overflow int the auth thread,the reason is alloc memory but not free. --- contrib/wifidog/files/wifidog.init | 2 +- scripts/DOG_monitor.sh | 21 +- scripts/DOG_monitor.sh~ | 7 +- src/centralserver.c | 29 +- src/get_clientinfo.c | 496 +++++++++-------------------- src/get_clientinfo.h | 8 +- src/get_devinfo.c | 2 + 7 files changed, 195 insertions(+), 370 deletions(-) diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init index 2a6533aa..38664265 100644 --- a/contrib/wifidog/files/wifidog.init +++ b/contrib/wifidog/files/wifidog.init @@ -11,7 +11,7 @@ EXTRA_HELP=" status Print the status of the service" start() { /usr/bin/dog_conf_generator & - echo "" > /etc/crontabs/root + echo "00 04 * * * reboot" > /etc/crontabs/root echo "root" > /etc/crontabs/cron.update sleep 1 /usr/bin/wifidog-init start diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh index 01428e8c..61ed5888 100644 --- a/scripts/DOG_monitor.sh +++ b/scripts/DOG_monitor.sh @@ -109,9 +109,12 @@ clients_RxTxRate_generator() ## was down,then start it. ## ################################################# +PID_NAME=wifidog +PID_FILE=/tmp/ps-info dog_daemon_monitor() { - pid=$(ps | grep wifidog | cut -d "r" -f 1) + ps > $PID_FILE + pid=$(cat $PID_FILE | grep $PID_NAME | awk '{print $1}') if [ -n "$pid" ] then @@ -125,6 +128,21 @@ dog_daemon_monitor() return 0 } + +################################################## +## +## Function: hostname_file_generator +## Description: this function generate and refresh +## the hostname file for wifidog. +## +################################################## +HOST_NAME_FILE=/tmp/hostname.txt + +hostname_file_generator() +{ + cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk '{print $2,$3,$4}' > $HOST_NAME_FILE +} + ################################################## ## ## Function: man_loop @@ -138,6 +156,7 @@ main_loop() do iface_data_file_generator clients_RxTxRate_generator + hostname_file_generator dog_daemon_monitor sleep $(($CHECK_INTERVAL - 3)) done diff --git a/scripts/DOG_monitor.sh~ b/scripts/DOG_monitor.sh~ index 565e03c0..b53acb6e 100644 --- a/scripts/DOG_monitor.sh~ +++ b/scripts/DOG_monitor.sh~ @@ -109,9 +109,13 @@ clients_RxTxRate_generator() ## was down,then start it. ## ################################################# +PID_NAME=wifidog +PID_FILE=/tmp/ps-info + dog_daemon_monitor() { - pid=$(ps | grep wifidog | cut -d "r" -f 1) + ps > $PID_FILE + pid=$(cat $PID_FILE | grep $PID_NAME | awk '{print $1}') if [ -n "$pid" ] then @@ -119,6 +123,7 @@ dog_daemon_monitor() fi /usr/bin/wdctl stop > /dev/null + sleep 1 /usr/bin/wifidog -d 1 & return 0 diff --git a/src/centralserver.c b/src/centralserver.c index a0ee3785..71a28ecf 100755 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -112,27 +112,23 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons if(0 == strcmp(request_type,REQUEST_TYPE_COUNTERS) || 0 == strcmp(request_type,REQUEST_TYPE_LOGOUT)){ - client_info = get_client_info_by_ip(ip); - //client_info = get_client_info_by_mac(mac); - if(NULL == client_info) - { - //debug(LOG_ERR,"ERROR: at get_client_info_by_ip(ip) failed."); - debug(LOG_ERR,"ERROR: at get_client_info_by_mac(mac) failed."); - //printf("ERROR: at get_client_info_by_ip(ip) failed.\n"); - } LOCK_CLIENT_LIST(); - - if(0 != collect_client_info()) - { + if(0 != collect_client_info()){ debug(LOG_ERR,"ERROR: at collect_client_info() failed."); printf("ERROR: at collect_client_info() failed.\n"); } - online_time = get_online_time(ip,mac); - UNLOCK_CLIENT_LIST(); + client_info = get_client_info_by_ip(ip); + //client_info = get_client_info_by_mac(mac); + if(NULL == client_info){ + //debug(LOG_ERR,"ERROR: at get_client_info_by_ip(ip) failed."); + debug(LOG_ERR,"ERROR: at get_client_info_by_mac(mac) failed."); + //printf("ERROR: at get_client_info_by_ip(ip) failed.\n"); + } + /******************************************/ @@ -173,7 +169,7 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons } else{ - get_unknown_client_speed(ip,&go_speed,&come_speed); + get_unknown_client_speed(ip,&go_speed,&come_speed); snprintf(buf, (sizeof(buf) - 1), "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" @@ -207,6 +203,11 @@ auth_server_request(t_authresponse *authresponse, const char *request_type, cons get_device_key() ); } + + /** clean up the clients info,free the memories. + * */ + clean_client_info(); + }else{ snprintf(buf, (sizeof(buf) - 1), diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c index 5cf37c27..995d5ab4 100644 --- a/src/get_clientinfo.c +++ b/src/get_clientinfo.c @@ -45,229 +45,130 @@ static char client_auth_flag[7]; * */ int collect_client_info() { - FILE *fp, - *fp_shell, - *fp_upspeed, - *fp_downspeed; + FILE *fp; - char info_buf[1024], - chain_test[64], - ip[18]; - - int speed; - - char *ptr, - *token; + char a_rate[20], + ip[18]; t_clientinfo *p1, *p2, *p3; - int i = 0; - memset(info_buf,0,1024); + int ret; + + int line_num = 0; + char *line = NULL; + + + /** + * malloc memories for clients info list. + * */ first_client_info = (t_clientinfo*)malloc(sizeof(t_clientinfo)); - if(NULL == first_client_info) - { + if(NULL == first_client_info){ debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - printf("ERROR: at collect_client_info(), malloc error.\n"); return -1; } first_client_info->next = NULL; - p1 = first_client_info; p2 = p1; - fp = popen(CMD_GET_CLIENT_LIST,"r"); - - if(NULL == fp) - { - debug(LOG_ERR,"ERROR: at collect_client_info(),popen error."); - printf("ERROR: at collect_client_info(),popen error.\n"); - return -2; - } - while(NULL != fgets(info_buf,1024,fp)) - { + /** + * get host name,ip and mac + * */ + fp = fopen(HOST_NAME_FILE,"r"); + if(NULL == fp){ - if(NULL == p1) - { + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + if(NULL == p1){ p1 = (t_clientinfo*)malloc(sizeof(t_clientinfo)); - if(NULL == p1) - { + if(NULL == p1){ debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - - printf("ERROR: at collect_client_info(), malloc error.\n"); - pclose(fp); - return -3; + fclose(fp); + return -1; } p2->next = p1; p2 = p1; p1->next = NULL; - }//if - - for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) - { - i++; - token = (char*)malloc(40); - if(NULL == token) - { - debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error.\n"); - printf("ERROR: at collect_client_info(), malloc error.\n"); - pclose(fp); - return -4; - } - strcpy(token,ptr); - if(1 == i) - { - strcpy(p1->client_mac,token); - free(token); - continue; - } - if(2 == i) - { - strcpy(p1->client_ip,token); - free(token); - continue; - } - if(3 == i) - { - strcpy(p1->host_name,token); - free(token); - break; - } - }//for + }//if(NULL == p1) + ret = sscanf(line,"%s %s %s",p1->client_mac,p1->client_ip,p1->host_name); + if(3 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } p1 = p1->next; - i = 0; - memset(info_buf,0,1024); + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } - pclose(fp); - -/********************* - /* make speed files - * * - memset(chain_test,0,64); - fp_shell = popen(CMD_MAKE_SPEED_FILE,"r"); - if(NULL == fp_shell) - { - debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); - printf("ERROR: at collect_client_info(),popen for fp_shell error.\n"); - return -5; - } - fread(chain_test,64,1,fp_shell); - pclose(fp_shell); - - - /* do some clean up,if it needs. - * * - int ret; - ret = clean_more_chain(); - if(0 != ret) - { - debug(LOG_ERR,"ERROR: clean_more_chain() return value:%d\n",ret); - printf("ERROR: clean_more_chain() return value:%d\n",ret); - } -****************************/ /* get up speed * */ - fp_upspeed = fopen(UP_SPEED_FILE,"r"); - if(NULL == fp_upspeed) - { - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_upseed error."); - printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); - return -6; + fp = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); + return -1; } - memset(info_buf,0,1024); - memset(ip,0,18); - i = 0; - while(NULL != fgets(info_buf,1024,fp_upspeed)) - { - for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) - { - i++; - token = (char*)malloc(20); - if(NULL == token) - { - debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - printf("ERROR: at collect_client_info(), malloc error.\n"); - fclose(fp_upspeed); - return -7; - } - strcpy(token,ptr); - if(i == 1) - { - strcpy(ip,token); - free(token); - continue; - } - if(i == 2) - { - speed = atoi(token); - free(token); - p3 = get_client_info_by_ip(ip); - if(NULL != p3) - { - p3->go_speed = speed; - } - memset(ip,0,18); - i = 0; - break; - } - }//for + while(-1 != getline(&line,&line_num,fp)){ + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p3 = get_client_info_by_ip(ip); + if(NULL != p3){ + p3->go_speed = atoi(a_rate); + } + }//while - fclose(fp_upspeed); + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + /* get the down speed * */ - fp_downspeed = fopen(DOWN_SPEED_FILE,"r"); - if(NULL == fp_downspeed) - { - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp_downspeed error."); - printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); - return -8; + fp = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); + return -1; } - memset(info_buf,0,1024); - memset(ip,0,18); - i = 0; - while(NULL != fgets(info_buf,1024,fp_downspeed)) - { - for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) - { - i++; - token = (char*)malloc(40); - if(NULL == token) - { - debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - printf("ERROR: at collect_client_info(), malloc error.\n"); - fclose(fp_downspeed); - return -9; - } - strcpy(token,ptr); - if(i == 1) - { - strcpy(ip,token); - free(token); - continue; - } - if(i == 2) - { - speed = atoi(token); - free(token); - p3 = get_client_info_by_ip(ip); - if(NULL != p3) - { - p3->come_speed = speed; - } - memset(ip,0,18); - i = 0; - break; - } + while(-1 != getline(&line,&line_num,fp)){ + + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; } + p3 = get_client_info_by_ip(ip); + if(NULL != p3){ + p3->come_speed = atoi(a_rate); + } + }//while - fclose(fp_downspeed); + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + return 0; } @@ -287,120 +188,76 @@ int collect_client_info() int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed) { - FILE *fp_upspeed, - *fp_downspeed; + FILE *fp; - char info_buf[1024], + char a_rate[20], ip[18]; - int speed; - int ret; - - char *ptr, - *token; + int ret; + int line_num = 0; + char *line = NULL; - int i = 0; /* get up speed * */ - fp_upspeed = fopen(UP_SPEED_FILE,"r"); - if(NULL == fp_upspeed) - { - debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...),fopen for fp_upseed error."); - //printf("ERROR: at collect_client_info(),fopen for fp_upseed error.\n"); - *go_speed = *come_speed = 0; + fp = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); return -1; } - memset(info_buf,0,1024); - memset(ip,0,18); - i = 0; - while(NULL != fgets(info_buf,1024,fp_upspeed)) - { - for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) - { - i++; - token = (char*)malloc(20); - if(NULL == token) - { - debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...), malloc error."); - //printf("ERROR: at collect_client_info(), malloc error.\n"); - fclose(fp_upspeed); - *go_speed = *come_speed = 0; - return -2; - } - strcpy(token,ptr); - if(i == 1) - { - strcpy(ip,token); - free(token); - continue; - } - if(i == 2) - { - speed = atoi(token); - free(token); - if(0 == strcmp(client_ip,ip)) - { - *go_speed = speed; - } - memset(ip,0,18); - i = 0; - break; - } - }//for + while(-1 != getline(&line,&line_num,fp)){ + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + *go_speed = 0; + *come_speed = 0; + return -1; + } + + if(0 == strcmp(client_ip,ip)){ + *go_speed = atoi(a_rate); + } + }//while - fclose(fp_upspeed); + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + /* get the down speed * */ - fp_downspeed = fopen(DOWN_SPEED_FILE,"r"); - if(NULL == fp_downspeed) - { - debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...),fopen for fp_downspeed error."); - //printf("ERROR: at collect_client_info(),fopen for fp_downspeed error.\n"); - *go_speed = *come_speed = 0; - return -3; + fp = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); + return -1; } - memset(info_buf,0,1024); - memset(ip,0,18); - i = 0; - while(NULL != fgets(info_buf,1024,fp_downspeed)) - { - for(ptr = strtok(info_buf," \t\r\n");ptr;ptr = strtok(NULL," \t\r\n")) - { - i++; - token = (char*)malloc(40); - if(NULL == token) - { - debug(LOG_ERR,"ERROR: at get_unknown_client_speed(...), malloc error."); - //printf("ERROR: at collect_client_info(), malloc error.\n"); - fclose(fp_downspeed); - *go_speed = *come_speed = 0; - return -4; - } - strcpy(token,ptr); - if(i == 1) - { - strcpy(ip,token); - free(token); - continue; - } - if(i == 2) - { - speed = atoi(token); - free(token); - if(0 == strcmp(client_ip,ip)) - { - *come_speed = speed; - } - memset(ip,0,18); - i = 0; - break; - } + while(-1 != getline(&line,&line_num,fp)){ + + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + *go_speed = 0; + *come_speed = 0; + return -1; } + if(0 == strcmp(client_ip,ip)){ + *come_speed = atoi(a_rate); + } + }//while - fclose(fp_downspeed); + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + return 0; } @@ -413,19 +270,17 @@ int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed) * */ void clean_client_info() { - t_clientinfo *p1, - *p2; + t_clientinfo *p; - p1 = first_client_info; - p2 = p1->next; + p = first_client_info; - while(NULL != p1) + while(NULL != p) { - free(p1); - p1 = p2; - if(NULL != p2) - p2 = p2->next; + free(p); + p = p->next; } + + first_client_info = NULL; } @@ -492,65 +347,6 @@ long get_online_time(const char *ip,const char *mac) } -/************************** -int clean_more_chain() -{ - FILE *fp; - - char chain_test[10]; - - int chain_num = 0, - m = 0, - failed_count = 0; - - - memset(chain_test,0,10); - fp = popen(CMD_GET_CHAIN_NUM,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"ERROR: at collect_client_info(),popen for fp_shell error."); - printf("ERROR: at collect_client_info(),popen for fp error.\n"); - return -1; - } - pclose(fp); - - fp = fopen("/tmp/client.speed.chain.num","r"); - if(NULL == fp) - { - debug(LOG_ERR,"ERROR: fopen() /tmp/client.speed.chain.num\n"); - printf("ERROR: fopen() /tmp/client.speed.chain.num\n"); - return -2; - } - while(NULL != fgets(chain_test,10,fp)) - { - m = atoi(chain_test); - - if(m > chain_num) - chain_num = m; - } - fclose(fp); - - while( --chain_num > 0) - { - - fp = popen(CMD_CLEAN_SPEED_CHAIN,"r"); - if(NULL != fp) - { - pclose(fp); - debug(LOG_INFO,"INFO: clean iptables chain"); - printf("INFO: clean iptables chain\n"); - } - else - { - failed_count++; - debug(LOG_ERR,"ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)"); - printf("ERROR: popen(CMD_CLEAN_SPEED_CHAIN,r)\n"); - } - } - - return failed_count; -} -*****************************************/ char *get_client_auth_flag() diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h index ae32e752..cee4fb09 100644 --- a/src/get_clientinfo.h +++ b/src/get_clientinfo.h @@ -15,6 +15,7 @@ #define UP_SPEED_FILE "/tmp/client.up.speed" #define DOWN_SPEED_FILE "/tmp/client.down.speed" +#define HOST_NAME_FILE "/tmp/hostname.txt" /*@breif the sturct for client_info list @@ -87,12 +88,13 @@ t_clientinfo * get_client_info_by_ip(const char *ip); long get_online_time(const char *ip,const char *mac); -/*** -int clean_more_chain(); -***/ + + char *get_client_auth_flag(); + + void set_client_auth_flag(); diff --git a/src/get_devinfo.c b/src/get_devinfo.c index 5c2635ed..394ed1fe 100644 --- a/src/get_devinfo.c +++ b/src/get_devinfo.c @@ -183,6 +183,8 @@ int get_apmac(char *mac) { if(':' == apmac[i]) apmac[i] = '-'; + if(apmac[i] >= 'A' && apmac[i] <= 'F') + apmac[i] += apmac[i] + 0x20; if(0x0a == apmac[i]) apmac[i] = 0; } From 2655a82541a5092102238a2204d45e395c32afce Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 28 Sep 2015 17:58:13 +0800 Subject: [PATCH 20/33] update some get device's info functions --- .cproject | 4 + .project | 0 contrib/wifidog/Makefile | 0 contrib/wifidog/files/wifidog.conf | 0 contrib/wifidog/files/wifidog.init | 0 scripts/DOG_monitor.sh | 59 ++++++++++-- scripts/DOG_monitor.sh~ | 0 scripts/GET_clients_rate.sh~ | 0 scripts/TEST_ServerIsAlive.sh~ | 0 scripts/authServerIsAlive.sh | 0 scripts/authServerIsAlive.sh~ | 0 scripts/conf/dog_post_conf | 4 +- scripts/conf/wifidog_conf | 2 +- scripts/dog_conf_generator.sh | 0 scripts/dog_conf_generator.sh~ | 0 scripts/etc/devicekey | 0 src/device_key.c | 0 src/device_key.h | 0 src/get_clientinfo.c | 38 ++++---- src/get_clientinfo.h | 17 +++- src/get_devinfo.c | 147 +++++++++++++++++++++++++++-- src/get_devinfo.h | 5 +- src/get_remote_shell.c | 0 src/get_remote_shell.h | 0 src/shell_command.h | 0 25 files changed, 228 insertions(+), 48 deletions(-) mode change 100644 => 100755 .cproject mode change 100644 => 100755 .project mode change 100644 => 100755 contrib/wifidog/Makefile mode change 100644 => 100755 contrib/wifidog/files/wifidog.conf mode change 100644 => 100755 contrib/wifidog/files/wifidog.init mode change 100644 => 100755 scripts/DOG_monitor.sh mode change 100644 => 100755 scripts/DOG_monitor.sh~ mode change 100644 => 100755 scripts/GET_clients_rate.sh~ mode change 100644 => 100755 scripts/TEST_ServerIsAlive.sh~ mode change 100644 => 100755 scripts/authServerIsAlive.sh mode change 100644 => 100755 scripts/authServerIsAlive.sh~ mode change 100644 => 100755 scripts/conf/dog_post_conf mode change 100644 => 100755 scripts/conf/wifidog_conf mode change 100644 => 100755 scripts/dog_conf_generator.sh mode change 100644 => 100755 scripts/dog_conf_generator.sh~ mode change 100644 => 100755 scripts/etc/devicekey mode change 100644 => 100755 src/device_key.c mode change 100644 => 100755 src/device_key.h mode change 100644 => 100755 src/get_clientinfo.c mode change 100644 => 100755 src/get_clientinfo.h mode change 100644 => 100755 src/get_devinfo.c mode change 100644 => 100755 src/get_devinfo.h mode change 100644 => 100755 src/get_remote_shell.c mode change 100644 => 100755 src/get_remote_shell.h mode change 100644 => 100755 src/shell_command.h diff --git a/.cproject b/.cproject old mode 100644 new mode 100755 index e2b2aaa0..6296caa4 --- a/.cproject +++ b/.cproject @@ -27,6 +27,9 @@ + @@ -46,4 +49,5 @@ + diff --git a/.project b/.project old mode 100644 new mode 100755 diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile old mode 100644 new mode 100755 diff --git a/contrib/wifidog/files/wifidog.conf b/contrib/wifidog/files/wifidog.conf old mode 100644 new mode 100755 diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init old mode 100644 new mode 100755 diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh old mode 100644 new mode 100755 index 61ed5888..6bd4a19d --- a/scripts/DOG_monitor.sh +++ b/scripts/DOG_monitor.sh @@ -10,7 +10,7 @@ ## Author: GaomingPan ## Lisence: GPL ## Date: 2015-09-12 -## Version: v1.2.0 +## Version: v1.2.1 ## ############################################################ @@ -24,7 +24,7 @@ ## ifacename RxBytes TxBytes dRx dTx ## ############################################################ -IFACE_DATA=/tmp/iface-data +IFACE_DATA=/tmp/.iface-data T_IFACE_DATA=/tmp/.t_iface-data DEV_FILE=/proc/net/dev TMP=/tmp/.ftmp @@ -80,9 +80,9 @@ iface_data_file_generator() ## Description: this function generator the client rate file. ## ########################################################### -UP_SPEED=/tmp/client.up.speed -DOWN_SPEED=/tmp/client.down.speed -MAC_IP=/tmp/mac-ip.client +UP_SPEED=/tmp/.client.up.speed +DOWN_SPEED=/tmp/.client.down.speed +MAC_IP=/tmp/.mac-ip.client I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') @@ -110,11 +110,11 @@ clients_RxTxRate_generator() ## ################################################# PID_NAME=wifidog -PID_FILE=/tmp/ps-info +PS_FILE=/tmp/ps-info dog_daemon_monitor() { - ps > $PID_FILE - pid=$(cat $PID_FILE | grep $PID_NAME | awk '{print $1}') + ps > $PS_FILE + pid=$(cat $PS_FILE | grep $PID_NAME | awk '{print $1}') if [ -n "$pid" ] then @@ -136,13 +136,48 @@ dog_daemon_monitor() ## the hostname file for wifidog. ## ################################################## -HOST_NAME_FILE=/tmp/hostname.txt +HOST_NAME_FILE=/tmp/.hostname.txt hostname_file_generator() { cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk '{print $2,$3,$4}' > $HOST_NAME_FILE } +################################################## +## +## Function: iface_conn_file_generator +## Description: this function generate and refresh +## the interface connection file for wifidog. +## +################################################## +IFACE_CONN_FILE=/tmp/.iface_conn +IFACE_LIST=/tmp/.iface_list.txt + +iface_conn_file_generator() +{ + rm -f $IFACE_CONN_FILE + cat /proc/net/arp | awk '{print $6}' | awk '!a[$1]++' | sed 1d > $IFACE_LIST + while read line + do + echo "$line $(cat /proc/net/arp | grep -e "0x2" | grep -e $line | awk 'END{print NR}')" >> $IFACE_CONN_FILE + done < $IFACE_LIST +} + + +################################################## +## +## Function: cpu_use_info_file_generator +## Description: this function generate and refresh +## the cpu use information file for wifidog. +## +################################################## +CPU_USE_INFO_FILE=/tmp/.cpu_use_info + +cpu_use_info_file_generator() +{ + echo "$(top -n 1 | grep id | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE +} + ################################################## ## ## Function: man_loop @@ -152,13 +187,17 @@ hostname_file_generator() ################################################# main_loop() { + sleep_time=$(($CHECK_INTERVAL - 4)) + while [ true ] do iface_data_file_generator clients_RxTxRate_generator hostname_file_generator + iface_conn_file_generator + cpu_use_info_file_generator dog_daemon_monitor - sleep $(($CHECK_INTERVAL - 3)) + sleep $sleep_time done } diff --git a/scripts/DOG_monitor.sh~ b/scripts/DOG_monitor.sh~ old mode 100644 new mode 100755 diff --git a/scripts/GET_clients_rate.sh~ b/scripts/GET_clients_rate.sh~ old mode 100644 new mode 100755 diff --git a/scripts/TEST_ServerIsAlive.sh~ b/scripts/TEST_ServerIsAlive.sh~ old mode 100644 new mode 100755 diff --git a/scripts/authServerIsAlive.sh b/scripts/authServerIsAlive.sh old mode 100644 new mode 100755 diff --git a/scripts/authServerIsAlive.sh~ b/scripts/authServerIsAlive.sh~ old mode 100644 new mode 100755 diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf old mode 100644 new mode 100755 index 9dd1a3eb..778646ae --- a/scripts/conf/dog_post_conf +++ b/scripts/conf/dog_post_conf @@ -1,7 +1,7 @@ config dog_post 'url' - option 'info_url' 'http://108.108.108.7:8080/WiFiAuth/wifidog/result' - option 'normal_url' 'http://108.108.108.7:8080/WiFiAuth/wifidog/result' + option 'info_url' 'http://108.108.108.7:8080/ReWiFiAuth/wifidog/result' + option 'normal_url' 'http://108.108.108.7:8080/ReWiFiAuth/wifidog/result' config dog_post 'rmflag' option 'info_rmflag' 'result' diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf old mode 100644 new mode 100755 index 1d85243d..39b3d74f --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -23,7 +23,7 @@ config 'wifidog_conf' 'authServer' option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' option 'sslPort' '# SSLPort (Optional;Default:443)' option 'httpPort' 'HTTPPort 8080' - option 'path' 'Path /WiFiAuth/wifidog/' + option 'path' 'Path /ReWiFiAuth/wifidog/' option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh old mode 100644 new mode 100755 diff --git a/scripts/dog_conf_generator.sh~ b/scripts/dog_conf_generator.sh~ old mode 100644 new mode 100755 diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey old mode 100644 new mode 100755 diff --git a/src/device_key.c b/src/device_key.c old mode 100644 new mode 100755 diff --git a/src/device_key.h b/src/device_key.h old mode 100644 new mode 100755 diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c old mode 100644 new mode 100755 index 995d5ab4..4dd5c914 --- a/src/get_clientinfo.c +++ b/src/get_clientinfo.c @@ -32,7 +32,7 @@ static t_clientinfo *first_client_info = NULL; -static char client_auth_flag[7]; +static char client_auth_flag[7] = {0}; /* @breif get client host name,income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell @@ -274,8 +274,7 @@ void clean_client_info() p = first_client_info; - while(NULL != p) - { + while(NULL != p){ free(p); p = p->next; } @@ -295,10 +294,8 @@ t_clientinfo * get_client_info_by_mac(const char *mac) { t_clientinfo *p; p = first_client_info; - while(NULL != p) - { - if(strcmp(mac,p->client_mac) == 0) - { + while(NULL != p){ + if(strcmp(mac,p->client_mac) == 0){ return p; } p = p->next; @@ -318,10 +315,8 @@ t_clientinfo * get_client_info_by_ip(const char *ip) { t_clientinfo *p; p = first_client_info; - while(NULL != p) - { - if(strcmp(ip,p->client_ip) == 0) - { + while(NULL != p){ + if(strcmp(ip,p->client_ip) == 0){ return p; } p = p->next; @@ -330,7 +325,11 @@ t_clientinfo * get_client_info_by_ip(const char *ip) } - +/* @breif find the element from the client_info list by ip. + * @ip,the pointer point to by client's ip. + * @@mac,the pointer point to by client's mac. + * GaomingPan lonely-test:yes + * */ long get_online_time(const char *ip,const char *mac) { t_client *ptr; @@ -339,16 +338,15 @@ long get_online_time(const char *ip,const char *mac) ptr = client_list_find(ip,mac); if(NULL!= ptr) - { online_time = time(NULL) - ptr->record_time; - } return online_time; } - +/*@breif get a flage string + * */ char *get_client_auth_flag() { return client_auth_flag; @@ -356,15 +354,17 @@ char *get_client_auth_flag() - +/*@breif set a flage string + * */ void set_client_auth_flag() { - // rand()%(max - min + 1) + min + /* + * Rand a range number at [max,min]: + * rand()%(max - min + 1) + min + */ int i; for(i = 0;i<6;i++) client_auth_flag[i] = rand()%(90 - 65 + 1) + 65; - - client_auth_flag[6] = 0; } diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h old mode 100644 new mode 100755 index cee4fb09..7d3d0c89 --- a/src/get_clientinfo.h +++ b/src/get_clientinfo.h @@ -13,9 +13,9 @@ #define CLIENT_MAC_ADDRESS_LEN 18 #define CLIENT_IP_ADDRESS_LEN 16 -#define UP_SPEED_FILE "/tmp/client.up.speed" -#define DOWN_SPEED_FILE "/tmp/client.down.speed" -#define HOST_NAME_FILE "/tmp/hostname.txt" +#define UP_SPEED_FILE "/tmp/.client.up.speed" +#define DOWN_SPEED_FILE "/tmp/.client.down.speed" +#define HOST_NAME_FILE "/tmp/.hostname.txt" /*@breif the sturct for client_info list @@ -86,15 +86,22 @@ t_clientinfo * get_client_info_by_mac(const char *mac); t_clientinfo * get_client_info_by_ip(const char *ip); +/* @breif find the element from the client_info list by ip. + * @ip,the pointer point to by client's ip. + * @@mac,the pointer point to by client's mac. + * GaomingPan lonely-test:yes + * */ long get_online_time(const char *ip,const char *mac); - +/*@breif get a flage string + * */ char *get_client_auth_flag(); - +/*@breif set a flage string + * */ void set_client_auth_flag(); diff --git a/src/get_devinfo.c b/src/get_devinfo.c old mode 100644 new mode 100755 index 394ed1fe..87531f19 --- a/src/get_devinfo.c +++ b/src/get_devinfo.c @@ -33,7 +33,8 @@ extern pthread_mutex_t client_list_mutex; static t_devinfo devinfo; static t_cpuuse cpuuse; -static char apmac[DEV_MAC_ADDR_LEN]; +static char apmac[DEV_MAC_ADDR_LEN] = {0}; +static char apwanip[DEV_WAN_IP_LEN] = {0}; //extern char *dev_extern_iface; @@ -49,17 +50,17 @@ t_devinfo *get_devinfo(void) if(get_devssid(devinfo.gw_ssid)) { - debug(LOG_ERR,"MyDEBUG:get ssid error!"); + debug(LOG_ERR,"ERR:get ssid error!"); } if(get_dogversion(devinfo.dog_version)) { - debug(LOG_ERR,"MyDEBUG: get_dogversion error!"); + debug(LOG_ERR,"ERR: get_dogversion error!"); } if(get_wanip(devinfo.wan_ip)) { - debug(LOG_ERR,"MyDEBUG: get_wanip error!\n"); + debug(LOG_ERR,"ERR: get_wanip error!\n"); } devinfo.cur_conn = get_curconn(); @@ -69,12 +70,12 @@ t_devinfo *get_devinfo(void) if(get_wanbps(&devinfo.go_speed,&devinfo.come_speed)) { - debug(LOG_ERR,"MyDEBUG: get_speed error!"); + debug(LOG_ERR,"ERR: get_speed error!"); } if(get_trafficCount(get_dev_extern_iface(),&devinfo.incoming,&devinfo.outgoing,NULL,NULL)) { - debug(LOG_ERR,"MyDEBUG: get_traffic error!\n"); + debug(LOG_ERR,"ERR: get_traffic error!\n"); } return &devinfo; @@ -130,6 +131,38 @@ int get_dogversion(char *dogversion) * GaomingPan lonely-test:yes * */ int get_wanip(char *wanip) +{ + FILE *fp; + + if(0 == strlen(apwanip)){ + fp = popen(CMD_GET_WAN_IP,"r"); + if(NULL == fp){ + debug(LOG_ERR,"get_wanip error!"); + if(NULL != wanip) + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(apwanip,DEV_WAN_IP_LEN - 1,1,fp); + pclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i >= 0;i--){ + if(0x0a == apwanip[i]){ + apwanip[i] = 0; + break; + } + } + + }else{ + if(NULL != wanip) + sprintf(wanip,"%s",apwanip); + } + + return 0; +} + +/** +int get_wanip(char *wanip) { FILE *fp; memset(wanip,0,DEV_WAN_IP_LEN); @@ -155,7 +188,7 @@ int get_wanip(char *wanip) return 0; } - +*****/ /* @breif get ap mac address,based on uci command. @@ -230,6 +263,33 @@ int get_curconn(void) * @RETURN_VALUE:the number of connected client * GaomingPan lonely-test:no * */ + +int get_devconn(void) +{ + FILE *fp; + char info_buf[512], + num_buf[10]; + char *ptr = NULL; + s_config *conf = config_get_config(); + + fp = fopen(IFACE_CONN_FILE,"r"); + if(NULL == fp){ + debug(LOG_ERR,"ERROR fopen error, at get_devconn()."); + return -1; + } + if(0 == fread(info_buf,1,512,fp)){ + fclose(fp); + return 0; + } + fclose(fp); + ptr = strstr(info_buf,conf->gw_interface); + if(NULL == ptr) + return 0; + sscanf(ptr,"%s* %d",num_buf); + return (atoi(num_buf)); +} + +/**** int get_devconn(void) { FILE *fp; @@ -255,13 +315,82 @@ int get_devconn(void) pclose(fp); return (atoi(buf)); } - +********/ /* @breif get cpu use infomation,based on shell command. * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD * @RETURN_VALUE:the number of current percent of CPU use. * GaomingPan lonely-test:yes * */ + +int get_cpuuse(int type) +{ + int use, + i; + FILE *fp; + + for(i = 0;i < 15;i++) + memset(cpuuse.use_info[i],0,8); + + fp = fopen(CPU_USE_INFO_FILE,"r"); + if(NULL == fp){ + debug(LOG_ERR,"fopen error,at get_cpuuse(...) !"); + return -1; + } + fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], + cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], + cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], + cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], + cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] + ); + fclose(fp); + +// for(;i<15;i++) +// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); + + switch(type){ + case CPU_USER: + cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; + use = atoi(cpuuse.use_info[CPU_USER]); + break; + case CPU_SYS: + cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SYS]); + break; + case CPU_NIC: + cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; + use = atoi(cpuuse.use_info[CPU_NIC]); + break; + case CPU_IDLE: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_LOAD: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_IO: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IO]); + break; + case CPU_IRQ: + cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IRQ]); + break; + case CPU_SIRQ: + cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SIRQ]); + break; + default: + use = -1; + break; + } + + return use; +} + +/***** int get_cpuuse(int type) { char num[4]; @@ -331,7 +460,7 @@ int get_cpuuse(int type) return use; } - +********************************************/ /* @breif get wan interface traffic. * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. diff --git a/src/get_devinfo.h b/src/get_devinfo.h old mode 100644 new mode 100755 index b39d0d04..7fb09fae --- a/src/get_devinfo.h +++ b/src/get_devinfo.h @@ -14,8 +14,9 @@ #define DEV_WAN_IP_LEN 16 #define DEV_IFNAME_LEN 11 -#define IFACE_DATA_FILE "/tmp/iface-data" - +#define IFACE_DATA_FILE "/tmp/.iface-data" +#define IFACE_CONN_FILE "/tmp/.iface_conn" +#define CPU_USE_INFO_FILE "/tmp/.cpu_use_info" #define CPU_USER 1 #define CPU_SYS 3 diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c old mode 100644 new mode 100755 diff --git a/src/get_remote_shell.h b/src/get_remote_shell.h old mode 100644 new mode 100755 diff --git a/src/shell_command.h b/src/shell_command.h old mode 100644 new mode 100755 From cfbd5e0cc373315d0baa8961fa4a86c6f2541e1a Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Sun, 11 Oct 2015 21:15:39 +0800 Subject: [PATCH 21/33] first commit in Beta.1 --- configure.in | 5 + .../wifidog/files/wifidog.conf | 369 ++++++ .../wifidog/files/wifidog.init | 45 + scripts/DOG_monitor.sh | 210 ++++ scripts/GET_settings.sh | 54 + scripts/conf/dog_post_conf | 9 + scripts/conf/wifidog_conf | 72 ++ scripts/dog_conf_generator.sh | 180 +++ scripts/etc/devicekey | 6 + scripts/init.d/wifidog | 2 +- src/Makefile.am | 6 +- src/auth.c | 20 + src/centralserver.c | 180 ++- src/client_list.c | 4 + src/client_list.h | 1 + src/commandline.c | 6 +- src/conf.c | 84 +- src/conf.h | 11 + src/debug.c | 3 +- src/extend_util.c | 1081 +++++++++++++++++ src/extend_util.h | 252 ++++ src/firewall.c | 5 + src/fw_iptables.c | 36 + src/fw_iptables.h | 7 + src/gateway.c | 38 +- src/ping_thread.c | 50 +- src/pstring.c | 5 +- src/simple_http.c | 2 +- wifidog.conf | 8 + 29 files changed, 2695 insertions(+), 56 deletions(-) create mode 100644 contrib/build-openwrt-common/wifidog/files/wifidog.conf create mode 100644 contrib/build-openwrt-common/wifidog/files/wifidog.init create mode 100644 scripts/DOG_monitor.sh create mode 100644 scripts/GET_settings.sh create mode 100644 scripts/conf/dog_post_conf create mode 100644 scripts/conf/wifidog_conf create mode 100644 scripts/dog_conf_generator.sh create mode 100644 scripts/etc/devicekey create mode 100644 src/extend_util.c create mode 100644 src/extend_util.h diff --git a/configure.in b/configure.in index 917d5ece..89057226 100644 --- a/configure.in +++ b/configure.in @@ -24,6 +24,11 @@ WIFIDOG_MINOR_VERSION=2 WIFIDOG_MICRO_VERSION=1 WIFIDOG_VERSION=$WIFIDOG_MAJOR_VERSION.$WIFIDOG_MINOR_VERSION.$WIFIDOG_MICRO_VERSION +# I want to use Semantic Beta Versioning like this x.y.z-Beta.x for test my new features. +WIFIDOG_BETA_VERSION=Beta-1 +WIFIDOG_VERSION=$WIFIDOG_VERSION-$WIFIDOG_BETA_VERSION + + AC_SUBST(WIFIDOG_MAJOR_VERSION) AC_SUBST(WIFIDOG_MINOR_VERSION) AC_SUBST(WIFIDOG_MICRO_VERSION) diff --git a/contrib/build-openwrt-common/wifidog/files/wifidog.conf b/contrib/build-openwrt-common/wifidog/files/wifidog.conf new file mode 100644 index 00000000..9039772d --- /dev/null +++ b/contrib/build-openwrt-common/wifidog/files/wifidog.conf @@ -0,0 +1,369 @@ +# $Id$ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +#AuthServer { +# Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the wifidog-ping protocol. See http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the wifidog-auth protocol. See http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1) +#} +# If SSLAvailable is set, then the client will be redirected to the +# auth daemon on its HTTPS port. If Wifidog is compiled with SSL support, +# then Wifidog will also use HTTPS to talk to the auth server instead of +# plain HTTP. +# + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: DeltaTraffic +# Default: no +# Optional +# +# Set this to true if you want to reset each user's traffic (Outgoing and Incoming) value after each Auth operation. +# If this is enabled, Wifidog will add two new parameters to the AuthScriptPathFragment: Incoming_Delta, Outgoing_delta. +# DeltaTraffic no + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: SSLPeerVerification +# Default: yes +# Optional +# +# Enable peer certificate verification when talking to the auth +# server over SSL/TLS. Disabling this setting is mainly useful if +# you do not want to install ca-certificates. +# +# If this setting is set to yes, then the certificates in +# the directory indicated by SSLCertPath will be used to +# verify the auth server. +# +# This setting requires that WifiDog is compiled with SSL support. +# It will be ignored otherwise. +# +# To disable SSL completely for testing purposes, set SSLAvailable +# to False for the auth server in question. Note that this will disable +# HTTPS when redirecting clients to your auth server. +# +# SSLPeerVerification yes + +# Parameter: SSLCertPath +# Default: /etc/ssl/certs/ +# Optional +# +# Where to look for SSL certificates to verify the auth servers +# certificate. Note that these will only be used if the auth server +# in question is configured with SSLAvailable yes. +# +# The certificates in this directory must be named by their hash +# value. For OpenWRT, you need a ca-certificates package newer +# than what is shipped in Barrier Breaker (see +# https://dev.openwrt.org/ticket/16537). +# +# This setting requires that WifiDog is compiled with SSL support. +# It will be ignored otherwise. +# +# SSLCertPath /etc/ssl/certs/ + +# Parameter: SSLAllowedCipherList +# Default: all ciphers supported +# Optional +# +# Which cipher suite to allow. Note that CyaSSL will ignore cipher +# suites that use algorithms that aren't compiled in or cipher +# suites *WITH ERRORS IN THEIR NAMES*. +# +# Please see CyaSSL documentation for allowed values, format is a +# string where the ciphers are separated by colons (:) with no +# spaces. Ciphers are ordered from most desirable to least desirable. +# +# SSLAllowedCipherList ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:AES128-SHA:AES256-SHA + +# Parameter: SSLUseSNI +# Default: no +# Optional +# +# Enable SNI (Server Name Indication) TLS extension. +# Enabling this setting is mainly useful if the auth server is hosted +# multiple secure (HTTPS) websites. The WifiDog should indicate which hostname +# it is attempting to connect to at the start of the handshaking process. +# +# This setting requires that WifiDog is compiled with SSL support. +# It will be ignored otherwise. +# +# SSLUseSNI no + +# Parameter: TrustedMACList +# Default: none +# Optional +# + +# Check DNS health by querying IPs of these hosts +PopularServers kernel.org,ieee.org + +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication. +# N.B.: weak security, since MAC addresses are easy to spoof. +# +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + + # FirewallRule syntax: + # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X or port-range X:Y]] [to IP/CIDR] + + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## This is an example ruleset for example.com + ## example.com means example.com and *.example.com + #FirewallRule allow tcp to example.com + + ## Use the following if you are having problems with Apple iOS 7 clients. + ## See #7 and #14 at https://github.com/wifidog/wifidog-gateway/issues/ + #FirewallRule allow tcp to apple.com + #FirewallRule allow tcp to icloud.com + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: auth-is-down +# +# Does nothing when not configured. +# +# Used when auth server is down +#FirewallRuleSet auth-is-down { +# FirewallRule allow to 0.0.0.0/0 +#} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + # Use to-ipset to block or allow externally specified hosts. + # Ipsets are created with the ipset utility. This is useful to + # block or allow hosts at runtime externally. + # For example, if your auth server requires users to log in + # via Facebook, use the ipset feature built into dnsmasq to + # to populate a list of various IPs used by the Facebook networks. + #FirewallRule allow to-ipset fb + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/build-openwrt-common/wifidog/files/wifidog.init b/contrib/build-openwrt-common/wifidog/files/wifidog.init new file mode 100644 index 00000000..4a8bef93 --- /dev/null +++ b/contrib/build-openwrt-common/wifidog/files/wifidog.init @@ -0,0 +1,45 @@ +#!/bin/sh /etc/rc.common +# wifidog start on boot +#2015-08-12 +# + +START=65 + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print the status of the service" + + +start() { + /usr/bin/dog_conf_generator & + echo "00 04 * * * reboot" > /etc/crontabs/root + echo "root" > /etc/crontabs/cron.update + sleep 1 + /usr/bin/wifidog-init start + +# sleep 1 +# /usr/bin/white_black_flush & + + sleep 5 + /usr/bin/DOG_monitor & +} + +stop() { + /usr/bin/wifidog-init stop +# sleep 1 +# rst=`ps | grep white_black | cut -d "r" -f 1` +# if [ -n "$rst" ]; then +# kill -9 $rst +# fi + + sleep 2 + rst=`ps | grep DOG_monitor | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi +} + +status() { + + /usr/bin/wifidog-init status +} + diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh new file mode 100644 index 00000000..6bd4a19d --- /dev/null +++ b/scripts/DOG_monitor.sh @@ -0,0 +1,210 @@ +#!/bin/sh +########################################################### +## +## Description: this scripts generate the interface traffic +## count file and clients rate file for the +## wifidog daemon,and monitor the wifidog daemon, +## if the wifidog was down,it will be start again. +## This scripts based on UCI and iptables,run on +## OpenWrt routers. +## Author: GaomingPan +## Lisence: GPL +## Date: 2015-09-12 +## Version: v1.2.1 +## +############################################################ + +############################################################ +## +## Function: iface_data_file_generator +## Description: generate the file that contains: interface +## name,Receive bytes,Transmit bytes,Rx rate in +## a second and Tx rate in a second. +## FileContentsFormat: +## ifacename RxBytes TxBytes dRx dTx +## +############################################################ +IFACE_DATA=/tmp/.iface-data +T_IFACE_DATA=/tmp/.t_iface-data +DEV_FILE=/proc/net/dev +TMP=/tmp/.ftmp +TMP_D=/tmp/.ftmpd + +iface_data_file_generator() +{ + echo > $IFACE_DATA + echo > $T_IFACE_DATA + echo > $TMP + echo > $TMP_D + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $T_IFACE_DATA + done < $TMP + sleep 1 + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $IFACE_DATA + done < $TMP + sed '/^$/d' $T_IFACE_DATA > $TMP + cat $TMP > $T_IFACE_DATA + sed '/^$/d' $IFACE_DATA > $TMP + cat $TMP > $IFACE_DATA + echo > $TMP + i=$(awk 'END{print NR}' $IFACE_DATA) + while [ $i -gt 0 ] + do + read line < $IFACE_DATA + rx1=$(echo $line | awk '{print $2}') + tx1=$(echo $line | awk '{print $3}') + read line < $T_IFACE_DATA + rx2=$(echo $line | awk '{print $2}') + tx2=$(echo $line | awk '{print $3}') + cat $IFACE_DATA|sed 1d > $TMP + cat $TMP > $IFACE_DATA + cat $T_IFACE_DATA|sed 1d > $TMP + cat $TMP > $T_IFACE_DATA + drx=$(($rx1 - $rx2)) + dtx=$(($tx1 - $tx2)) + echo "$line $drx $dtx" >> $TMP_D + i=$(($i - 1)) + done + cat $TMP_D > $IFACE_DATA + +} + +########################################################## +## +## Function: clients_RxTxRate_generator +## Description: this function generator the client rate file. +## +########################################################### +UP_SPEED=/tmp/.client.up.speed +DOWN_SPEED=/tmp/.client.down.speed +MAC_IP=/tmp/.mac-ip.client +I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') + +clients_RxTxRate_generator() +{ + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP + iptables -N UPLOAD + iptables -N DOWNLOAD + while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + sleep 1 + iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -X UPLOAD + iptables -X DOWNLOAD +} + +################################################## +## +## Function: dog_daemon_monitor +## Description: monitor the wifidog daemon,if it +## was down,then start it. +## +################################################# +PID_NAME=wifidog +PS_FILE=/tmp/ps-info +dog_daemon_monitor() +{ + ps > $PS_FILE + pid=$(cat $PS_FILE | grep $PID_NAME | awk '{print $1}') + + if [ -n "$pid" ] + then + return 1 + fi + + /usr/bin/wdctl stop > /dev/null + sleep 1 + /usr/bin/wifidog -d 1 & + + return 0 +} + + +################################################## +## +## Function: hostname_file_generator +## Description: this function generate and refresh +## the hostname file for wifidog. +## +################################################## +HOST_NAME_FILE=/tmp/.hostname.txt + +hostname_file_generator() +{ + cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk '{print $2,$3,$4}' > $HOST_NAME_FILE +} + +################################################## +## +## Function: iface_conn_file_generator +## Description: this function generate and refresh +## the interface connection file for wifidog. +## +################################################## +IFACE_CONN_FILE=/tmp/.iface_conn +IFACE_LIST=/tmp/.iface_list.txt + +iface_conn_file_generator() +{ + rm -f $IFACE_CONN_FILE + cat /proc/net/arp | awk '{print $6}' | awk '!a[$1]++' | sed 1d > $IFACE_LIST + while read line + do + echo "$line $(cat /proc/net/arp | grep -e "0x2" | grep -e $line | awk 'END{print NR}')" >> $IFACE_CONN_FILE + done < $IFACE_LIST +} + + +################################################## +## +## Function: cpu_use_info_file_generator +## Description: this function generate and refresh +## the cpu use information file for wifidog. +## +################################################## +CPU_USE_INFO_FILE=/tmp/.cpu_use_info + +cpu_use_info_file_generator() +{ + echo "$(top -n 1 | grep id | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE +} + +################################################## +## +## Function: man_loop +## Description: this is the mian function,do above +## things to refresh data. +## +################################################# +main_loop() +{ + sleep_time=$(($CHECK_INTERVAL - 4)) + + while [ true ] + do + iface_data_file_generator + clients_RxTxRate_generator + hostname_file_generator + iface_conn_file_generator + cpu_use_info_file_generator + dog_daemon_monitor + sleep $sleep_time + done + } + +############################# +## +## now,do the loop +## +############################# +main_loop + diff --git a/scripts/GET_settings.sh b/scripts/GET_settings.sh new file mode 100644 index 00000000..a5326654 --- /dev/null +++ b/scripts/GET_settings.sh @@ -0,0 +1,54 @@ +#!/bin/sh +############################################################################################################################### +# +# description: get the settings of wireless, +# lan,wan,reboot_info and dhcp. +# use in OpenWrt router,based on uci +# Version: 1.0.0 +# Author: GaomingPan +# 2015-07-29 +# +# Pram: $1 gw_id +# $2 cmd_id +# +################################################################################################################################ +TMP=/tmp/.tmpfile +STMP=/tmp/.stmpfile +RESULT_FILE=/tmp/.routersettings +RESULT="" +echo "" > $RESULT_FILE +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" +RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" +uci show wireless > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"lan\":{" +uci show network.lan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"wan\":{" +uci show network.wan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"dhcp\":{" +uci show dhcp > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," +RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}]}} + +rm $TMP $STMP +echo $RESULT > $RESULT_FILE +##### +# delete the single quote ' character,because some uci version will echo ' to the file. +# +sed -i 's/'\''//g' $RESULT_FILE + + diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf new file mode 100644 index 00000000..08d52a8e --- /dev/null +++ b/scripts/conf/dog_post_conf @@ -0,0 +1,9 @@ + +config dog_post 'url' + option 'info_url' 'http://222.85.149.5/WiFiAuth/wifidog/result' + option 'normal_url' 'http://222.85.149.5/WiFiAuth/wifidog/result' + +config dog_post 'rmflag' + option 'info_rmflag' 'result' + option 'normal_rmflag' 'result' + diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf new file mode 100644 index 00000000..3d797269 --- /dev/null +++ b/scripts/conf/wifidog_conf @@ -0,0 +1,72 @@ +package 'wifidog_conf' + +config 'wifidog_conf' 'single' + option gatewayId '#GatewayID default is mac addr' + option externalInterface '# ExternalInterface eth0' + option gatewayInterface 'GatewayInterface br-lan' + option gatewayAddress '# GatewayAddress 192.168.1.1' + option htmlMessageFile '# HtmlMessageFile /opt/wifidog/etc/wifidog-.html' + option daemon '# Deamon 1' + option gatewayPort '# GatewayPort 2060' + option proxyPort '# ProxyPort 0' + option httpdName '# HTTPDName WiFiDog' + option httpdMaxConn '# HTTPDMaxConn 10' + option httpdRealm '# HTTPDRealm WiFiDog' + option httpdUserName '# HTTPDUserName admin' + option httpdPassword '# HTTPDPassword secret' + option checkInterval 'CheckInterval 30' + option clientTimeout 'ClientTimeout 5' + + +config 'wifidog_conf' 'authServer' + option 'hostname' 'Hostname 222.85.149.5' + option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' + option 'sslPort' '# SSLPort (Optional;Default:443)' + option 'httpPort' 'HTTPPort 12347' + option 'path' 'Path /WiFiAuth/wifidog/' + option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' + option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' + option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'pingScriptPathFragment' '# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'authScriptPathFragment' '# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.)' + +config 'wifidog_conf' 'trustedMACList' + option 'enable' '1' + list 'TrustedMACList' '11:22:33:44:55:66' + list 'TrustedMACList' 'aa:bb:cc:dd:ee:ff' + +config 'wifidog_conf' 'untrustedMACList' + option 'enable' '1' + list 'UntrustedMACList' 'aa:bb:cc:dd:ee:ff' + + +config 'wifidog_conf' 'whiteBlackList' + option 'white_enable' '0' + option 'black_enable' '0' + list 'WhiteList' 'www.baidu.com' + list 'WhiteList' 'www.taobao.com' + list 'BlackList' 'www.google.com' + list 'BlackList' 'www.hao123.com' + + +config 'wifidog_conf' 'firewallRule_global' + list 'FirewallRuleSet_global' '# FirewallRule block to 192.168.0.0/16 L' + list 'FirewallRuleSet_global' '# FirewallRule block to 172.16.0.0/12 L' + + +config 'wifidog_conf' 'firewallRule_validating_users' + list 'FirewallRuleSet_validating_users' 'FirewallRule allow to 0.0.0.0/0 L' + + +config 'wifidog_conf' 'firewallRule_known_users' + list 'FirewallRuleSet_known_users' 'FirewallRule allow to 0.0.0.0/0 L' + +config 'wifidog_conf' 'firewallRule_unknown_users' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 67 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 67 L' + +config 'wifidog_conf' 'firewallRule_locked_users' + list 'FirewallRuleSet_locked_users' 'FirewallRule block to 0.0.0.0/0 L' + diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh new file mode 100644 index 00000000..d2192933 --- /dev/null +++ b/scripts/dog_conf_generator.sh @@ -0,0 +1,180 @@ +#!/bin/sh +############################################################################################################## +# +# Generates the wifidog config file based on UCI +# +# Author : GaomingPan +# Date : 2015-08-05 +# Version: 1.0.0 +# +############################################################################################################### + +version="1.0.0" + +WIFI_DOG_CONF_FILE=/etc/wifidog.conf +WIFI_DOG_CONF=/etc/config/wifidog_conf +SINGLE=wifidog_conf.single +AUTH_SERVER=wifidog_conf.authServer +TRUSTED_MAC_LIST=wifidog_conf.trustedMACList +UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList +WHITE_LIST=wifidog_conf.whiteBlackList +BLACK_LIST=wifidog_conf.whiteBlackList +FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global +FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users +FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users +FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users +FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users + + +generate_single() +{ + echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE +} + +generate_authServer() +{ + echo "AuthServer {" >> $WIFI_DOG_CONF_FILE + echo "$(uci show $AUTH_SERVER | sed 1d | \ + awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_trustedMACList() +{ + enable=$(uci get "$TRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_untrustedMACList() +{ + enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_whiteList() +{ + white_enable=$(uci get "$WHITE_LIST.white_enable") + + if [ $white_enable -ne 1 ] + then + return + fi + + echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_blackList() +{ + black_enable=$(uci get "$BLACK_LIST.black_enable") + + if [ $black_enable -ne 1 ] + then + return + fi + + echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_global() +{ + echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + + +generate_firewallRule_validating_users() +{ + echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_known_users() +{ + echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_unknown_users() +{ + echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_locked_users() +{ + echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +conf_character_check() +{ + +##### +# delete the single quote ' character,because some uci version will echo ' to the +# config file. + sed -i 's/'\''//g' $WIFI_DOG_CONF_FILE +#### +# delete the blank character at the line header + sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE + +#### +# delete the blank character at the line tail + sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE + +} + +generate_wifidog_conf_file() +{ + echo "###########################################################" > $WIFI_DOG_CONF_FILE + echo "## this is wifidog config file" >> $WIFI_DOG_CONF_FILE + echo "## auto generate by dog_conf_generator.sh" >> $WIFI_DOG_CONF_FILE + echo "## Version: $version Based on UCI" >> $WIFI_DOG_CONF_FILE + echo "############################################################" >> $WIFI_DOG_CONF_FILE + + generate_single + generate_authServer + generate_trustedMACList + generate_untrustedMACList + generate_whiteList + generate_blackList + generate_firewallRule_global + generate_firewallRule_validating_users + generate_firewallRule_known_users + generate_firewallRule_unknown_users + generate_firewallRule_locked_users + + conf_character_check +} + + +#echo "------ starting generate wifidog config file --------" + +generate_wifidog_conf_file + +#echo "------ wifidog config file generate complete --------" + diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey new file mode 100644 index 00000000..12a3d538 --- /dev/null +++ b/scripts/etc/devicekey @@ -0,0 +1,6 @@ +######################################################## +## ### +## this file is the device key, do NOT modify it. ### +## ### +######################################################## +ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file diff --git a/scripts/init.d/wifidog b/scripts/init.d/wifidog index f5447651..37ea5715 100644 --- a/scripts/init.d/wifidog +++ b/scripts/init.d/wifidog @@ -14,7 +14,7 @@ IPT=/usr/sbin/iptables WD_DIR=/usr/bin -OPTIONS="" +OPTIONS="-d 4" case "$1" in start) diff --git a/src/Makefile.am b/src/Makefile.am index fba84cf0..d93f598c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,7 +34,8 @@ libgateway_a_SOURCES = commandline.c \ httpd_thread.c \ simple_http.c \ pstring.c \ - wd_util.c + wd_util.c \ + extend_util.c noinst_HEADERS = commandline.h \ common.h \ @@ -55,7 +56,8 @@ noinst_HEADERS = commandline.h \ httpd_thread.h \ simple_http.h \ pstring.h \ - wd_util.h + wd_util.h \ + extend_util.h wdctl_LDADD = libgateway.a diff --git a/src/auth.c b/src/auth.c index 549a59d3..67391e7a 100644 --- a/src/auth.c +++ b/src/auth.c @@ -50,6 +50,8 @@ #include "util.h" #include "wd_util.h" +#include "extend_util.h" + /** Launches a thread that periodically checks if any of the connections has timed out @param arg Must contain a pointer to a string containing the IP adress of the client to check to check @todo Also pass MAC adress? @@ -61,8 +63,18 @@ thread_client_timeout_check(const void *arg) pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; struct timespec timeout; + int ret = 0; while (1) { + /** + * Now,cllecting client's info,will create a + * client's info list. + * Added by GaomingPan + * */ + ret = collect_client_info(); + if(ret) + debug(LOG_WARNING,"cllecting client's info ERROR."); + /* Sleep for config.checkinterval seconds... */ timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; timeout.tv_nsec = 0; @@ -79,6 +91,14 @@ thread_client_timeout_check(const void *arg) debug(LOG_DEBUG, "Running fw_counter()"); fw_sync_with_authserver(); + + /** + * Now,clearing client's info list, + * free the memories. + * Added by GaomingPan + * */ + ret = clean_client_info(); + debug(LOG_DEBUG,"free [%d] entry client's info.",ret); } } diff --git a/src/centralserver.c b/src/centralserver.c index 22c87099..7a478ef2 100644 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -25,6 +25,8 @@ @author Copyright (C) 2004 Philippe April */ + + #include #include #include @@ -39,19 +41,21 @@ #include #include "httpd.h" - -#include "common.h" -#include "safe.h" -#include "util.h" -#include "wd_util.h" #include "auth.h" +#include "common.h" #include "conf.h" #include "debug.h" -#include "centralserver.h" #include "firewall.h" +#include "safe.h" +#include "simple_http.h" +#include "util.h" +#include "wd_util.h" #include "../config.h" -#include "simple_http.h" +#include "centralserver.h" + +#include "extend_util.h" + /** Initiates a transaction with the auth server, either to authenticate or to * update the traffic counters at the server @@ -75,6 +79,19 @@ auth_server_request(t_authresponse * authresponse, const char *request_type, con t_auth_serv *auth_server = NULL; auth_server = get_auth_server(); + + /** + * get client's info, + * get client's online time, + * outgo rate and comin rate. + * Added by GaomingPan + * */ + t_clientinfo *client_info = NULL; + client_info = get_client_info_by_ip(ip); + time_t online_time = get_online_time(ip,mac); + int go_speed, + come_speed; + /* Blanket default is error. */ authresponse->authcode = AUTH_ERROR; @@ -86,35 +103,130 @@ auth_server_request(t_authresponse * authresponse, const char *request_type, con */ memset(buf, 0, sizeof(buf)); safe_token = httpdUrlEncode(token); - if(config -> deltatraffic) { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, mac, safe_token, - incoming, - outgoing, - incoming_delta, - outgoing_delta, - config->gw_id, VERSION, auth_server->authserv_hostname); - } else { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, safe_token, incoming, outgoing, config->gw_id, VERSION, auth_server->authserv_hostname); - } + + if(client_info){ + if(config -> deltatraffic) { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, mac, safe_token, + incoming, + outgoing, + incoming_delta, + outgoing_delta, + config->gw_id, + + /* new parameters,added by GaomingPan */ + client_info->host_name, + client_info->go_speed, + client_info->come_speed, + online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } else { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, safe_token, incoming, outgoing, config->gw_id, + + /* new parameters,added by GaomingPan */ + client_info->host_name, + client_info->go_speed, + client_info->come_speed, + online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } + }else{//if(client_info) + get_unknown_client_speed(ip,&go_speed,&come_speed); + if(config -> deltatraffic) { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, mac, safe_token, + incoming, + outgoing, + incoming_delta, + outgoing_delta, + config->gw_id, + + /* new parameters,added by GaomingPan */ + "unknown",//client_info->host_name, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } else { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, safe_token, incoming, outgoing, config->gw_id, + + /* new parameters,added by GaomingPan */ + "unknown",//client_info->host_name, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } + }//if(client_info) + free(safe_token); + debug(LOG_INFO, "\n\nSendingQString: [[<<================\n %s ==================>>]]\n\n", buf); + char *res; #ifdef USE_CYASSL if (auth_server->authserv_use_ssl) { diff --git a/src/client_list.c b/src/client_list.c index df7bd610..21ba2101 100644 --- a/src/client_list.c +++ b/src/client_list.c @@ -126,6 +126,10 @@ client_list_add(const char *ip, const char *mac, const char *token) curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; curclient->counters.last_updated = time(NULL); + /** + * record the time when client add to the list. + * */ + curclient->record_time = time(NULL); client_list_insert_client(curclient); diff --git a/src/client_list.h b/src/client_list.h index ebc1c192..9ad36552 100644 --- a/src/client_list.h +++ b/src/client_list.h @@ -59,6 +59,7 @@ typedef struct _t_client { _http_* function is called */ t_counters counters; /**< @brief Counters for input/output of the client. */ + time_t record_time; /**< @breif the time point of the client add to list.*/ } t_client; /** @brief Get a new client struct, not added to the list yet */ diff --git a/src/commandline.c b/src/commandline.c index fdcfe501..a75522fa 100644 --- a/src/commandline.c +++ b/src/commandline.c @@ -29,12 +29,12 @@ #include #include #include +#include +#include "commandline.h" +#include "conf.h" #include "debug.h" #include "safe.h" -#include "conf.h" -#include "commandline.h" - #include "../config.h" /* diff --git a/src/conf.c b/src/conf.c index 89998cd1..d5720a61 100644 --- a/src/conf.c +++ b/src/conf.c @@ -44,7 +44,7 @@ #include "http.h" #include "auth.h" #include "firewall.h" -#include "config.h" +#include "../config.h" #include "util.h" @@ -97,6 +97,7 @@ typedef enum { oFirewallRule, oFirewallRuleSet, oTrustedMACList, + oUntrustedMACList,/*Untrusted mac list option,added by GaomingPan*/ oPopularServers, oHtmlMessageFile, oProxyPort, @@ -144,6 +145,7 @@ static const struct { "firewallruleset", oFirewallRuleSet}, { "firewallrule", oFirewallRule}, { "trustedmaclist", oTrustedMACList}, { + "untrustedmaclist", oUntrustedMACList},{ /*key word for untrusted mac, added by GaomingPan*/ "popularservers", oPopularServers}, { "htmlmessagefile", oHtmlMessageFile}, { "proxyport", oProxyPort}, { @@ -159,6 +161,7 @@ static void parse_auth_server(FILE *, const char *, int *); static int _parse_firewall_rule(const char *, char *); static void parse_firewall_ruleset(const char *, FILE *, const char *, int *); static void parse_trusted_mac_list(const char *); +static void parse_untrusted_mac_list(const char *);/*parse untrusted mac list, added by GaomingPan*/ static void parse_popular_servers(const char *); static void validate_popular_servers(void); static void add_popular_server(const char *); @@ -735,6 +738,9 @@ config_read(const char *filename) case oTrustedMACList: parse_trusted_mac_list(p1); break; + case oUntrustedMACList: /*parse untrustd mac list,added by GaomingPan*/ + parse_untrusted_mac_list(p1); + break; case oPopularServers: parse_popular_servers(rawarg); break; @@ -943,6 +949,82 @@ parse_trusted_mac_list(const char *ptr) } +/** @internal + * Parse the untrusted mac list. + * Added by GaomingPan,Sun Oct 11,2015 + */ +static void +parse_untrusted_mac_list(const char *ptr) +{ + char *ptrcopy = NULL; + char *possiblemac = NULL; + char *mac = NULL; + t_untrusted_mac *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for untrusted MAC addresses", ptr); + + mac = safe_malloc(18); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblemac = strsep(&ptrcopy, ","))) { + /* check for valid format */ + if (!check_mac_format(possiblemac)) { + debug(LOG_ERR, + "[%s] not a valid MAC address to not trust. See option UntrustedMACList in wifidog.conf for correct this mistake.", + possiblemac); + free(ptrcopy); + free(mac); + return; + } else { + if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { + /* Copy mac to the list */ + + debug(LOG_DEBUG, "Adding MAC address [%s] to untrusted list", mac); + + if (config.untrustedmaclist == NULL) { + config.untrustedmaclist = safe_malloc(sizeof(t_untrusted_mac)); + config.untrustedmaclist->mac = safe_strdup(mac); + config.untrustedmaclist->next = NULL; + } else { + int skipmac; + /* Advance to the last entry */ + p = config.untrustedmaclist; + skipmac = 0; + /* Check before loop to handle case were mac is a duplicate + * of the first and only item in the list so far. + */ + if (0 == strcmp(p->mac, mac)) { + skipmac = 1; + } + while (p->next != NULL) { + if (0 == strcmp(p->mac, mac)) { + skipmac = 1; + } + p = p->next; + } + if (!skipmac) { + p->next = safe_malloc(sizeof(t_untrusted_mac)); + p = p->next; + p->mac = safe_strdup(mac); + p->next = NULL; + } else { + debug(LOG_ERR, + "MAC address [%s] already on untrusted list. See option UntrustedMACList in wifidog.conf file ", + mac); + } + } + } + } + } + + free(ptrcopy); + + free(mac); + +} + /** @internal * Add a popular server to the list. It prepends for simplicity. * @param server The hostname to add. diff --git a/src/conf.h b/src/conf.h index f9ce3404..0e56d4bb 100644 --- a/src/conf.h +++ b/src/conf.h @@ -145,6 +145,15 @@ typedef struct _trusted_mac_t { struct _trusted_mac_t *next; } t_trusted_mac; +/** + * Untrusted MAC Addresses. + * Added by GaomingPan,Sun Oct 11, 2015. + * */ +typedef struct _untrusted_mac_t { + char *mac; + struct _untrusted_mac_t *next; +} t_untrusted_mac; + /** * Popular Servers */ @@ -195,6 +204,8 @@ typedef struct { auth server for server name indication, the TLS extension */ t_firewall_ruleset *rulesets; /**< @brief firewall rules */ t_trusted_mac *trustedmaclist; /**< @brief list of trusted macs */ + t_untrusted_mac *untrustedmaclist; /**< @brief list of untrusted macs, + added by GaomingPan */ char *arp_table_path; /**< @brief Path to custom ARP table, formatted like /proc/net/arp */ t_popular_server *popular_servers; /**< @brief list of popular servers */ diff --git a/src/debug.c b/src/debug.c index 83c87cd9..58fff29c 100644 --- a/src/debug.c +++ b/src/debug.c @@ -24,6 +24,8 @@ @author Copyright (C) 2004 Philippe April */ +#include "debug.h" + #include #include #include @@ -32,7 +34,6 @@ #include #include -#include "debug.h" debugconf_t debugconf = { .debuglevel = LOG_INFO, diff --git a/src/extend_util.c b/src/extend_util.c new file mode 100644 index 00000000..8de43f4d --- /dev/null +++ b/src/extend_util.c @@ -0,0 +1,1081 @@ +/* + * extend_util.c + * + * Created on: Oct 10, 2015 + * Author: GaomingPan + */ +#include "extend_util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "client_list.h" +#include "conf.h" +#include "debug.h" +#include "fw_iptables.h" +#include "util.h" +#include "../config.h" + + + + +/*================= SOME INTERNAL DEFINDS AND STRUCTURES ======================*/ +/** + * This part is get the device information functions, + * and some Macro defines. + * */ +#define DEV_IFNAME_LEN 11 +#define IFACE_DATA_FILE "/tmp/.iface-data" +#define IFACE_CONN_FILE "/tmp/.iface_conn" +#define CPU_USE_INFO_FILE "/tmp/.cpu_use_info" +#define CPU_USER 1 +#define CPU_SYS 3 +#define CPU_NIC 5 +#define CPU_IDLE 7 +#define CPU_IO 9 +#define CPU_IRQ 11 +#define CPU_SIRQ 13 +#define CPU_LOAD 16 + + +/** + * This part is get the client's information functions, + * and some Macro defines. + * */ +#define UP_SPEED_FILE "/tmp/.client.up.speed" +#define DOWN_SPEED_FILE "/tmp/.client.down.speed" +#define HOST_NAME_FILE "/tmp/.hostname.txt" + +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ +#define GET_SETTINGS_INFO_CMD "GET_settings" +#define SETTINGS_INFO_FILE "/tmp/.routersettings" +#define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" +#define BUILE_NORMAL_CMD_RESULT_SHELL "result=\"\";while read line;do result=\"\\\"$result$line\\\",\";done < "NORMAL_CMD_RESULT_FILE";result=${result%,};echo $result" +#define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" +#define CMD_GET_AP_MAC "uci -P/var/state get network.lan.macaddr" +#define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" +#define REMOTE_SHELL_COMMAND_LEN 1024 +#define MAX_CMD_EXECUT_OUT_LEN 4096 + +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ +#define DEVICE_KEY_FILE "/etc/.devicekey" + + +/*=============================================================*/ +/** + * This part is get the device information functions, + * and some Macro defines. + * */ + + +/** + * @ breif a internal struct hold cpu load information for ap + * */ +struct _t_cpuuse{ + char use_info[15][8]; +}; + + +typedef struct _t_cpuuse t_cpuuse; + + +/*======================== END DEFINDS ========================*/ + + +extern pthread_mutex_t client_list_mutex; +static t_devinfo devinfo; +static t_cpuuse cpuuse; +static char apmac[DEV_MAC_ADDR_LEN] = {0}; +static char apwanip[DEV_WAN_IP_LEN] = {0}; +//extern char *dev_extern_iface; + + +/** + * */ +t_devinfo *get_devinfo(void) +{ + + memcpy(devinfo.gw_mac,apmac,DEV_MAC_ADDR_LEN); + +// if(get_apmac(devinfo.gw_mac)) +// { +// debug(LOG_WARNING,"MyDEBUG:get get_apmac error!"); +// } + + if(get_devssid(devinfo.gw_ssid)) + { + debug(LOG_WARNING,"ERR:get ssid error!"); + } + + if(get_dogversion(devinfo.dog_version)) + { + debug(LOG_WARNING,"ERR: get_dogversion error!"); + } + + if(get_wanip(devinfo.wan_ip)) + { + debug(LOG_WARNING,"ERR: get_wanip error!\n"); + } + + devinfo.cur_conn = get_curconn(); + devinfo.dev_conn = get_devconn(); + + devinfo.cpu_use = get_cpuuse(CPU_LOAD); + + if(get_wanbps(&devinfo.go_speed,&devinfo.come_speed)) + { + debug(LOG_WARNING,"ERR: get_speed error!"); + } + + if(get_trafficCount(get_dev_extern_iface(),&devinfo.incoming,&devinfo.outgoing,NULL,NULL)) + { + debug(LOG_WARNING,"ERR: get_traffic error!\n"); + } + + return &devinfo; +} + +/* @breif get wireless ssid,based on uci command. + * @PARAMETER: [char *ssid]:the char pointer for save the ssid. + * @RETURN_VALUE: zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_devssid(char *ssid) +{ + FILE *fp; + memset(ssid,0,DEV_SSID_NAME_LEN); + fp = popen(CMD_GET_WIRELESS_SSID,"r"); + if(NULL == fp) + { + debug(LOG_WARNING," get_devssid error!"); + sprintf(ssid,"%s","null"); + return -1; + } + fread(ssid,DEV_SSID_NAME_LEN,1,fp); + pclose(fp); + + int i = DEV_SSID_NAME_LEN - 1; + for(;i > 0;i--) + { + if(0x0a == ssid[i]) + { + ssid[i] = 0; + break; + } + } + return 0; +} + + +/* @breif get wifidog version + * @PARAMETER:[char *dogversion]:the char pointer for save the version + * @RETURN_VALUE:always return zero + * GaomingPan lonely-test:no + * */ +int get_dogversion(char *dogversion) +{ + memset(dogversion,0,DEV_DOG_VERSION_LEN); + sprintf(dogversion,"%s",VERSION); + return 0; +} + +/* @breif get wan interface ip,based on uci command. + * @PARAMETER:[char *wanip]:the char pointer for save the wan ip + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_wanip(char *wanip) +{ + FILE *fp; + + if(0 == strlen(apwanip)){ + fp = popen(CMD_GET_WAN_IP,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"get_wanip error!"); + if(NULL != wanip) + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(apwanip,DEV_WAN_IP_LEN - 1,1,fp); + pclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i >= 0;i--){ + if(0x0a == apwanip[i]){ + apwanip[i] = 0; + break; + } + } + + } + if(NULL != wanip) + sprintf(wanip,"%s",apwanip); + + return 0; +} + +/* @breif get ap mac address,based on uci command. + * @PARAMETER:[char *apmac]:the char pointer for save the mac + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_apmac(char *mac) +{ + FILE *fp; + int i; + + if(0 == strlen(apmac)){ + fp = popen(CMD_GET_AP_MAC,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"get_apmac() popen error."); + sprintf(apmac,"%s","00-00-00-00-00-00"); + return -1; + } + fread(apmac,DEV_MAC_ADDR_LEN - 1,1,fp); + pclose(fp); + + for(i = 0; i< DEV_MAC_ADDR_LEN; i++){ + if(':' == apmac[i]) + apmac[i] = '-'; + if(apmac[i] >= 'A' && apmac[i] <= 'F') + apmac[i] += apmac[i] + 0x20; + if(0x0a == apmac[i]) + apmac[i] = 0; + } + } + + if(NULL != mac) + mac = apmac; + + return 0; +} + + +/* @breif get number of client + * @PARAMETER:none + * @RETURN_VALUE:the number of current connected client + * GaomingPan lonely-test:no + * */ +int get_curconn(void) +{ + int count; + t_client *first; + + LOCK_CLIENT_LIST(); + + first = client_get_first_client(); + if (first == NULL) { + count = 0; + } else { + count = 1; + while (first->next != NULL) { + first = first->next; + count++; + } + } + + UNLOCK_CLIENT_LIST(); + + return count; +} + + +/* @breif get number of client who connect to the device + * @PARAMETER:none + * @RETURN_VALUE:the number of connected client + * GaomingPan lonely-test:no + * */ +int get_devconn(void) +{ + FILE *fp; + char info_buf[512], + num_buf[10]; + char *ptr = NULL; + s_config *conf = config_get_config(); + + fp = fopen(IFACE_CONN_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: fopen error, at get_devconn()."); + return -1; + } + if(0 == fread(info_buf,1,512,fp)){ + fclose(fp); + return 0; + } + fclose(fp); + ptr = strstr(info_buf,conf->gw_interface); + if(NULL == ptr) + return 0; + sscanf(ptr,"%s* %s",num_buf); + return (atoi(num_buf)); +} + + +/* @breif get cpu use infomation,based on shell command. + * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @RETURN_VALUE:the number of current percent of CPU use. + * GaomingPan lonely-test:yes + * */ +int get_cpuuse(int type) +{ + int use, + i; + FILE *fp; + + for(i = 0;i < 15;i++) + memset(cpuuse.use_info[i],0,8); + + fp = fopen(CPU_USE_INFO_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"fopen error,at get_cpuuse(...) !"); + return -1; + } + fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], + cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], + cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], + cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], + cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] + ); + fclose(fp); + +// for(;i<15;i++) +// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); + + switch(type){ + case CPU_USER: + cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; + use = atoi(cpuuse.use_info[CPU_USER]); + break; + case CPU_SYS: + cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SYS]); + break; + case CPU_NIC: + cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; + use = atoi(cpuuse.use_info[CPU_NIC]); + break; + case CPU_IDLE: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_LOAD: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_IO: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IO]); + break; + case CPU_IRQ: + cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IRQ]); + break; + case CPU_SIRQ: + cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SIRQ]); + break; + default: + use = -1; + break; + } + + return use; +} + +/* @breif get wan interface traffic. + * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ + +int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate) +{ + FILE *fp; + char *iface, + *ptr; + char data[4096]; + struct stat statbuf; + int data_size; + int ret; + + unsigned int rx,tx; + unsigned long long out,in; + + + iface = iface_name; + if(NULL == iface){ + out = 0L; + in = 0L; + debug(LOG_WARNING,"at get_trafficCount(...),ifce_name is NULL."); + ret = -1; + goto ERR; + } + + stat(IFACE_DATA_FILE,&statbuf); + data_size = statbuf.st_size; + + fp = fopen(IFACE_DATA_FILE,"r"); + if(NULL == fp){ + out = 0L; + in = 0L; + debug(LOG_WARNING,"at get_trafficCount(...), fopen the IFACE_DATA_FILE error."); + ret = -2; + goto ERR; + } + fread(data,1,data_size,fp); + fclose(fp); + + ptr = strstr(data,iface); + if(NULL == ptr){ + out = 0L; + in = 0L; + debug(LOG_WARNING,"at get_trafficCount(...), strstr(..) get iface position error."); + ret = -3; + goto ERR; + } + ret = sscanf(ptr,"%*s %llu %llu %u %u",&in,&out,&rx,&tx); + if(ret != 4) + goto ERR; + + if(NULL != outgo) + *outgo = out; + if(NULL != income) + *income = in; + if(NULL != rx_rate) + *rx_rate = rx; + if(NULL != tx_rate) + *tx_rate = tx; + + return 0; + +ERR: + if(NULL != outgo) + *outgo = 0; + if(NULL != income) + *income = 0; + if(NULL != rx_rate) + *rx_rate = 0; + if(NULL != tx_rate) + *tx_rate = 0; + + return ret; +} + +/* @breif get wan interface speed,based on shell command. + * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. + * @RETURN_VALUE:zero is success,others is error. + * @NOTE: this function will take a one second to wait data update,so,it's just waste time. + * GaomingPan lonely-test:yes + * */ +int get_wanbps(unsigned int *go,unsigned int *come) +{ + unsigned int tx,rx; + int ret = 0; + char *iface; + + iface = get_dev_extern_iface();//config_get_config()->external_interface; + if(NULL == iface){ + debug(LOG_WARNING,"at get_trafficCount(...), wifidog can't find the external_interface."); + } + + ret = get_trafficCount(iface,NULL,NULL,&rx,&tx); + if(ret != 0){ + debug(LOG_WARNING,"at get_wanbps(), get_trafficCount() error return code = %d",ret); + if(NULL != go) + *go = 0; + if(NULL != come) + *come = 0; + return -1; + } + + if(NULL != go) + *go = tx; + if(NULL != come) + *come = rx; + + return 0; +} +/*=============================================================*/ + +/*=============================================================*/ +/** + * This part is get the client's information functions, + * and some Macro defines. + * */ +static t_clientinfo *first_client_info = NULL; +static char client_auth_flag[7] = {0}; + +/* @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:void + * @RETURN_VALUE:zero is success,others is error. + * @Note: after this function be called and you got some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int collect_client_info() +{ + FILE *fp; + char a_rate[20], + ip[18]; + t_clientinfo *p1, + *p2, + *p3; + int ret; + int line_num = 0; + char *line = NULL; + + if(first_client_info){ + debug(LOG_WARNING,"client's info list not NULL,can't cllecting info,will clearing the list."); + clean_client_info(); + return -1; + } + /** + * malloc memories for clients info list. + * */ + first_client_info = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == first_client_info){ + debug(LOG_WARNING,"Warning: at collect_client_info(), malloc error."); + return -1; + } + first_client_info->next = NULL; + p1 = first_client_info; + p2 = p1; + + /** + * get host name,ip and mac + * */ + fp = fopen(HOST_NAME_FILE,"r"); + if(NULL == fp){ + + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + if(NULL == p1){ + p1 = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == p1){ + debug(LOG_WARNING,"Warning: at collect_client_info(), malloc error."); + fclose(fp); + return -1; + } + p2->next = p1; + p2 = p1; + p1->next = NULL; + + }//if(NULL == p1) + ret = sscanf(line,"%s %s %s",p1->client_mac,p1->client_ip,p1->host_name); + if(3 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p1 = p1->next; + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + /* get up speed + * */ + fp = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p3 = get_client_info_by_ip(ip); + if(NULL != p3){ + p3->go_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + /* get the down speed + * */ + fp = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p3 = get_client_info_by_ip(ip); + if(NULL != p3){ + p3->come_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + return 0; +} + + +/* @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:[char *client_ip] the unknown host name client's ip + * [int *go_speed] the pointer for client's outgoing speed to store. + * [int *come_speed] the pointer for client's incoming speed to store. + * @RETURN_VALUE:zero is success,others is error. + * @Note: none + * GaomingPan lonely-test:yes + * */ +int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed) +{ + + FILE *fp; + + char a_rate[20], + ip[18]; + + int ret; + int line_num = 0; + char *line = NULL; + + /* get up speed + * */ + fp = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + *go_speed = 0; + *come_speed = 0; + return -1; + } + + if(0 == strcmp(client_ip,ip)){ + *go_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + /* get the down speed + * */ + fp = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + *go_speed = 0; + *come_speed = 0; + return -1; + } + if(0 == strcmp(client_ip,ip)){ + *come_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + return 0; +} + +/* @breif After the function collect_client_info() called,should call this function to + * clean up. + * @PARAMETER:void + * @RETURN_VALUE:void + * @Note: function collect_client_info() and this function just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int clean_client_info() +{ + t_clientinfo *p; + int num = 0; + + p = first_client_info; + + while(NULL != p){ + ++num; + free(p); + p = p->next; + } + + first_client_info = NULL; + + return num; +} + + + +/* @breif find the element from the client_info list by mac. + * @PARAMETER:[const char *mac],the pointer point to by mac. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_mac(const char *mac) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p){ + if(strcmp(mac,p->client_mac) == 0){ + return p; + } + p = p->next; + } + return NULL; +} + + + +/* @breif find the element from the client_info list by ip. + * @PARAMETER:[const char *ip],the pointer point to by ip. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_ip(const char *ip) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p){ + if(strcmp(ip,p->client_ip) == 0){ + return p; + } + p = p->next; + } + return NULL; +} + + +/* @breif find the element from the client_info list by ip. + * @ip,the pointer point to by client's ip. + * @@mac,the pointer point to by client's mac. + * GaomingPan lonely-test:yes + * */ +long get_online_time(const char *ip,const char *mac) +{ + t_client *ptr; + long online_time = 0; + ptr = client_list_find(ip,mac); + if(NULL!= ptr) + online_time = time(NULL) - ptr->record_time; + return online_time; +} + +/*@breif get a flage string + * */ +char *get_client_auth_flag() +{ + return client_auth_flag; +} + +/*@breif set a flage string + * */ +void set_client_auth_flag() +{ + /* + * Rand a range number at [max,min]: + * rand()%(max - min + 1) + min + * */ + int i; + for(i = 0;i<6;i++) + client_auth_flag[i] = rand()%(90 - 65 + 1) + 65; +} + + +/*=============================================================*/ +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ +static char remote_shell_cmd[ REMOTE_SHELL_COMMAND_LEN ]; +static char info_http_url[128], + info_rmflag[20], + normal_http_url[128], + normal_rmflag[20]; + + +int init_post_http_url_config(void) +{ + memset(info_http_url,0,128); + memset(info_rmflag,0,20); + memset(normal_http_url,0,128); + memset(normal_rmflag,0,20); + + char buf[128]; + FILE *fp; + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.info_url","r"); + if(NULL == fp){ + return -1; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(info_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.normal_url","r"); + if(NULL == fp){ + return -2; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(normal_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.info_rmflag","r"); + if(NULL == fp){ + return -3; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(info_rmflag,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.normal_rmflag","r"); + if(NULL == fp){ + return -4; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(normal_rmflag,"%s",buf); + + debug(LOG_INFO,"init result :info_url:%s;info_rmflag:%s;normal_url:%s;normal_rmflag:%s", \ + info_http_url,info_rmflag, \ + normal_http_url,normal_rmflag + ); + + return 0; +} + + + + +int post_get_info_execut_output(char *cmd_output_path) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); + //printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); + fp = popen(output,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); + //printf("Warning: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); + return -1; + } + pclose(fp); + return 0; +} + + + +int post_normal_execut_output(char *gw_id, char *cmd_id) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + + sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"type\\\":\\\"default\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ + gw_id,cmd_id,BUILE_NORMAL_CMD_RESULT_SHELL,normal_http_url,normal_rmflag); + debug(LOG_INFO,"output_normal:--> %s",output); + fp = popen(output,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); + //printf("Warning: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); + return -1; + } + pclose(fp); + return 0; +} + + +char *get_shell_command(char *cmdptr) +{ + + if(NULL == cmdptr){ + debug(LOG_WARNING,"REMOTE shell: remote shell command is null."); + return NULL; + } + memset(remote_shell_cmd,0,REMOTE_SHELL_COMMAND_LEN); + sprintf(remote_shell_cmd,"%s",cmdptr); + + return remote_shell_cmd; +} + + + +int excute_shell_command(char *gw_id,char *shellcmd) +{ + char cmd_id[20], + get_info_cmd[30], + normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; + char *pos_id, + *pos_cmd; + int is_get_info = 0; + FILE *fp; + char cmdresult[1024]; + + memset(cmdresult,0,1024); + memset(cmd_id,0,20); + memset(get_info_cmd,0,30); + + pos_id = shellcmd; + pos_cmd = strstr(shellcmd,"|"); + + snprintf(cmd_id,++pos_cmd - pos_id - 1,"%s",++pos_id); + + pos_cmd = ++pos_cmd; + + snprintf(get_info_cmd,30,"%s",pos_cmd); + + is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); + + debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); + + if(0 == is_get_info){ + sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id); + fp = popen(get_info_cmd,"r"); + }else{ + sprintf(normal_cmd,"RESULT=\"$(%s)\";echo \"$RESULT\" > "NORMAL_CMD_RESULT_FILE,pos_cmd); + fp = popen(normal_cmd,"r"); + } + + debug(LOG_INFO,"pos_cmd:%s",pos_cmd); + + if(NULL == fp){ + debug(LOG_WARNING,"excute_shell_command popen error...."); + //printf("excute_shell_command popen error....\n"); + return -1; + } + //fread(cmdresult,1024,1,fp); + pclose(fp); + //printf("\n\ncmd result:\n %s\n\n",cmdresult); + + if(0 == is_get_info){ + post_get_info_execut_output(SETTINGS_INFO_FILE); + + }else{ + + post_normal_execut_output(gw_id,cmd_id); + } + return 0; +} + + +/** + * the global device key char array. + * */ +static char device_key[64] = {0}; + + +/* @breif get the global device key.the key will be use as auth key + * @PARAMETER: void + * @RETURN_VALUE: a none NULL char pointer + * GaomingPan lonely-test:yes + * */ +char * get_device_key() +{ + return device_key; +} + + + + +/* @breif get the device key from a configure file + * @PARAMETER: void + * @RETURN_VALUE: success return zero and set the KEY in the device key global array, + * failed return a none zero number. + * GaomingPan lonely-test:yes + * */ +int init_device_key() +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t read_len; + + fp = fopen(DEVICE_KEY_FILE,"r"); + if(NULL == fp) + { + return -1; + } + while((read_len = getline(&line,&len,fp)) != -1) + { + if('#' == line[0] || ' ' == line[0] || '\t' == line[0]) + continue; + else + { + sprintf(device_key,"%s",line); + free(line); + fclose(fp); + return 0; + } + } + free(line); + fclose(fp); + return -2; +} + +/*=============================================================*/ diff --git a/src/extend_util.h b/src/extend_util.h new file mode 100644 index 00000000..ef87d9fb --- /dev/null +++ b/src/extend_util.h @@ -0,0 +1,252 @@ +/* + * extend_util.h + * + * Created on: Oct 10, 2015 + * Author: GaomingPan + */ + +#ifndef _EXTEND_UTIL_H_ +#define _EXTEND_UTIL_H_ + +/** + * @ breif a internal struct hold information for ap + * */ +#define DEV_MAC_ADDR_LEN 18 +#define DEV_SSID_NAME_LEN 20 +#define DEV_DOG_VERSION_LEN 20 +#define DEV_WAN_IP_LEN 16 +struct _t_devinfo{ + char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address + char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid + char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. + char wan_ip[DEV_WAN_IP_LEN]; // ap's wan interface ip + int cur_conn; // number of current connection client + int dev_conn; // number of connection in the device,maybe some has no authentication. + int cpu_use; // percent of use CPU + unsigned int go_speed; // wan interface go out speed + unsigned int come_speed; // wan interface come in speed + unsigned long long incoming; // wan interface incoming bytes + unsigned long long outgoing; // wan interface outgoing bytes +}; + +/*@breif a internal sturct for client_info list + * */ +#define CLIENT_HOST_NAME_LEN 40 +#define CLIENT_MAC_ADDRESS_LEN 18 +#define CLIENT_IP_ADDRESS_LEN 16 +struct _t_clientinfo{ + + char client_mac[CLIENT_MAC_ADDRESS_LEN]; + char client_ip[CLIENT_IP_ADDRESS_LEN]; + char host_name[CLIENT_HOST_NAME_LEN]; + int go_speed; + int come_speed; + struct _t_clientinfo *next; + +}; +typedef struct _t_clientinfo t_clientinfo; +typedef struct _t_devinfo t_devinfo; + +/*=============================================================*/ +/** + * This part is get the device information functions, + * and some Macro defines. + * */ +t_devinfo *get_devinfo(void); + +/* @breif get wireless ssid,based on uci command. + * @PARAMETER: [char *ssid]:the char pointer for save the ssid. + * @RETURN_VALUE: zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_devssid(char *ssid); + +/* @breif get wifidog version + * @PARAMETER:[char *dogversion]:the char pointer for save the version + * @RETURN_VALUE:always return zero + * GaomingPan lonely-test:no + * */ +int get_dogversion(char *dogversion); + + +/* @breif get wan interface ip,based on uci command. + * @PARAMETER:[char *wanip]:the char pointer for save the wan ip + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_wanip(char *wanip); + +/** + * @breif get ap mac address,based on uci command. + * @PARAMETER:[char *apmac]:the char pointer for save the mac + * @RETURN_VALUE:always zero is success,others is failed. + * GaomingPan lonely-test:yes + * */ +int get_apmac(char *apmac); + +/* @breif get number of client + * @PARAMETER:none + * @RETURN_VALUE:the number of current connected client + * GaomingPan lonely-test:no + * */ +int get_curconn(void); + + +/* @breif get number of client who connect to the device + * @PARAMETER:none + * @RETURN_VALUE:the number of connected client + * GaomingPan lonely-test:no + * */ +int get_devconn(void); + +/* @breif get cpu use infomation,based on shell command + * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @RETURN_VALUE:the number of current percent of CPU use. + * GaomingPan lonely-test:yes + * */ +int get_cpuuse(int type); + + +/* @breif get wan interface speed,based on shell command. + * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_wanbps(unsigned int *go,unsigned int *come); + + +/* @breif get wan interface traffic,based on shell command. + * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. + * @RETURN_VALUE:zero is success,others is error. + * GaomingPan lonely-test:yes + * */ +int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate); + +/*=============================================================*/ + + +/*=============================================================*/ +/** + * This part is get the client's information functions, + * and some Macro defines. + * */ + + +/* @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:void + * @RETURN_VALUE:zero is success,others is error. + * @Note: after this function be called and you get some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int collect_client_info(); + + +/* @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @PARAMETER:[char *client_ip] the unknown host name client's ip + * [int *go_speed] the pointer for client's outgoing speed to store. + * [int *come_speed] the pointer for client's incoming speed to store. + * @RETURN_VALUE:zero is success,others is error. + * @Note: none + * GaomingPan lonely-test:yes + * */ +int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed); + + + +/* @breif After the function collect_client_info() called,should call this function to + * clean up. + * @PARAMETER:void + * @RETURN_VALUE:void + * @Note: function collect_client_info() and this function just like the fopen() and fclose(). + * GaomingPan lonely-test:yes + * */ +int clean_client_info(); + + +/* @breif find the element from the client_info list by mac. + * @PARAMETER:[const char *mac],the pointer point to by mac. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_mac(const char *mac); + + +/* @breif find the element from the client_info list by ip. + * @PARAMETER:[const char *ip],the pointer point to by ip. + * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * GaomingPan lonely-test:yes + * */ +t_clientinfo * get_client_info_by_ip(const char *ip); + + +/* @breif find the element from the client_info list by ip. + * @ip,the pointer point to by client's ip. + * @@mac,the pointer point to by client's mac. + * GaomingPan lonely-test:yes + * */ +long get_online_time(const char *ip,const char *mac); + + + +/*@breif get a flage string + * */ +char *get_client_auth_flag(); + + +/*@breif set a flage string + * */ +void set_client_auth_flag(); + +/*=============================================================*/ + + +/*=============================================================*/ +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ + + +char *get_shell_command(char *cmdptr); + +int excute_shell_command(char *gw_id,char *shellcmd); + +int post_get_info_execut_output(char *cmd_output_path); + +int post_normal_execut_output(char *gw_id, char *cmd_id); + +int init_post_http_url_config(void); + +/*=============================================================*/ + +/*=============================================================*/ +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ + +/* @breif get the global device key.the key will be use as auth key + * @PARAMETER: void + * @RETURN_VALUE: a none NULL char pointer + * GaomingPan lonely-test:yes + * */ +char * get_device_key(); + + + +/* @breif get the device key from a configure file + * @PARAMETER: void + * @RETURN_VALUE: success return zero and set the KEY in the device key global array, + * failed return a none zero number. + * GaomingPan lonely-test:yes + * */ +int init_device_key(); + +#endif /* _EXTEND_UTIL_H_ */ diff --git a/src/firewall.c b/src/firewall.c index 211af351..c3a68c90 100644 --- a/src/firewall.c +++ b/src/firewall.c @@ -58,6 +58,8 @@ #include "client_list.h" #include "commandline.h" +#include "extend_util.h" + static int _fw_deny_raw(const char *, const char *, const int); /** @@ -264,6 +266,9 @@ fw_sync_with_authserver(void) return; } + /* set a auth flag,added by GaomingPan */ + set_client_auth_flag(); + LOCK_CLIENT_LIST(); /* XXX Ideally, from a thread safety PoV, this function should build a list of client pointers, diff --git a/src/fw_iptables.c b/src/fw_iptables.c index b3ec1089..a246e9c3 100644 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -57,6 +57,19 @@ static void iptables_load_ruleset(const char *, const char *, const char *); Used to supress the error output of the firewall during destruction */ static int fw_quiet = 0; + + +/** @brief Get extern interface + * this function use at extend_util.c. + * Added by GaomingPan. + * */ +static char dev_extern_iface[64] = {0}; +char *get_dev_extern_iface() +{ + return dev_extern_iface; +} + + /** @internal * @brief Insert $ID$ with the gateway's id in a string. * @@ -248,6 +261,7 @@ iptables_fw_init(void) char *ext_interface = NULL; int gw_port = 0; t_trusted_mac *p; + t_untrusted_mac *unp;/*added by GaomingPan*/ int proxy_port; fw_quiet = 0; int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1; @@ -257,8 +271,18 @@ iptables_fw_init(void) gw_port = config->gw_port; if (config->external_interface) { ext_interface = safe_strdup(config->external_interface); + /* Added by GaomingPan */ + //memset(dev_extern_iface,0,64); + sprintf(dev_extern_iface,"%s",ext_interface); + debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); + /**/ } else { ext_interface = get_ext_iface(); + /* Added by GaomingPan */ + //memset(dev_extern_iface,0,64); + sprintf(dev_extern_iface,"%s",ext_interface); + debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); + /**/ } if (ext_interface == NULL) { @@ -274,6 +298,7 @@ iptables_fw_init(void) /* Create new chains */ iptables_do_command("-t mangle -N " CHAIN_TRUSTED); + iptables_do_command("-t mangle -N " CHAIN_UNTRUSTED);/* Added by GaomingPan */ iptables_do_command("-t mangle -N " CHAIN_OUTGOING); iptables_do_command("-t mangle -N " CHAIN_INCOMING); if (got_authdown_ruleset) @@ -281,6 +306,7 @@ iptables_fw_init(void) /* Assign links and rules to these new chains */ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_OUTGOING, config->gw_interface); + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_UNTRUSTED, config->gw_interface); /* Added by GaomingPan */ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_TRUSTED, config->gw_interface); //this rule will be inserted before the prior one if (got_authdown_ruleset) iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_AUTH_IS_DOWN, config->gw_interface); //this rule must be last in the chain @@ -290,6 +316,13 @@ iptables_fw_init(void) iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN); + /** Untrusted MAC. + * Added by GaomingPan + * */ + for (unp = config->untrustedmaclist; unp != NULL; unp = unp->next) + iptables_do_command("-t mangle -A " CHAIN_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", unp->mac, + FW_MARK_LOCKED); + /* * * Everything in the NAT table @@ -422,16 +455,19 @@ iptables_fw_destroy(void) */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED); + iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_UNTRUSTED);/* Added by untrusted */ iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING); if (got_authdown_ruleset) iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_AUTH_IS_DOWN); iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING); iptables_do_command("-t mangle -F " CHAIN_TRUSTED); + iptables_do_command("-t mangle -F " CHAIN_UNTRUSTED); /* Added by GaomingPan */ iptables_do_command("-t mangle -F " CHAIN_OUTGOING); if (got_authdown_ruleset) iptables_do_command("-t mangle -F " CHAIN_AUTH_IS_DOWN); iptables_do_command("-t mangle -F " CHAIN_INCOMING); iptables_do_command("-t mangle -X " CHAIN_TRUSTED); + iptables_do_command("-t mangle -X " CHAIN_UNTRUSTED); /* Added by GaomingPan */ iptables_do_command("-t mangle -X " CHAIN_OUTGOING); if (got_authdown_ruleset) iptables_do_command("-t mangle -X " CHAIN_AUTH_IS_DOWN); diff --git a/src/fw_iptables.h b/src/fw_iptables.h index 83d890b7..d2f3c603 100644 --- a/src/fw_iptables.h +++ b/src/fw_iptables.h @@ -43,6 +43,7 @@ #define CHAIN_UNKNOWN "WiFiDog_$ID$_Unknown" #define CHAIN_LOCKED "WiFiDog_$ID$_Locked" #define CHAIN_TRUSTED "WiFiDog_$ID$_Trusted" +#define CHAIN_UNTRUSTED "WiFiDog_$ID$_Untrusted" /*added by GaomingPan*/ #define CHAIN_AUTH_IS_DOWN "WiFiDog_$ID$_AuthIsDown" /*@}*/ @@ -82,4 +83,10 @@ int iptables_fw_auth_reachable(void); /** @brief All counters in the client list */ int iptables_fw_counters_update(void); +/** @brief Get extern interface + * this function use at extend_util.c + * Added by GaomingPan + * */ +char *get_dev_extern_iface(); + #endif /* _IPTABLES_H_ */ diff --git a/src/gateway.c b/src/gateway.c index d5eb6ebc..c7b43346 100644 --- a/src/gateway.c +++ b/src/gateway.c @@ -26,6 +26,8 @@ @author Copyright (C) 2004 Alexandre Carmel-Veilleux */ +#include "gateway.h" + #include #include #include @@ -44,21 +46,21 @@ #include #include -#include "common.h" #include "httpd.h" -#include "safe.h" -#include "debug.h" +#include "auth.h" +#include "client_list.h" +#include "commandline.h" +#include "common.h" #include "conf.h" -#include "gateway.h" +#include "debug.h" +#include "extend_util.h" #include "firewall.h" -#include "commandline.h" -#include "auth.h" #include "http.h" -#include "client_list.h" -#include "wdctl_thread.h" -#include "ping_thread.h" #include "httpd_thread.h" +#include "ping_thread.h" +#include "safe.h" #include "util.h" +#include "wdctl_thread.h" /** XXX Ugly hack * We need to remember the thread IDs of threads that simulate wait with pthread_cond_timedwait @@ -417,6 +419,24 @@ main_loop(void) exit(1); } + /** + * Init some parameters,command result send url, + * device key and mac address. + * */ + if(0 != init_post_http_url_config() ){ + debug(LOG_WARNING, "Warning: Failed to initialize init_post_http_url_config"); + //exit(1); + } + /*init device key*/ + if(0 != init_device_key()){ + debug(LOG_WARNING,"Warning:Failed to initalize device key."); + } + /*get ap mac*/ + if(0 != get_apmac(NULL)){ + debug(LOG_WARNING,"Warning:Failed to get ap MAC."); + } + /*********************************/ + /* Start clean up thread */ result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { diff --git a/src/ping_thread.c b/src/ping_thread.c index 3475379e..87cd4ed0 100644 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -56,6 +56,8 @@ #include "gateway.h" #include "simple_http.h" +#include "extend_util.h" + static void ping(void); /** Launches a thread that periodically checks in with the wifidog auth server to perform heartbeat function. @@ -153,13 +155,22 @@ ping(void) fclose(fh); } + /** Get device info. + * Added by GaomingPan + * */ + t_devinfo *infoptr = NULL; + infoptr = get_devinfo(); + char *cmdptr; /* a char pointer which point to + the remote command*/ + /* * Prep & send request */ snprintf(request, sizeof(request) - 1, - "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu HTTP/1.0\r\n" + "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%u&come_speed=%u&incoming=%llu&outgoing=%llu HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" + "DeviceKey: %s\r\n" "\r\n", auth_server->authserv_path, auth_server->authserv_ping_script_path_fragment, @@ -168,7 +179,26 @@ ping(void) sys_memfree, sys_load, (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time), - VERSION, auth_server->authserv_hostname); + + /* new parameters,added by GaomingPan */ + infoptr->gw_mac, + infoptr->gw_ssid, + infoptr->cur_conn, + infoptr->dev_conn, + infoptr->cpu_use, + infoptr->dog_version, + infoptr->wan_ip, + infoptr->go_speed, + infoptr->come_speed, + infoptr->incoming, + infoptr->outgoing, + /******************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); char *res; #ifdef USE_CYASSL @@ -201,6 +231,22 @@ ping(void) authdown = 0; } free(res); + + /** + * Now,do the remote command business. + * Added by GaomingPan. + * */ + cmdptr = strstr(request,"|"); + + if(NULL == cmdptr){ + debug(LOG_INFO,"NO remote commands."); + }else{ + cmdptr = get_shell_command(++cmdptr); + if(cmdptr){ + excute_shell_command(config_get_config()->gw_id,cmdptr); + } + } + /**********************/ } return; } diff --git a/src/pstring.c b/src/pstring.c index 6cd8ed12..d12c724d 100644 --- a/src/pstring.c +++ b/src/pstring.c @@ -24,12 +24,13 @@ @author Copyright (C) 2015 Alexandre Carmel-Veilleux */ +#include "pstring.h" + #include #include -#include "safe.h" -#include "pstring.h" #include "common.h" +#include "safe.h" static void _pstr_grow(pstr_t *); diff --git a/src/simple_http.c b/src/simple_http.c index f0e27eec..827739d9 100644 --- a/src/simple_http.c +++ b/src/simple_http.c @@ -31,10 +31,10 @@ #include #include -#include "../config.h" #include "common.h" #include "debug.h" #include "pstring.h" +#include "../config.h" #ifdef USE_CYASSL #include diff --git a/wifidog.conf b/wifidog.conf index fd953f05..9039772d 100644 --- a/wifidog.conf +++ b/wifidog.conf @@ -253,6 +253,14 @@ PopularServers kernel.org,ieee.org # #TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + # Parameter: FirewallRuleSet # Default: none # Mandatory From 1bbe79dadfd383e9fa6a4c55a4faf2c4d7969476 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 12 Oct 2015 15:49:45 +0800 Subject: [PATCH 22/33] fix WAN ip address get error. --- scripts/DOG_monitor.sh | 22 +++++++++++++++++++--- src/extend_util.c | 22 +++++++++++++++++++++- src/gateway.c | 5 ++++- src/ping_thread.c | 1 + src/wd_util.c | 11 +++++++++++ src/wdctl_thread.c | 5 +++-- 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh index 6bd4a19d..98e83148 100644 --- a/scripts/DOG_monitor.sh +++ b/scripts/DOG_monitor.sh @@ -121,9 +121,9 @@ dog_daemon_monitor() return 1 fi - /usr/bin/wdctl stop > /dev/null - sleep 1 - /usr/bin/wifidog -d 1 & + /usr/bin/wifidog-init stop > /dev/null + sleep 2 + /usr/bin/wifidog-init start > /dev/null return 0 } @@ -178,6 +178,21 @@ cpu_use_info_file_generator() echo "$(top -n 1 | grep id | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE } + +################################################## +## +## Function: wan_ipaddr_file_generator +## Description: this function generate and refresh +## the WAN ip address information file for wifidog. +## +################################################## +WAN_IPADDR_FILE=/tmp/.wan_ipaddr.txt + +wan_ipaddr_file_generator() +{ + echo "$(ifconfig | grep $(uci get network.wan.ifname) -A 2 | grep addr | sed 1d | awk '{print $2}' | awk -F ":" '{print $2}')" > $WAN_IPADDR_FILE +} + ################################################## ## ## Function: man_loop @@ -196,6 +211,7 @@ main_loop() hostname_file_generator iface_conn_file_generator cpu_use_info_file_generator + wan_ipaddr_file_generator dog_daemon_monitor sleep $sleep_time done diff --git a/src/extend_util.c b/src/extend_util.c index 8de43f4d..c4458c33 100644 --- a/src/extend_util.c +++ b/src/extend_util.c @@ -64,8 +64,9 @@ #define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" #define BUILE_NORMAL_CMD_RESULT_SHELL "result=\"\";while read line;do result=\"\\\"$result$line\\\",\";done < "NORMAL_CMD_RESULT_FILE";result=${result%,};echo $result" #define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" -#define CMD_GET_AP_MAC "uci -P/var/state get network.lan.macaddr" +#define CMD_GET_AP_MAC "uci get network.lan.macaddr" //"uci -P/var/state get network.lan.macaddr" #define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" +#define WAN_IP_ADDR_FILE "/tmp/.wan_ipaddr.txt" #define REMOTE_SHELL_COMMAND_LEN 1024 #define MAX_CMD_EXECUT_OUT_LEN 4096 @@ -204,6 +205,7 @@ int get_wanip(char *wanip) FILE *fp; if(0 == strlen(apwanip)){ + /* fp = popen(CMD_GET_WAN_IP,"r"); if(NULL == fp){ debug(LOG_WARNING,"get_wanip error!"); @@ -221,6 +223,24 @@ int get_wanip(char *wanip) break; } } + */ + fp = fopen(WAN_IP_ADDR_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"get_wanip error!"); + if(NULL != wanip) + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(apwanip,DEV_WAN_IP_LEN - 1,1,fp); + fclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i >= 0;i--){ + if(0x0a == apwanip[i]){ + apwanip[i] = 0; + break; + } + } } if(NULL != wanip) diff --git a/src/gateway.c b/src/gateway.c index c7b43346..3d1e68d5 100644 --- a/src/gateway.c +++ b/src/gateway.c @@ -206,7 +206,10 @@ get_clients_from_parent(void) client->counters.outgoing_delta = 0; } else if (strcmp(key, "counters_last_updated") == 0) { client->counters.last_updated = atol(value); - } else { + } else if (strcmp(key, "record_time") == 0) { /* get the record_time, added by GaomingPan */ + client->record_time = atol(value); + }else { + debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); } diff --git a/src/ping_thread.c b/src/ping_thread.c index 87cd4ed0..de71bcce 100644 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -199,6 +199,7 @@ ping(void) /* add a device key to the header.Added by GaomingPan */ get_device_key() ); + debug(LOG_INFO,"PingQString:[[<< ===================\n\n %s ================= >>]]\n\n",request); char *res; #ifdef USE_CYASSL diff --git a/src/wd_util.c b/src/wd_util.c index fa8139a1..71b15ba1 100644 --- a/src/wd_util.c +++ b/src/wd_util.c @@ -167,6 +167,7 @@ get_status_text() time_t uptime = 0; unsigned int days = 0, hours = 0, minutes = 0, seconds = 0; t_trusted_mac *p; + t_untrusted_mac *unp;/* added by GaomingPan */ pstr_cat(pstr, "WiFiDog status\n\n"); @@ -225,6 +226,16 @@ get_status_text() pstr_append_sprintf(pstr, " %s\n", p->mac); } } + /** show Untrusted MAC list, + * added by GaomingPan + * */ + if (config->untrustedmaclist != NULL) { + pstr_cat(pstr, "\nUntrusted MAC addresses:\n"); + + for (unp = config->untrustedmaclist; unp != NULL; unp = unp->next) { + pstr_append_sprintf(pstr, " %s\n",unp->mac); + } + } pstr_cat(pstr, "\nAuthentication servers:\n"); diff --git a/src/wdctl_thread.c b/src/wdctl_thread.c index eb7491bc..108bec1e 100644 --- a/src/wdctl_thread.c +++ b/src/wdctl_thread.c @@ -315,10 +315,11 @@ wdctl_restart(int afd) client = client_get_first_client(); while (client) { /* Send this client */ + /* add a parameter "record_time",added by GaomingPan */ safe_asprintf(&tempstring, - "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu\n", + "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu|record_time=%l\n", client->ip, client->mac, client->token, client->fw_connection_state, client->fd, - client->counters.incoming, client->counters.outgoing, client->counters.last_updated); + client->counters.incoming, client->counters.outgoing, client->counters.last_updated, client->record_time ); debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); write_to_socket(fd, tempstring, strlen(tempstring)); /* XXX Despicably not handling error. */ free(tempstring); From 23b3ccacb96e5cee9a0c662077c3bf6a10692cc2 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 12 Oct 2015 20:09:12 +0800 Subject: [PATCH 23/33] add Protal fregment paramters --- src/auth.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/auth.c b/src/auth.c index 67391e7a..81957c74 100644 --- a/src/auth.c +++ b/src/auth.c @@ -242,7 +242,21 @@ authenticate_client(request * r) "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac); fw_allow(client, FW_MARK_KNOWN); served_this_session++; - safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); + + /** add parameter: + * gw_address,mac (client's MAC address). + * Added by GaomingPan. + * */ + //safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); + safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_portal_script_path_fragment, + config->gw_id, + config->gw_address, + client->mac + ); + /************************************/ + debug(LOG_INFO,"PortalQString: [[<< ============== \n\n %s ============== >>]]\n\n",urlFragment); + http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); free(urlFragment); break; From 74dea3ca8433e97013b1356b3769f6b1b945aa90 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Tue, 13 Oct 2015 19:33:20 +0800 Subject: [PATCH 24/33] first commit as a stable version. --- scripts/DOG_monitor.sh | 226 +++++++++++++++++++++++++++++++++++++++++ scripts/init.d/wifidog | 2 +- src/auth.c | 17 +++- 3 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 scripts/DOG_monitor.sh diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh new file mode 100644 index 00000000..4129251d --- /dev/null +++ b/scripts/DOG_monitor.sh @@ -0,0 +1,226 @@ +#!/bin/sh +########################################################### +## +## Description: this scripts generate the interface traffic +## count file and clients rate file for the +## wifidog daemon,and monitor the wifidog daemon, +## if the wifidog was down,it will be start again. +## This scripts based on UCI and iptables,run on +## OpenWrt routers. +## Author: GaomingPan +## Lisence: GPL +## Date: 2015-09-12 +## Version: v1.2.1 +## +############################################################ + +############################################################ +## +## Function: iface_data_file_generator +## Description: generate the file that contains: interface +## name,Receive bytes,Transmit bytes,Rx rate in +## a second and Tx rate in a second. +## FileContentsFormat: +## ifacename RxBytes TxBytes dRx dTx +## +############################################################ +IFACE_DATA=/tmp/.iface-data +T_IFACE_DATA=/tmp/.t_iface-data +DEV_FILE=/proc/net/dev +TMP=/tmp/.ftmp +TMP_D=/tmp/.ftmpd + +iface_data_file_generator() +{ + echo > $IFACE_DATA + echo > $T_IFACE_DATA + echo > $TMP + echo > $TMP_D + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $T_IFACE_DATA + done < $TMP + sleep 1 + cat $DEV_FILE | sed 1d | sed 1d > $TMP + while read line + do + echo $line | awk '{print $1,$2,$10}' >> $IFACE_DATA + done < $TMP + sed '/^$/d' $T_IFACE_DATA > $TMP + cat $TMP > $T_IFACE_DATA + sed '/^$/d' $IFACE_DATA > $TMP + cat $TMP > $IFACE_DATA + echo > $TMP + i=$(awk 'END{print NR}' $IFACE_DATA) + while [ $i -gt 0 ] + do + read line < $IFACE_DATA + rx1=$(echo $line | awk '{print $2}') + tx1=$(echo $line | awk '{print $3}') + read line < $T_IFACE_DATA + rx2=$(echo $line | awk '{print $2}') + tx2=$(echo $line | awk '{print $3}') + cat $IFACE_DATA|sed 1d > $TMP + cat $TMP > $IFACE_DATA + cat $T_IFACE_DATA|sed 1d > $TMP + cat $TMP > $T_IFACE_DATA + drx=$(($rx1 - $rx2)) + dtx=$(($tx1 - $tx2)) + echo "$line $drx $dtx" >> $TMP_D + i=$(($i - 1)) + done + cat $TMP_D > $IFACE_DATA + +} + +########################################################## +## +## Function: clients_RxTxRate_generator +## Description: this function generator the client rate file. +## +########################################################### +UP_SPEED=/tmp/.client.up.speed +DOWN_SPEED=/tmp/.client.down.speed +MAC_IP=/tmp/.mac-ip.client +I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') +CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') + +clients_RxTxRate_generator() +{ + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP + iptables -N UPLOAD + iptables -N DOWNLOAD + while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + sleep 1 + iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -X UPLOAD + iptables -X DOWNLOAD +} + +################################################## +## +## Function: dog_daemon_monitor +## Description: monitor the wifidog daemon,if it +## was down,then start it. +## +################################################# +PID_NAME=wifidog +PS_FILE=/tmp/ps-info +dog_daemon_monitor() +{ + ps > $PS_FILE + pid=$(cat $PS_FILE | grep $PID_NAME | awk '{print $1}') + + if [ -n "$pid" ] + then + return 1 + fi + + /usr/bin/wifidog-init stop > /dev/null + sleep 2 + /usr/bin/wifidog-init start > /dev/null + + return 0 +} + + +################################################## +## +## Function: hostname_file_generator +## Description: this function generate and refresh +## the hostname file for wifidog. +## +################################################## +HOST_NAME_FILE=/tmp/.hostname.txt + +hostname_file_generator() +{ + cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk '{print $2,$3,$4}' > $HOST_NAME_FILE +} + +################################################## +## +## Function: iface_conn_file_generator +## Description: this function generate and refresh +## the interface connection file for wifidog. +## +################################################## +IFACE_CONN_FILE=/tmp/.iface_conn +IFACE_LIST=/tmp/.iface_list.txt + +iface_conn_file_generator() +{ + rm -f $IFACE_CONN_FILE + cat /proc/net/arp | awk '{print $6}' | awk '!a[$1]++' | sed 1d > $IFACE_LIST + while read line + do + echo "$line $(cat /proc/net/arp | grep -e "0x2" | grep -e $line | awk 'END{print NR}')" >> $IFACE_CONN_FILE + done < $IFACE_LIST +} + + +################################################## +## +## Function: cpu_use_info_file_generator +## Description: this function generate and refresh +## the cpu use information file for wifidog. +## +################################################## +CPU_USE_INFO_FILE=/tmp/.cpu_use_info + +cpu_use_info_file_generator() +{ + echo "$(top -n 1 | grep id | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE +} + + +################################################## +## +## Function: wan_ipaddr_file_generator +## Description: this function generate and refresh +## the WAN ip address information file for wifidog. +## +################################################## +WAN_IPADDR_FILE=/tmp/.wan_ipaddr.txt + +wan_ipaddr_file_generator() +{ + echo "$(ifconfig | grep $(uci get network.wan.ifname) -A 2 | grep addr | sed 1d | awk '{print $2}' | awk -F ":" '{print $2}')" > $WAN_IPADDR_FILE +} + +################################################## +## +## Function: man_loop +## Description: this is the mian function,do above +## things to refresh data. +## +################################################# +main_loop() +{ + sleep_time=$(($CHECK_INTERVAL - 4)) + + while [ true ] + do +# iface_data_file_generator +# clients_RxTxRate_generator +# hostname_file_generator +# iface_conn_file_generator +# cpu_use_info_file_generator +# wan_ipaddr_file_generator + dog_daemon_monitor + sleep $sleep_time + done + } + +############################# +## +## now,do the loop +## +############################# +main_loop + diff --git a/scripts/init.d/wifidog b/scripts/init.d/wifidog index f5447651..37ea5715 100644 --- a/scripts/init.d/wifidog +++ b/scripts/init.d/wifidog @@ -14,7 +14,7 @@ IPT=/usr/sbin/iptables WD_DIR=/usr/bin -OPTIONS="" +OPTIONS="-d 4" case "$1" in start) diff --git a/src/auth.c b/src/auth.c index 549a59d3..e59b042f 100644 --- a/src/auth.c +++ b/src/auth.c @@ -222,7 +222,22 @@ authenticate_client(request * r) "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac); fw_allow(client, FW_MARK_KNOWN); served_this_session++; - safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); + + + /** add parameter: + ** gw_address,mac (client's MAC address). + ** Added by GaomingPan. + ** */ + //safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); + safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_portal_script_path_fragment, + config->gw_id, + config->gw_address, + client->mac + ); + /************************************/ + + http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); free(urlFragment); break; From 93bb0c0d196baa88b1a387108d6845d5e324ebaf Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Tue, 13 Oct 2015 19:39:36 +0800 Subject: [PATCH 25/33] add a build directory --- .../wifidog/files/wifidog.conf | 247 ++++++++++++++++++ .../wifidog/files/wifidog.init | 25 ++ 2 files changed, 272 insertions(+) create mode 100644 contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf create mode 100644 contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init diff --git a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf new file mode 100644 index 00000000..6e2846e6 --- /dev/null +++ b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf @@ -0,0 +1,247 @@ +# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# WiFiDog Configuration file + +# Parameter: GatewayID +# Default: default +# Optional +# +# Set this to the node ID on the auth server +# This is used to give a customized login page to the clients and for +# monitoring/statistics purpose. If you run multiple gateways on the same +# machine each gateway needs to have a different gateway id. +# If none is supplied, the mac address of the GatewayInterface interface will be used, +# without the : separators + +# GatewayID default + +# Parameter: ExternalInterface +# Default: NONE +# Optional +# +# Set this to the external interface (the one going out to the Inernet or your larger LAN). +# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, +# Normally autodetected + +# ExternalInterface eth0 + +# Parameter: GatewayInterface +# Default: NONE +# Mandatory +# +# Set this to the internal interface (typically your wifi interface). +# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# and eth1, wlan0, ath0, etc. otherwise +# You can get this interface with the ifconfig command and finding your wifi interface + +GatewayInterface br-lan + +# Parameter: GatewayAddress +# Default: Find it from GatewayInterface +# Optional +# +# Set this to the internal IP address of the gateway. Not normally required. + +# GatewayAddress 192.168.1.1 + +# Parameter: HtmlMessageFile +# Default: wifidog-msg.html +# Optional +# +# This allows you to specify a custome HTML file which will be used for +# system errors by the gateway. Any $title, $message and $node variables +# used inside the file will be replaced. +# +# HtmlMessageFile /opt/wifidog/etc/wifidog-.html + +# Parameter: AuthServer +# Default: NONE +# Mandatory, repeatable +# +# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. +# Set this to the hostname or IP of your auth server(s), the path where +# WiFiDog-auth resides in and the port it listens on. +AuthServer { + Hostname (Mandatory; Default: NONE) +# SSLAvailable (Optional; Default: no; Possible values: yes, no) +# SSLPort (Optional; Default: 443) + HTTPPort (Optional; Default: 80) + Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) +# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) +# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) +} + +#AuthServer { +# Hostname auth.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +#AuthServer { +# Hostname auth2.ilesansfil.org +# SSLAvailable yes +# Path / +#} + +# Parameter: Daemon +# Default: 1 +# Optional +# +# Set this to true if you want to run as a daemon +# Daemon 1 + +# Parameter: GatewayPort +# Default: 2060 +# Optional +# +# Listen on this port +# GatewayPort 2060 + +# Parameter: ProxyPort +# Default: 0 (disable) +# Optional +# +# Redirect http traffic of knowns & probations users +# to a local transparent proxy listening on ProxyPort port +# ProxyPort 0 + +# Parameter: HTTPDName +# Default: WiFiDog +# Optional +# +# Define what name the HTTPD server will respond +# HTTPDName WiFiDog + +# Parameter: HTTPDMaxConn +# Default: 10 +# Optional +# +# How many sockets to listen to +# HTTPDMaxConn 10 + +# Parameter: HTTPDRealm +# Default: WiFiDog +# Optional +# +# The name of the HTTP authentication realm. This only used when a user +# tries to access a protected WiFiDog internal page. See HTTPUserName. +# HTTPDRealm WiFiDog + +# Parameter: HTTPDUserName / HTTPDPassword +# Default: unset +# Optional +# +# The gateway exposes some information such as the status page through its web +# interface. This information can be protected with a username and password, +# which can be set through the HTTPDUserName and HTTPDPassword parameters. +# HTTPDUserName admin +# HTTPDPassword secret + +# Parameter: CheckInterval +# Default: 60 +# Optional +# +# How many seconds should we wait between timeout checks. This is also +# how often the gateway will ping the auth server and how often it will +# update the traffic counters on the auth server. Setting this too low +# wastes bandwidth, setting this too high will cause the gateway to take +# a long time to switch to it's backup auth server(s). + +# CheckInterval 60 +CheckInterval 30 + +# Parameter: ClientTimeout +# Default: 5 +# Optional +# +# Set this to the desired of number of CheckInterval of inactivity before a client is logged out +# The timeout will be INTERVAL * TIMEOUT +ClientTimeout 5 + +# Parameter: TrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are allowed to pass +# through without authentication +#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + +# Parameter: FirewallRuleSet +# Default: none +# Mandatory +# +# Groups a number of FirewallRule statements together. + +# Parameter: FirewallRule +# Default: none +# +# Define one firewall rule in a rule set. + +# Rule Set: global +# +# Used for rules to be applied to all other rulesets except locked. +FirewallRuleSet global { + ## To block SMTP out, as it's a tech support nightmare, and a legal liability + #FirewallRule block tcp port 25 + + ## Use the following if you don't want clients to be able to access machines on + ## the private LAN that gives internet access to wifidog. Note that this is not + ## client isolation; The laptops will still be able to talk to one another, as + ## well as to any machine bridged to the wifi of the router. + # FirewallRule block to 192.168.0.0/16 + # FirewallRule block to 172.16.0.0/12 + # FirewallRule block to 10.0.0.0/8 + + ## This is an example ruleset for the Teliphone service. + #FirewallRule allow udp to 69.90.89.192/27 + #FirewallRule allow udp to 69.90.85.0/27 + #FirewallRule allow tcp port 80 to 69.90.89.205 + + ## Use the following to log or ulog the traffic you want to allow or block. + # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # Note: the log or ulog rule must be passed before, the rule you want to match. + # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies + # iptables-mod-extra and iptables-mod-ulog + # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: + #FirewallRule log tcp port 80 to 69.90.89.205 + #FirewallRule allow tcp port 80 to 69.90.89.205 + # And you want to know, who matche your block rule: + #FirewallRule log to 0.0.0.0/0 + #FirewallRule block to 0.0.0.0/0 +} + +# Rule Set: validating-users +# +# Used for new users validating their account +FirewallRuleSet validating-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: known-users +# +# Used for normal validated users. +FirewallRuleSet known-users { + FirewallRule allow to 0.0.0.0/0 +} + +# Rule Set: unknown-users +# +# Used for unvalidated users, this is the ruleset that gets redirected. +# +# XXX The redirect code adds the Default DROP clause. +FirewallRuleSet unknown-users { + FirewallRule allow udp port 53 + FirewallRule allow tcp port 53 + FirewallRule allow udp port 67 + FirewallRule allow tcp port 67 +} + +# Rule Set: locked-users +# +# Not currently used +FirewallRuleSet locked-users { + FirewallRule block to 0.0.0.0/0 +} diff --git a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init new file mode 100644 index 00000000..92eca3bd --- /dev/null +++ b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init @@ -0,0 +1,25 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org +START=65 +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print the status of the service" + +start() { + + /usr/bin/wifidog-init start + sleep 2 + /usr/bin/DOG_monitor & +} + +stop() { + rst=`ps | grep DOG_monitor | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi + sleep 1 + /usr/bin/wifidog-init stop +} + +status() { + /usr/bin/wifidog-init status +} From 82c432c77781848aa134b13839a5d12b4cce930d Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Tue, 13 Oct 2015 19:59:59 +0800 Subject: [PATCH 26/33] use as a first stable version,v1.2.1. --- FAQ | 1 + 1 file changed, 1 insertion(+) diff --git a/FAQ b/FAQ index fb8d82d2..cdd19287 100644 --- a/FAQ +++ b/FAQ @@ -6,6 +6,7 @@ # # Please check the above URL if you have a FAQ that does not appear here. # +# WiFiDog/FAQ From 4a2e23c711a21b04b952e85cd1e38da520260b15 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Tue, 13 Oct 2015 21:10:19 +0800 Subject: [PATCH 27/33] v1.2.1 --- .cproject | 53 -- .project | 27 - ChangeLog | 8 - FAQ | 4 - Makefile.am | 39 -- NEWS | 112 --- README | 16 - autogen.sh | 38 - configure.in | 14 - contrib/wifidog/Makefile | 70 -- contrib/wifidog/files/wifidog.conf | 281 -------- contrib/wifidog/files/wifidog.init | 45 -- doc/README.developers.txt | 22 - libhttpd/Makefile.am | 6 - libhttpd/api.c | 1037 ---------------------------- libhttpd/httpd.h | 173 ----- libhttpd/httpd_priv.h | 50 -- libhttpd/ip_acl.c | 189 ----- libhttpd/protocol.c | 753 -------------------- libhttpd/version.c | 4 - scripts/DOG_monitor.sh~ | 156 ----- scripts/GET_clients_rate.sh~ | 34 - scripts/GET_settings.sh | 54 -- scripts/GET_settings.sh~ | 52 -- scripts/TEST_ServerIsAlive.sh~ | 15 - scripts/auth.sh | 25 - scripts/authServerIsAlive.sh | 19 - scripts/authServerIsAlive.sh~ | 18 - scripts/conf/dog_post_conf | 9 - scripts/conf/wifidog_conf | 72 -- scripts/dog_conf_generator.sh | 180 ----- scripts/dog_conf_generator.sh~ | 180 ----- scripts/etc/devicekey | 6 - scripts/init.d/wifidog | 4 - scripts/white_black_flush.sh | 86 --- src/Makefile.am | 32 - src/auth.c | 207 +----- src/auth.h | 9 - src/centralserver.c | 442 ------------ src/centralserver.h | 20 - src/client_list.c | 119 ---- src/client_list.h | 64 -- src/commandline.c | 141 ---- src/commandline.h | 10 - src/conf.c | 904 ------------------------ src/conf.h | 146 ---- src/debug.c | 46 -- src/debug.h | 16 - src/device_key.c | 66 -- src/device_key.h | 31 - src/firewall.c | 341 --------- src/firewall.h | 32 - src/fw_iptables.c | 660 ------------------ src/fw_iptables.h | 47 -- src/gateway.c | 508 -------------- src/gateway.h | 11 - src/get_clientinfo.c | 370 ---------- src/get_clientinfo.h | 112 --- src/get_devinfo.c | 683 ------------------ src/get_devinfo.h | 125 ---- src/get_remote_shell.c | 213 ------ src/get_remote_shell.h | 35 - src/http.c | 277 -------- src/http.h | 20 - src/ping_thread.c | 236 ------- src/ping_thread.h | 3 - src/safe.c | 90 --- src/safe.h | 33 - src/shell_command.h | 63 -- src/util.c | 512 -------------- src/util.h | 60 -- src/wdctl.c | 237 ------- src/wdctl.h | 6 - src/wdctl_thread.c | 346 ---------- src/wdctl_thread.h | 5 - wifidog-msg.html.in | 4 - wifidog.conf | 63 -- 77 files changed, 15 insertions(+), 11181 deletions(-) delete mode 100755 .cproject delete mode 100755 .project delete mode 100755 README delete mode 100755 contrib/wifidog/Makefile delete mode 100755 contrib/wifidog/files/wifidog.conf delete mode 100755 contrib/wifidog/files/wifidog.init delete mode 100755 scripts/DOG_monitor.sh~ delete mode 100755 scripts/GET_clients_rate.sh~ delete mode 100755 scripts/GET_settings.sh delete mode 100755 scripts/GET_settings.sh~ delete mode 100755 scripts/TEST_ServerIsAlive.sh~ delete mode 100755 scripts/auth.sh delete mode 100755 scripts/authServerIsAlive.sh delete mode 100755 scripts/authServerIsAlive.sh~ delete mode 100755 scripts/conf/dog_post_conf delete mode 100755 scripts/conf/wifidog_conf delete mode 100755 scripts/dog_conf_generator.sh delete mode 100755 scripts/dog_conf_generator.sh~ delete mode 100755 scripts/etc/devicekey delete mode 100755 scripts/white_black_flush.sh delete mode 100755 src/device_key.c delete mode 100755 src/device_key.h delete mode 100755 src/get_clientinfo.c delete mode 100755 src/get_clientinfo.h delete mode 100755 src/get_devinfo.c delete mode 100755 src/get_devinfo.h delete mode 100755 src/get_remote_shell.c delete mode 100755 src/get_remote_shell.h delete mode 100755 src/shell_command.h diff --git a/.cproject b/.cproject deleted file mode 100755 index 6296caa4..00000000 --- a/.cproject +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.project b/.project deleted file mode 100755 index 7785dd6f..00000000 --- a/.project +++ /dev/null @@ -1,27 +0,0 @@ - - - wifidog-20140822 - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.core.ccnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - diff --git a/ChangeLog b/ChangeLog index bb86fbd1..35cc8823 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,4 @@ # $Id$ -<<<<<<< HEAD 2015-03-19 * See NEWS file from now on 2015-03-18 @@ -40,13 +39,6 @@ 2014-08-31 * Fixed parsing process for AuthServer configurations by Kontinuation (https://github.com/wifidog/wifidog-gateway/pull/24) -======= -2015-07-13 - * add get_clientinfo.h get_clientinfo.c -2015-07-09 - * add shell_command.h - * add get_devinfo.h get_devinfo.c ->>>>>>> FETCH_HEAD 2014-05-13 * libhttpd crash on invalid HTTP headers (second part of the patch) by Benoit GrĂ©goire 2013-08-21 diff --git a/FAQ b/FAQ index 5cc4ea29..fb8d82d2 100644 --- a/FAQ +++ b/FAQ @@ -6,10 +6,6 @@ # # Please check the above URL if you have a FAQ that does not appear here. # -<<<<<<< HEAD -# -======= ->>>>>>> FETCH_HEAD WiFiDog/FAQ diff --git a/Makefile.am b/Makefile.am index cb945eb0..bd4f559f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,10 +1,7 @@ # $Id$ -<<<<<<< HEAD AUTOMAKE_OPTIONS = foreign -======= ->>>>>>> FETCH_HEAD SUBDIRS = libhttpd src . doc docdir = ${prefix}/share/doc/wifidog-@VERSION@ @@ -12,14 +9,8 @@ docdir = ${prefix}/share/doc/wifidog-@VERSION@ doc_DATA = \ AUTHORS \ COPYING \ -<<<<<<< HEAD NEWS \ README.md \ -======= - INSTALL \ - NEWS \ - README \ ->>>>>>> FETCH_HEAD ChangeLog EXTRA_DIST = \ @@ -34,33 +25,3 @@ EXTRA_DIST = \ .PHONY: doc doc: $(MAKE) -C doc doc -<<<<<<< HEAD -======= - -.PHONY: whiterussianipk -whiterussianipk: dist - make -C $(OPENWRTSDK) distclean - mkdir -p $(OPENWRTSDK)/dl - cp -f ${srcdir}/wifidog-@VERSION@.tar.gz $(OPENWRTSDK)/dl/ - make -C ${srcdir}/contrib/build-openwrt-whiterussianipk/wifidog TOPDIR=$(OPENWRTSDK) PKG_MD5SUM= V=99 - @echo DONE. If there were no errors, your package should be in: $(OPENWRTSDK)/bin/packages/ - -.PHONY: kamikazeipk -kamikazeipk: dist - make -C $(OPENWRTSDK) distclean - mkdir -p $(OPENWRTSDK)/dl - cp -f ${srcdir}/wifidog-@VERSION@.tar.gz $(OPENWRTSDK)/dl/ - make -C ${srcdir}/contrib/build-openwrt-kamikazeipk/wifidog TOPDIR=$(OPENWRTSDK) PKG_MD5SUM= V=99 SDK=1 DEVELOPER=1 - @echo DONE. If there were no errors, your package should be in: $(OPENWRTSDK)/bin/packages/ - -.PHONY: rpm -rpm: dist - cp ${builddir}wifidog.spec /usr/src/RPM/SPECS - cp ${builddir}wifidog-@VERSION@.tar.gz /usr/src/RPM/SOURCES - rpmbuild -ta ${builddir}wifidog-@VERSION@.tar.gz - -#clean-local: -# echo "clean-local: " && pwd -# rm -f /usr/src/RPM/SPECS/wifidog.spec -# rm -f /usr/src/RPM/SOURCES/wifidog-@VERSION@.tar.gz ->>>>>>> FETCH_HEAD diff --git a/NEWS b/NEWS index 09b706e9..2f4594df 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,3 @@ -<<<<<<< HEAD # vim: set noet sw=4 ts=4 : WiFiDog 1.2.1: @@ -49,20 +48,13 @@ WiFiDog 1.2.0: * Various other fixes and minor improvements, see https://github.com/wifidog/wifidog-gateway/compare/1.1.5...1.2.0 -======= -# $Id$ ->>>>>>> FETCH_HEAD WiFiDog 1.1.5: * First supported version on OpenWRT kamikaze WiFiDog 1.1.4: -<<<<<<< HEAD * Fix incorrect firewal rule deletion introduced in 1.1.3rc1. Caused the incoming byte count reported to be incorrect for users that logged in a second time on a gateway that wasn't restarted in between. -======= - * Fix incorrect firewal rule deletion introduced in 1.1.3rc1. Caused the incoming byte count reported to be incorrect for users that logged in a second time on a gateway that wasn't restarted in between. ->>>>>>> FETCH_HEAD WiFiDog 1.1.3: * Fix incomplete change to make te gateway retry external interface forever. @@ -70,7 +62,6 @@ WiFiDog 1.1.3: * Add manual logout URL, based in part on work by David Bird WiFiDog 1.1.3rc1: -<<<<<<< HEAD * Close #321: Make the Gateway retry forever if it cannot find it's interface. You never know when someone may finally replug the network cable or something... * Close #332: Apply patch from Laurent Marchal. biguphpcgmailcom @@ -89,24 +80,10 @@ WiFiDog 1.1.3rc1: part of wifidog. * Modify the build system to finally be able to build wifidog directly from the wifidog directory using the same files -======= - * Close #321: Make the Gateway retry forever if it cannot find it's interface. You never know when someone may finally replug the network cable or something... - * Close #332: Apply patch from Laurent Marchal. biguphpcgmailcom - * fw_iptables.c: Fix error in iptables_fw_access(). Rules were created as ACCEPT instead of DROP - * firewall.c: Fix bug in fw_sync_with_authserver(). The traffic for the validation period of a user who validated his account while connected wouldn't get counted. - * doc/wifidog_firewall_map.dia: At long last, full documentation of the firewall. We would have avoided a lot of stupid mistakes if we produced that sooner. - * Release 1.1.3_rc1 - * Fix #324 - * wifidog.conf: Improve comments and add examples of blocking access to the upstream LAN. - * conf.h: The DEFAULT_CHECKINTERVAL was 5 instead of 60 (as stated in the config file) which caused huge needless load on the auth servers, and needless ping traffic towards the clients if it wasn't manually set. - * contrib/ Add contrib dir to collect the scripts and other code distributed with, but not really part of wifidog. - * Modify the build system to finally be able to build wifidog directly from the wifidog directory using the same files ->>>>>>> FETCH_HEAD used to make the official .ipk, without having to copy ANYTHNG to the openwrt SDK. There is now a new target: make ipk make ipk OPENWRTSDK=path_to_openwrt_sdk WiFiDog 1.1.3beta6: -<<<<<<< HEAD * Fix bug #238 (config file location was hardcoded) * Fix problem with autodectection of the External interface if the interface isn't fully up yet. wifidog wil now retry for up to two minutes. @@ -145,50 +122,10 @@ WiFiDog 1.1.2: terminations as per email from ludocornut@users.sourceforge.net * Firewall: make the default ruleset for validating users = allow all (except sending SMTP) -======= - -Fix bug #238 (config file location was hardcoded) - -Fix problem with autodectection of the External interface if the interface isn't fully up yet. wifidog wil now retry for up to two minutes. - -WiFiDog 1.1.3beta4: - -Changed ordering in the filter.FORWARD chain - -Added TCPMSS rule - -Fixed rules bieng left over on shutdown - -Fixed wdctl reset problem - -WiFiDog 1.1.3beta2: - -Fix bug #65 (Whitelisted servers would still splash on port 80 - -Fix incorrect default value for Path in the AuthServer configuration - -Add more info to wdctl status - -WiFiDog 1.1.3beta1: - -Added patch by wireless London to use the GW interface's mac address as the node_id - if no node_id is specified. It allows the use of generic configuration files without - the need to hardcoding the node_id in. - -Added TrustedMACList configuration variable which allows specifying - MAC addresses which are allowed to go through without authentication. - -New wdctl command "restart" which will get wifidog to restart itself - while preserving the existing clientlist. Perfect for 0-downtime - upgrading! - -libhttpd: Fixed two bugs parsing the GET query string making wifidog segfault - - -WiFiDog 1.1.2: - - Added some informations so it compiles on newer OpenWRT's (whiterussian-rc2) - - Fixed minor issue with wdctl - - Changed the iptables rules priority to allow existing NAT rules to work - - read()s from central server in auth_server_request() are - now timed-out (via select). This is hopefully a bugfix to the - thread-freezing problem. - - Bugfix non-RFC compliant HTTP requests using \n instead of \r\n as line - terminations as per email from ludocornut@users.sourceforge.net - - Firewall: make the default ruleset for validating users = allow all - (except sending SMTP) ->>>>>>> FETCH_HEAD Fixed issue with FAQ WiFiDog 1.1.1: -<<<<<<< HEAD * An auth server on port 80 will now work * Added an FAQ @@ -244,52 +181,3 @@ WiFiDog 1.0.2: WiFiDog 1.0.0: * Initial release -======= - - An auth server on port 80 will now work - - Added an FAQ - -WiFiDog 1.1.0: - - Changes: - - Visual tweaks in the web interface - - Internal code & documentation touch-ups - - More debugging output - - Bugfixes: - - Wrong reported uptime - - Invalid http header sent during redirection - - Mixed long/long long type for counter - - Respect SSL setting in auth server definition - - Explicitly allow traffic coming into the router - - SIGPIPE handling - - Firewall destruction not occuring on wifidog termination - -WiFiDog 1.1.0_beta3: - - Completely re-did the iptables rules. Most of the rules are now in the filter table instead of the nat table. Also DROPs are now replaced with REJECTs to help tell the user connection refused instead of endless pauses - - wdctl status will return more informations - - Some error messages are now displayed by the auth server (used to be done in a non-pretty way by wifidog) - - We now 'ping' authserver and detect when authservers are changing IPs - - Fixed memory leaks - - Incoming and outgoing counters were reversed - - More verbose debugging - - ICMP Ping the users everytime we check their counters to keep them alive - - Optional ExternalInterface - - Optional GatewayAddress - - /about URL now shows wifidog version - - Keep track of last times we successfully & unsuccessfully spoke to the auth server/used DNS. Then, if we know we're not online, show a little apology to the user instead of re-directing them to the auth server. - - When pinging auth server now also sends sys_uptime, sys_memfree and sys_load - - Bugfix: Traffic from client to router was counted twice in the "outgoing" bytecount since it increased both counters in mangle.* and filter.* - Got rid of TABLE_WIFIDOG_WIFI_TO_GW completely since it's unneeded - - Do not update the last_updated field on incoming traffic - update it on outgoing traffic only. This should be a much more reliable indication of client no longer being there - - WiFiDog status is now viewable with a web browser at http://ip:port/wifidog/status - -WiFiDog 1.0.2: - - Fix reversed incoming and outgoing connections in statistics reported to the auth server - - Will now gracefully handle auth servers changing IP adress. - - Fixes two bugs in byte counting. (Possible missed data, and incoming and outgoing were reversed. - - Fixed file descriptor leaks - - wdctl_status now returns all connected users. - - worked around sed -i not being available on all platform - - ipkg no longuer overwrites config file - - Several code changes in thread handling and libhttpd to fix occasional hangs. - -WiFiDog 1.0.0: - - Initial release ->>>>>>> FETCH_HEAD diff --git a/README b/README deleted file mode 100755 index 15c6bc87..00000000 --- a/README +++ /dev/null @@ -1,16 +0,0 @@ -# -# $Id$ -# - -The WiFi Guard Dog project is a complete and embeddable captive portal -solution for wireless community groups or individuals who wish to open a -free HotSpot while still preventing abuse of their Internet connection. - -The project's homepage is: - http://dev.wifidog.org/ - -Mailing list interface: - http://listes.ilesansfil.org/cgi-bin/mailman/listinfo/wifidog - -The project's software is released under the GPL license and is copyright it's respective owners. - diff --git a/autogen.sh b/autogen.sh index b2d60b2d..7024c9cf 100755 --- a/autogen.sh +++ b/autogen.sh @@ -9,33 +9,6 @@ then make distclean fi -<<<<<<< HEAD -======= -if [ "X$1" != "X" ] -then - BUILDROOT=`echo "$1" | sed 's/^[^=]*[=]//'` - - OLDCC=${CC} - OLDRANLIB=${RANLIB} - OLDAR=${AR} - - CC=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-gcc - RANLIB=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-ranlib - AR=${BUILDROOT}/build_mipsel/staging_dir/bin/mipsel-linux-uclibc-ar - - POSTCONF=--host=mipsel - - export CC - export RANLIB - export AR -else - OLDCC=${CC} - OLDRANLIB=${RANLIB} - OLDAR=${AR} - POSTCONF= -fi - ->>>>>>> FETCH_HEAD echo "Running mkdir -p config" mkdir -p config @@ -58,14 +31,3 @@ echo "Running autoconf" autoconf echo "Running ./configure ${POSTCONF} --enable-maintainer-mode $conf_flags $@" ./configure ${POSTCONF} --enable-maintainer-mode $conf_flags "$@" -<<<<<<< HEAD -======= - -CC=${OLDCC} -RANLIB=${OLDRANLIB} -AR=${OLDAR} - -export CC -export RANLIB -export AR ->>>>>>> FETCH_HEAD diff --git a/configure.in b/configure.in index a6b8a172..6daed5fc 100644 --- a/configure.in +++ b/configure.in @@ -18,18 +18,11 @@ AC_PROG_CXX AC_SUBST(BUILDROOT) -<<<<<<< HEAD # we use Semantic Versioning x.y.z tag for release, docs: http://semver.org/ WIFIDOG_MAJOR_VERSION=1 WIFIDOG_MINOR_VERSION=2 WIFIDOG_MICRO_VERSION=1 WIFIDOG_VERSION=$WIFIDOG_MAJOR_VERSION.$WIFIDOG_MINOR_VERSION.$WIFIDOG_MICRO_VERSION -======= -WIFIDOG_MAJOR_VERSION=1 -WIFIDOG_MINOR_VERSION=1 -WIFIDOG_MICRO_VERSION=5 -WIFIDOG_VERSION=20140822-v1.0.0 ->>>>>>> FETCH_HEAD AC_SUBST(WIFIDOG_MAJOR_VERSION) AC_SUBST(WIFIDOG_MINOR_VERSION) @@ -92,7 +85,6 @@ AC_SUBST(enable_latex_docs) # Acutally perform the doxygen check BB_ENABLE_DOXYGEN -<<<<<<< HEAD # Enable cyassl? AC_DEFUN([BB_CYASSL], [ @@ -138,8 +130,6 @@ BB_CYASSL -======= ->>>>>>> FETCH_HEAD # check for pthread AC_CHECK_HEADER(pthread.h, , AC_MSG_ERROR(You need the pthread headers) ) AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR(You need the pthread library) ) @@ -153,11 +143,7 @@ echo "libhttpd dependencies check complete" AC_OUTPUT( Makefile wifidog.spec -<<<<<<< HEAD wifidog-msg.html -======= - wifidog-msg.html ->>>>>>> FETCH_HEAD src/Makefile libhttpd/Makefile doc/Makefile diff --git a/contrib/wifidog/Makefile b/contrib/wifidog/Makefile deleted file mode 100755 index 090a4a93..00000000 --- a/contrib/wifidog/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2006,2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -#PKG_VERSION:=gateway -PKG_VERSION:=20140822 -PKG_RELEASE:=v1.0.0 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -#PKG_MD5SUM:=b992869cb6607d89362f2fc09a727af9 -PKG_MD5SUM:=7241d86b46bbfeef54fb72e48a56dc8c - -PKG_FIXUP:=autoreconf -PKG_INSTALL:=1 - -include $(INCLUDE_DIR)/package.mk - -define Package/wifidog -# SUBMENU:=Captive Portals - SECTION:=wifidog - CATEGORY:=Wifidog -# SECTION:=net -# CATEGORY:=Network - DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +kmod-ipt-nat +iptables-mod-nat-extra +libpthread - TITLE:=A wireless captive portal solution - URL:=http://www.wifidog.org -endef - -define Package/wifidog/description - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. -endef - -define Package/wifidog/conffiles -/etc/wifidog.conf -endef - -define Package/wifidog/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/GET_settings.sh $(1)/usr/bin/GET_settings - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/dog_conf_generator.sh $(1)/usr/bin/dog_conf_generator -# $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/white_black_flush.sh $(1)/usr/bin/white_black_flush - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/DOG_monitor.sh $(1)/usr/bin/DOG_monitor - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) $(PKG_BUILD_DIR)/contrib/wifidog/files/wifidog.conf $(1)/etc/wifidog.conf.bak - $(INSTALL_DIR) $(1)/etc/config - $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/conf/* $(1)/etc/config/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) $(PKG_BUILD_DIR)/scripts/etc/devicekey $(1)etc/.devicekey - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) $(PKG_BUILD_DIR)/contrib/wifidog/files/$(PKG_NAME).init $(1)/etc/init.d/wifidog -endef - -$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/wifidog/files/wifidog.conf b/contrib/wifidog/files/wifidog.conf deleted file mode 100755 index 42e767c6..00000000 --- a/contrib/wifidog/files/wifidog.conf +++ /dev/null @@ -1,281 +0,0 @@ -# $Id$ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -# GatewayInterface br-lan - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: UntrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are not allowed to pass -# through without authentication -#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - - -# Parameter: WhiteList -# Default: none -# Optional -# Comma separated list of url who are allowed to pass -# through router -#WhiteList www.baidu.com,www.taobao.com - -# Parameter: BlackList -# Default: none -# Optional -# Comma separated list of url who are not allowed to pass -# through router -#BlackList www.av123.com,www.av456.com - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - - # FirewallRule syntax: - # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X]] [to IP/CIDR] - - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/wifidog/files/wifidog.init b/contrib/wifidog/files/wifidog.init deleted file mode 100755 index 38664265..00000000 --- a/contrib/wifidog/files/wifidog.init +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh /etc/rc.common -# wifidog start on boot -#2015-08-12 -# - -START=99 - -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Print the status of the service" - - -start() { - /usr/bin/dog_conf_generator & - echo "00 04 * * * reboot" > /etc/crontabs/root - echo "root" > /etc/crontabs/cron.update - sleep 1 - /usr/bin/wifidog-init start - -# sleep 1 -# /usr/bin/white_black_flush & - - sleep 5 - /usr/bin/DOG_monitor & -} - -stop() { - /usr/bin/wifidog-init stop -# sleep 1 -# rst=`ps | grep white_black | cut -d "r" -f 1` -# if [ -n "$rst" ]; then -# kill -9 $rst -# fi - - sleep 2 - rst=`ps | grep DOG_monitor | cut -d "r" -f 1` - if [ -n "$rst" ]; then - kill -9 $rst - fi -} - -status() { - - /usr/bin/wifidog-init status -} - diff --git a/doc/README.developers.txt b/doc/README.developers.txt index eb4e8ab9..5dcb8a5e 100644 --- a/doc/README.developers.txt +++ b/doc/README.developers.txt @@ -4,7 +4,6 @@ $Id$ This file contains some small notes on developing the WiFiDog application. -<<<<<<< HEAD The application's GitHub page is: https://github.com/wifidog/ @@ -36,23 +35,11 @@ Once your patch is good to go, submit a pull request on GitHub: If you're having any questions, file an issue on GitHub and add the "Question" label: https://github.com/wifidog/wifidog-gateway/issues/new -======= -The application's home page is: - http://www.ilesansfil.org/wiki/WiFiDog - -The application's sourceforge page is: - http://sourceforge.net/projects/wifidog/ - -As a developer, you must subscribe to sourceforge as a "developer" under WiFiDog, as well as subscribe to the WiFiDog mailing list located at: - http://listes.ilesansfil.org/cgi-bin/mailman/listinfo/wifidog - ->>>>>>> FETCH_HEAD SOURCE CODE: - Please do not contribute unless you agree with the GPL license and are contributing your portion under that license. See the included LICENSE.txt - Please respect the intellectual property of others. You are not allowed to taint WiFiDog by including source code from projects that do not allow so. - Keep in mind that this application will run on extremely simple embedded devices. The binary size needs to be small, the dependencies absolutely minimal, and the memory footprint negligible. -<<<<<<< HEAD - Since this is a collaborative project, please aim for clearness instead of cleverness when faced with a choice. - If you must use some cleverness, please add appropriate clear comments. - Please format your code properly before submitting a patch or a pull request. In general, we use 4 tabs instead of spaces with a maximum @@ -64,12 +51,6 @@ SOURCE CODE: The complete code style is defined by the following GNU indent call: indent --linux-style --no-tabs --indent-level 4 --line-length 120 --procnames-start-lines - Do not introduce compiler warnings. If the compiler warning is indeed harmless, disable it with the appropriate -Wno- flag in Makefile.am -======= - - Always place the subversion "Id" macro at the top of every file - - Since this is a collaborative project, please aim for clearness instead of cleverness when faced with a choice. - - If you must use some cleverness, please add appropriate clear comments. - - Please re-indent your code before committing to subversion - see the "Formatting Your Source Code" section in the GNU Coding Standards at http://www.gnu.org/prep/standards_toc.html - the entire document makes a good reading if you haven't read it before. Also see the "indent" program. ->>>>>>> FETCH_HEAD - Before writing any brand-new large chunks of code, make sure it's logic has been discussed with the other team of developers or included in the design stage. @@ -82,8 +63,5 @@ DOCUMENTATION: - Please use DoxyGen-style comments (see http://www.doxygen.org/ for details) for source code documentation. - Please use DocBook-SGML documentation for user documentation. This will make it easy to export documentation in multiple formats. Otherwise submit your documentation in plaintext format to someone who will change it to DocBook. - Please thoroughly-comment non-clear sections in your code. -<<<<<<< HEAD - Remember that commit messages and pull request descriptions also serve as a form of documentation. -======= ->>>>>>> FETCH_HEAD diff --git a/libhttpd/Makefile.am b/libhttpd/Makefile.am index f36ed277..ec8811cb 100644 --- a/libhttpd/Makefile.am +++ b/libhttpd/Makefile.am @@ -14,14 +14,8 @@ noinst_HEADERS = httpd_priv.h pkginclude_HEADERS = httpd.h EXTRA_DIST = README -<<<<<<< HEAD AM_CPPFLAGS = \ -Wall \ -Wextra \ -Wno-unused-parameter -======= - -#AM_CPPFLAGS = \ -# -I${top_srcdir}/inc ->>>>>>> FETCH_HEAD diff --git a/libhttpd/api.c b/libhttpd/api.c index e0c02f14..a59d55ad 100644 --- a/libhttpd/api.c +++ b/libhttpd/api.c @@ -1,8 +1,4 @@ -<<<<<<< HEAD /* vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab -======= -/* ->>>>>>> FETCH_HEAD ** Copyright (c) 2002 Hughes Technologies Pty Ltd. All rights ** reserved. ** @@ -33,21 +29,12 @@ #if defined(_WIN32) #include #else -<<<<<<< HEAD #include #include #include #include #include #include -======= -#include -#include -#include -#include -#include -#include ->>>>>>> FETCH_HEAD #include #endif @@ -56,7 +43,6 @@ #include "httpd_priv.h" #ifdef HAVE_STDARG_H -<<<<<<< HEAD #include #else #include @@ -965,1027 +951,4 @@ httpdForceAuthenticate(request * r, const char *realm) snprintf(buffer, sizeof(buffer), "WWW-Authenticate: Basic realm=\"%s\"\n", realm); httpdAddHeader(r, buffer); httpdOutput(r, "\n"); -======= -# include -#else -# include -#endif - - -char *httpdUrlEncode(str) - const char *str; -{ - char *new, - *cp; - - new = (char *)_httpd_escape(str); - if (new == NULL) - { - return(NULL); - } - cp = new; - while(*cp) - { - if (*cp == ' ') - *cp = '+'; - cp++; - } - return(new); -} - - - -char *httpdRequestMethodName(request *r) -{ - static char tmpBuf[255]; - - switch(r->request.method) - { - case HTTP_GET: return("GET"); - case HTTP_POST: return("POST"); - default: - snprintf(tmpBuf,255,"Invalid method '%d'", - r->request.method); - return(tmpBuf); - } -} - - -httpVar *httpdGetVariableByName(request *r, const char *name) -{ - httpVar *curVar; - - curVar = r->variables; - while(curVar) - { - if (strcmp(curVar->name, name) == 0) - return(curVar); - curVar = curVar->nextVariable; - } - return(NULL); -} - - - -httpVar *httpdGetVariableByPrefix(request *r, const char *prefix) -{ - httpVar *curVar; - - if (prefix == NULL) - return(r->variables); - curVar = r->variables; - while(curVar) - { - if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) - return(curVar); - curVar = curVar->nextVariable; - } - return(NULL); -} - - -httpVar *httpdGetVariableByPrefixedName(request *r, const char *prefix, const char *name) -{ - httpVar *curVar; - int prefixLen; - - if (prefix == NULL) - return(r->variables); - curVar = r->variables; - prefixLen = strlen(prefix); - while(curVar) - { - if (strncmp(curVar->name, prefix, prefixLen) == 0 && - strcmp(curVar->name + prefixLen, name) == 0) - { - return(curVar); - } - curVar = curVar->nextVariable; - } - return(NULL); -} - - -httpVar *httpdGetNextVariableByPrefix(curVar, prefix) - httpVar *curVar; - const char *prefix; -{ - if(curVar) - curVar = curVar->nextVariable; - while(curVar) - { - if (strncmp(curVar->name, prefix, strlen(prefix)) == 0) - return(curVar); - curVar = curVar->nextVariable; - } - return(NULL); -} - - -int httpdAddVariable(request *r, const char *name, const char *value) -{ - httpVar *curVar, *lastVar, *newVar; - - while(*name == ' ' || *name == '\t') - name++; - newVar = malloc(sizeof(httpVar)); - bzero(newVar, sizeof(httpVar)); - newVar->name = strdup(name); - newVar->value = strdup(value); - lastVar = NULL; - curVar = r->variables; - while(curVar) - { - if (strcmp(curVar->name, name) != 0) - { - lastVar = curVar; - curVar = curVar->nextVariable; - continue; - } - while(curVar) - { - lastVar = curVar; - curVar = curVar->nextValue; - } - lastVar->nextValue = newVar; - return(0); - } - if (lastVar) - lastVar->nextVariable = newVar; - else - r->variables = newVar; - return(0); -} - -httpd *httpdCreate(host, port) - char *host; - int port; -{ - httpd *new; - int sock, - opt; - struct sockaddr_in addr; - - /* - ** Create the handle and setup it's basic config - */ - new = malloc(sizeof(httpd)); - if (new == NULL) - return(NULL); - bzero(new, sizeof(httpd)); - new->port = port; - if (host == HTTP_ANY_ADDR) - new->host = HTTP_ANY_ADDR; - else - new->host = strdup(host); - new->content = (httpDir*)malloc(sizeof(httpDir)); - bzero(new->content,sizeof(httpDir)); - new->content->name = strdup(""); - - /* - ** Setup the socket - */ -#ifdef _WIN32 - { - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD( 2, 2 ); - - err = WSAStartup( wVersionRequested, &wsaData ); - - /* Found a usable winsock dll? */ - if( err != 0 ) - return NULL; - - /* - ** Confirm that the WinSock DLL supports 2.2. - ** Note that if the DLL supports versions greater - ** than 2.2 in addition to 2.2, it will still return - ** 2.2 in wVersion since that is the version we - ** requested. - */ - - if( LOBYTE( wsaData.wVersion ) != 2 || - HIBYTE( wsaData.wVersion ) != 2 ) { - - /* - ** Tell the user that we could not find a usable - ** WinSock DLL. - */ - WSACleanup( ); - return NULL; - } - - /* The WinSock DLL is acceptable. Proceed. */ - } -#endif - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - { - free(new); - return(NULL); - } -# ifdef SO_REUSEADDR - opt = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int)); -# endif - new->serverSock = sock; - bzero(&addr, sizeof(addr)); - addr.sin_family = AF_INET; - if (new->host == HTTP_ANY_ADDR) - { - addr.sin_addr.s_addr = htonl(INADDR_ANY); - } - else - { - addr.sin_addr.s_addr = inet_addr(new->host); - } - addr.sin_port = htons((u_short)new->port); - if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0) - { - close(sock); - free(new); - return(NULL); - } - listen(sock, 128); - new->startTime = time(NULL); - return(new); -} - -void httpdDestroy(server) - httpd *server; -{ - if (server == NULL) - return; - if (server->host) - free(server->host); - free(server); -} - - - -request *httpdGetConnection(server, timeout) - httpd *server; - struct timeval *timeout; -{ - int result; - fd_set fds; - struct sockaddr_in addr; - socklen_t addrLen; - char *ipaddr; - request *r; - - FD_ZERO(&fds); - FD_SET(server->serverSock, &fds); - result = 0; - while(result == 0) - { - result = select(server->serverSock + 1, &fds, 0, 0, timeout); - if (result < 0) - { - server->lastError = -1; - return(NULL); - } - if (timeout != 0 && result == 0) - { - return(NULL); - server->lastError = 0; - } - if (result > 0) - { - break; - } - } - /* Allocate request struct */ - r = (request *)malloc(sizeof(request)); - if (r == NULL) { - server->lastError = -3; - return(NULL); - } - memset((void *)r, 0, sizeof(request)); - /* Get on with it */ - bzero(&addr, sizeof(addr)); - addrLen = sizeof(addr); - r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr, - &addrLen); - ipaddr = inet_ntoa(addr.sin_addr); - if (ipaddr) { - strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN); - r->clientAddr[HTTP_IP_ADDR_LEN-1]=0; - } else - *r->clientAddr = 0; - r->readBufRemain = 0; - r->readBufPtr = NULL; - - /* - ** Check the default ACL - */ - if (server->defaultAcl) - { - if (httpdCheckAcl(server, r, server->defaultAcl) - == HTTP_ACL_DENY) - { - httpdEndRequest(r); - server->lastError = 2; - return(NULL); - } - } - return(r); -} - - - -int httpdReadRequest(httpd *server, request *r) -{ - static char buf[HTTP_MAX_LEN]; - int count, - inHeaders; - char *cp, *cp2; - int _httpd_decode(); - - - /* - ** Setup for a standard response - */ - strcpy(r->response.headers, - "Server: Hughes Technologies Embedded Server\n"); - strcpy(r->response.contentType, "text/html"); - strcpy(r->response.response,"200 Output Follows\n"); - r->response.headersSent = 0; - - - /* - ** Read the request - */ - count = 0; - inHeaders = 1; - while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0) - { - count++; - - /* - ** Special case for the first line. Scan the request - ** method and path etc - */ - if (count == 1) - { - /* - ** First line. Scan the request info - */ - cp = cp2 = buf; - while(isalpha((unsigned char)*cp2)) - cp2++; - *cp2 = 0; - if (strcasecmp(cp,"GET") == 0) - r->request.method = HTTP_GET; - if (strcasecmp(cp,"POST") == 0) - r->request.method = HTTP_POST; - if (r->request.method == 0) - { - _httpd_net_write( r->clientSock, - HTTP_METHOD_ERROR, - strlen(HTTP_METHOD_ERROR)); - _httpd_net_write( r->clientSock, cp, - strlen(cp)); - _httpd_writeErrorLog(server, r, LEVEL_ERROR, - "Invalid method received"); - return(-1); - } - cp = cp2+1; - while(*cp == ' ') - cp++; - cp2 = cp; - while(*cp2 != ' ' && *cp2 != 0) - cp2++; - *cp2 = 0; - strncpy(r->request.path,cp,HTTP_MAX_URL); - r->request.path[HTTP_MAX_URL-1]=0; - _httpd_sanitiseUrl(r->request.path); - continue; - } - - /* - ** Process the headers - */ - if (inHeaders) - { - if (*buf == 0) - { - /* - ** End of headers. Continue if there's - ** data to read - */ - if (r->request.contentLength == 0) - break; - inHeaders = 0; - break; - } -#if 0 - /** - * Philippe commenting this out, it crashed with a - * particular pattern sent from the browser - * and we don't need it - if (strncasecmp(buf,"Cookie: ",7) == 0) - { - char *var, - *val, - *end; - - var = strchr(buf,':'); - while(var) - { - var++; - val = strchr(var, '='); - *val = 0; - val++; - end = strchr(val,';'); - if(end) - *end = 0; - httpdAddVariable(r, var, val); - var = end; - } - } - */ -#endif - if (strncasecmp(buf,"Authorization: ",15) == 0) - { - cp = strchr(buf,':'); - if (cp) { - cp += 2; - - if (strncmp(cp,"Basic ", 6) != 0) - { - /* Unknown auth method */ - } - else - { - char authBuf[100]; - - cp = strchr(cp,' ') + 1; - _httpd_decode(cp, authBuf, 100); - r->request.authLength = - strlen(authBuf); - cp = strchr(authBuf,':'); - if (cp) - { - *cp = 0; - strncpy( - r->request.authPassword, - cp+1, HTTP_MAX_AUTH); - r->request.authPassword[HTTP_MAX_AUTH-1]=0; - } - strncpy(r->request.authUser, - authBuf, HTTP_MAX_AUTH); - r->request.authUser[HTTP_MAX_AUTH-1]=0; - } - } - } -#if 0 - if (strncasecmp(buf,"Referer: ",9) == 0) - { - cp = strchr(buf,':') + 2; - if(cp) - { - strncpy(r->request.referer,cp, - HTTP_MAX_URL); - r->request.referer[HTTP_MAX_URL-1]=0; - } - } -#endif - /* acv@acv.ca/wifidog: Added decoding of host: if - * present. */ - if (strncasecmp(buf,"Host: ",6) == 0) - { - cp = strchr(buf,':'); - if(cp) - { - cp += 2; - strncpy(r->request.host,cp, - HTTP_MAX_URL); - r->request.host[HTTP_MAX_URL-1]=0; - } - } - /* End modification */ -#if 0 - if (strncasecmp(buf,"If-Modified-Since: ",19) == 0) - { - cp = strchr(buf,':') + 2; - if(cp) - { - strncpy(r->request.ifModified,cp, - HTTP_MAX_URL); - r->request.ifModified[HTTP_MAX_URL-1]=0; - cp = strchr(r->request.ifModified, - ';'); - if (cp) - *cp = 0; - } - } - if (strncasecmp(buf,"Content-Type: ",14) == 0) - { - cp = strchr(buf,':') + 2; - if(cp) - { - strncpy(r->request.contentType,cp, - HTTP_MAX_URL); - r->request.contentType[HTTP_MAX_URL-1]=0; - } - } - if (strncasecmp(buf,"Content-Length: ",16) == 0) - { - cp = strchr(buf,':') + 2; - if(cp) - r->request.contentLength=atoi(cp); - } -#endif - continue; - } - } - - -#if 0 - /* XXX: For WifiDog, we only process the query string parameters - but keep the GET variables in the request.query! - */ - /* - ** Process and POST data - */ - if (r->request.contentLength > 0) - { - bzero(buf, HTTP_MAX_LEN); - _httpd_readBuf(r, buf, r->request.contentLength); - _httpd_storeData(r, buf); - - } -#endif - - /* - ** Process any URL data - */ - cp = strchr(r->request.path,'?'); - if (cp != NULL) - { - *cp++ = 0; - strncpy(r->request.query, cp, sizeof(r->request.query)); - r->request.query[sizeof(r->request.query)-1]=0; - _httpd_storeData(r, cp); - } - - return(0); -} - - -void httpdEndRequest(request *r) -{ - _httpd_freeVariables(r->variables); - shutdown(r->clientSock,2); - close(r->clientSock); - free(r); -} - - -void httpdFreeVariables(request *r) -{ - _httpd_freeVariables(r->variables); -} - - - -void httpdDumpVariables(request *r) -{ - httpVar *curVar, - *curVal; - - curVar = r->variables; - while(curVar) - { - printf("Variable '%s'\n", curVar->name); - curVal = curVar; - while(curVal) - { - printf("\t= '%s'\n",curVal->value); - curVal = curVal->nextValue; - } - curVar = curVar->nextVariable; - } -} - -void httpdSetFileBase(server, path) - httpd *server; - const char *path; -{ - strncpy(server->fileBasePath, path, HTTP_MAX_URL); - server->fileBasePath[HTTP_MAX_URL-1]=0; -} - - -int httpdAddFileContent(server, dir, name, indexFlag, preload, path) - httpd *server; - char *dir, - *name; - int (*preload)(); - int indexFlag; - char *path; -{ - httpDir *dirPtr; - httpContent *newEntry; - - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = strdup(name); - newEntry->type = HTTP_FILE; - newEntry->indexFlag = indexFlag; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - if (*path == '/') - { - /* Absolute path */ - newEntry->path = strdup(path); - } - else - { - /* Path relative to base path */ - newEntry->path = malloc(strlen(server->fileBasePath) + - strlen(path) + 2); - snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", - server->fileBasePath, path); - } - return(0); -} - - - -int httpdAddWildcardContent(server, dir, preload, path) - httpd *server; - char *dir; - int (*preload)(); - char *path; -{ - httpDir *dirPtr; - httpContent *newEntry; - - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = NULL; - newEntry->type = HTTP_WILDCARD; - newEntry->indexFlag = HTTP_FALSE; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - if (*path == '/') - { - /* Absolute path */ - newEntry->path = strdup(path); - } - else - { - /* Path relative to base path */ - newEntry->path = malloc(strlen(server->fileBasePath) + - strlen(path) + 2); - snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s", - server->fileBasePath, path); - } - return(0); -} - - - - -int httpdAddC404Content(server, function) - httpd *server; - void (*function)(); -{ - if (!server->handle404) { - server->handle404 = (http404*)malloc(sizeof(http404)); - } - - if (!server->handle404) { - return(-1); - } - - server->handle404->function = function; - return(0); -} - -int httpdAddCContent(server, dir, name, indexFlag, preload, function) - httpd *server; - char *dir; - char *name; - int (*preload)(); - void (*function)(); -{ - httpDir *dirPtr; - httpContent *newEntry; - - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = strdup(name); - newEntry->type = HTTP_C_FUNCT; - newEntry->indexFlag = indexFlag; - newEntry->function = function; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - return(0); -} - - -int httpdAddCWildcardContent(server, dir, preload, function) - httpd *server; - char *dir; - int (*preload)(); - void (*function)(); -{ - httpDir *dirPtr; - httpContent *newEntry; - - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = NULL; - newEntry->type = HTTP_C_WILDCARD; - newEntry->indexFlag = HTTP_FALSE; - newEntry->function = function; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - return(0); -} - -int httpdAddStaticContent(server, dir, name, indexFlag, preload, data) - httpd *server; - char *dir; - char *name; - int (*preload)(); - char *data; -{ - httpDir *dirPtr; - httpContent *newEntry; - - dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE); - newEntry = malloc(sizeof(httpContent)); - if (newEntry == NULL) - return(-1); - bzero(newEntry,sizeof(httpContent)); - newEntry->name = strdup(name); - newEntry->type = HTTP_STATIC; - newEntry->indexFlag = indexFlag; - newEntry->data = data; - newEntry->preload = preload; - newEntry->next = dirPtr->entries; - dirPtr->entries = newEntry; - return(0); -} - -void httpdSendHeaders(request *r) -{ - _httpd_sendHeaders(r, 0, 0); -} - -void httpdSetResponse(request *r, const char *msg) -{ - strncpy(r->response.response, msg, HTTP_MAX_URL); - r->response.response[HTTP_MAX_URL-1]=0; -} - -void httpdSetContentType(request *r, const char *type) -{ - strcpy(r->response.contentType, type); -} - - -void httpdAddHeader(request *r, const char *msg) -{ - int size; - size = HTTP_MAX_HEADERS - 2 - strlen(r->response.headers); - if(size > 0) - { - strncat(r->response.headers,msg,size); - if (r->response.headers[strlen(r->response.headers) - 1] != '\n') - strcat(r->response.headers,"\n"); - } -} - -void httpdSetCookie(request *r, const char *name, const char *value) -{ - char buf[HTTP_MAX_URL]; - - snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value); - httpdAddHeader(r, buf); -} - -void httpdOutput(request *r, const char *msg) -{ - const char *src; - char buf[HTTP_MAX_LEN], - varName[80], - *dest; - int count; - - src = msg; - dest = buf; - count = 0; - while(*src && count < HTTP_MAX_LEN) - { - if (*src == '$') - { - const char *tmp; - char *cp; - int count2; - httpVar *curVar; - - tmp = src + 1; - cp = varName; - count2 = 0; - while (*tmp && (isalnum((unsigned char)*tmp) || *tmp == '_') && - count2 < 80) - { - *cp++ = *tmp++; - count2++; - } - *cp = 0; - curVar = httpdGetVariableByName(r,varName); - if (curVar) - { - strcpy(dest, curVar->value); - dest = dest + strlen(dest); - count += strlen(dest); - } - else - { - *dest++ = '$'; - strcpy(dest, varName); - dest += strlen(varName); - count += 1 + strlen(varName); - } - src = src + strlen(varName) + 1; - continue; - } - *dest++ = *src++; - count++; - } - *dest = 0; - r->response.responseLength += strlen(buf); - if (r->response.headersSent == 0) - httpdSendHeaders(r); - _httpd_net_write( r->clientSock, buf, strlen(buf)); -} - - - -#ifdef HAVE_STDARG_H -void httpdPrintf(request *r, const char *fmt, ...) -{ -#else -void httpdPrintf(va_alist) - va_dcl -{ - request *r;; - const char *fmt; -#endif - va_list args; - char buf[HTTP_MAX_LEN]; - -#ifdef HAVE_STDARG_H - va_start(args, fmt); -#else - va_start(args); - r = (request *) va_arg(args, request * ); - fmt = (char *) va_arg(args, char *); -#endif - if (r->response.headersSent == 0) - httpdSendHeaders(r); - vsnprintf(buf, HTTP_MAX_LEN, fmt, args); - r->response.responseLength += strlen(buf); - _httpd_net_write( r->clientSock, buf, strlen(buf)); -} - - - - -void httpdProcessRequest(httpd *server, request *r) -{ - char dirName[HTTP_MAX_URL], - entryName[HTTP_MAX_URL], - *cp; - httpDir *dir; - httpContent *entry; - - r->response.responseLength = 0; - strncpy(dirName, httpdRequestPath(r), HTTP_MAX_URL); - dirName[HTTP_MAX_URL-1]=0; - cp = strrchr(dirName, '/'); - if (cp == NULL) - { - printf("Invalid request path '%s'\n",dirName); - return; - } - strncpy(entryName, cp + 1, HTTP_MAX_URL); - entryName[HTTP_MAX_URL-1]=0; - if (cp != dirName) - *cp = 0; - else - *(cp+1) = 0; - dir = _httpd_findContentDir(server, dirName, HTTP_FALSE); - if (dir == NULL) - { - _httpd_send404(server, r); - _httpd_writeAccessLog(server, r); - return; - } - entry = _httpd_findContentEntry(r, dir, entryName); - if (entry == NULL) - { - _httpd_send404(server, r); - _httpd_writeAccessLog(server, r); - return; - } - if (entry->preload) - { - if ((entry->preload)(server) < 0) - { - _httpd_writeAccessLog(server, r); - return; - } - } - switch(entry->type) - { - case HTTP_C_FUNCT: - case HTTP_C_WILDCARD: - (entry->function)(server, r); - break; - - case HTTP_STATIC: - _httpd_sendStatic(server, r, entry->data); - break; - - case HTTP_FILE: - _httpd_sendFile(server, r, entry->path); - break; - - case HTTP_WILDCARD: - if (_httpd_sendDirectoryEntry(server, r, entry, - entryName)<0) - { - _httpd_send404(server, r); - } - break; - } - _httpd_writeAccessLog(server, r); -} - -void httpdSetAccessLog(server, fp) - httpd *server; - FILE *fp; -{ - server->accessLog = fp; -} - -void httpdSetErrorLog(server, fp) - httpd *server; - FILE *fp; -{ - server->errorLog = fp; -} - -void httpdAuthenticate(request *r, const char *realm) -{ - char buffer[255]; - - if (r->request.authLength == 0) - { - httpdSetResponse(r, "401 Please Authenticate"); - snprintf(buffer,sizeof(buffer), - "WWW-Authenticate: Basic realm=\"%s\"\n", realm); - httpdAddHeader(r, buffer); - httpdOutput(r,"\n"); - } -} - - -void httpdForceAuthenticate(request *r, const char *realm) -{ - char buffer[255]; - - httpdSetResponse(r, "401 Please Authenticate"); - snprintf(buffer,sizeof(buffer), - "WWW-Authenticate: Basic realm=\"%s\"\n", realm); - httpdAddHeader(r, buffer); - httpdOutput(r,"\n"); ->>>>>>> FETCH_HEAD } diff --git a/libhttpd/httpd.h b/libhttpd/httpd.h index f078c6a5..eb5012d1 100644 --- a/libhttpd/httpd.h +++ b/libhttpd/httpd.h @@ -22,10 +22,6 @@ ** libhttpd Header File */ -<<<<<<< HEAD -======= - ->>>>>>> FETCH_HEAD /*********************************************************************** ** Standard header preamble. Ensure singular inclusion, setup for ** function prototypes and c++ inclusion @@ -39,15 +35,9 @@ #if !defined(__ANSI_PROTO) #if defined(_WIN32) || defined(__STDC__) || defined(__cplusplus) -<<<<<<< HEAD #define __ANSI_PROTO(x) x #else #define __ANSI_PROTO(x) () -======= -# define __ANSI_PROTO(x) x -#else -# define __ANSI_PROTO(x) () ->>>>>>> FETCH_HEAD #endif #endif @@ -59,19 +49,10 @@ extern "C" { #endif -<<<<<<< HEAD -======= - - ->>>>>>> FETCH_HEAD /*********************************************************************** ** Macro Definitions */ -<<<<<<< HEAD -======= - ->>>>>>> FETCH_HEAD #define HTTP_PORT 80 #define HTTP_MAX_LEN 10240 #define HTTP_MAX_URL 1024 @@ -105,20 +86,12 @@ extern "C" { #define HTTP_ACL_PERMIT 1 #define HTTP_ACL_DENY 2 -<<<<<<< HEAD extern char LIBHTTPD_VERSION[], LIBHTTPD_VENDOR[]; -======= - - -extern char LIBHTTPD_VERSION[], - LIBHTTPD_VENDOR[]; ->>>>>>> FETCH_HEAD /*********************************************************************** ** Type Definitions */ -<<<<<<< HEAD typedef struct { int method, contentLength, authLength; char path[HTTP_MAX_URL], query[HTTP_MAX_URL], host[HTTP_MAX_URL], /* acv@acv.ca/wifidog: Added decoding @@ -176,104 +149,11 @@ extern char LIBHTTPD_VERSION[], httpVar *variables; char readBuf[HTTP_READ_BUF_LEN + 1], *readBufPtr, clientAddr[HTTP_IP_ADDR_LEN]; } request; -======= -typedef struct { - int method, - contentLength, - authLength; - char path[HTTP_MAX_URL], - query[HTTP_MAX_URL], - host[HTTP_MAX_URL], /* acv@acv.ca/wifidog: Added decoding - of host: header if present. */ - ifModified[HTTP_MAX_URL]; -#if(0) - userAgent[HTTP_MAX_URL], - referer[HTTP_MAX_URL], - contentType[HTTP_MAX_URL], -#endif - char authUser[HTTP_MAX_AUTH]; - char authPassword[HTTP_MAX_AUTH]; -} httpReq; - - -typedef struct _httpd_var{ - char *name, - *value; - struct _httpd_var *nextValue, - *nextVariable; -} httpVar; - -typedef struct _httpd_content{ - char *name; - int type, - indexFlag; - void (*function)(); - char *data, - *path; - int (*preload)(); - struct _httpd_content *next; -} httpContent; - -typedef struct { - int responseLength; - httpContent *content; - char headersSent, - headers[HTTP_MAX_HEADERS], - response[HTTP_MAX_URL], - contentType[HTTP_MAX_URL]; -} httpRes; - - -typedef struct _httpd_dir{ - char *name; - struct _httpd_dir *children, - *next; - struct _httpd_content *entries; -} httpDir; - - -typedef struct ip_acl_s{ - int addr; - char len, - action; - struct ip_acl_s *next; -} httpAcl; - -typedef struct _httpd_404 { - void (*function)(); -} http404; - -typedef struct { - int port, - serverSock, - startTime, - lastError; - char fileBasePath[HTTP_MAX_URL], - *host; - httpDir *content; - httpAcl *defaultAcl; - http404 *handle404; - FILE *accessLog, - *errorLog; -} httpd; - -typedef struct { - int clientSock, - readBufRemain; - httpReq request; - httpRes response; - httpVar *variables; - char readBuf[HTTP_READ_BUF_LEN + 1], - *readBufPtr, - clientAddr[HTTP_IP_ADDR_LEN]; -} request; ->>>>>>> FETCH_HEAD /*********************************************************************** ** Function Prototypes */ -<<<<<<< HEAD int httpdAddCContent __ANSI_PROTO((httpd *, char *, char *, int, int (*)(), void (*)())); int httpdAddFileContent __ANSI_PROTO((httpd *, char *, char *, int, int (*)(), char *)); int httpdAddStaticContent __ANSI_PROTO((httpd *, char *, char *, int, int (*)(), char *)); @@ -317,65 +197,12 @@ typedef struct { httpVar *httpdGetNextVariableByPrefix __ANSI_PROTO((httpVar *, const char *)); httpAcl *httpdAddAcl __ANSI_PROTO((httpd *, httpAcl *, char *, int)); -======= - -int httpdAddCContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),void(*)())); -int httpdAddFileContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); -int httpdAddStaticContent __ANSI_PROTO((httpd*,char*,char*,int,int(*)(),char*)); -int httpdAddWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),char*)); -int httpdAddCWildcardContent __ANSI_PROTO((httpd*,char*,int(*)(),void(*)())); -int httpdAddVariable __ANSI_PROTO((request*, const char*, const char*)); -request *httpdGetConnection __ANSI_PROTO((httpd*, struct timeval*)); -int httpdReadRequest __ANSI_PROTO((httpd*, request*)); -int httpdCheckAcl __ANSI_PROTO((httpd*, request *, httpAcl*)); -int httpdAddC404Content __ANSI_PROTO((httpd*,void(*)())); - -char *httpdRequestMethodName __ANSI_PROTO((request*)); -char *httpdUrlEncode __ANSI_PROTO((const char *)); - -void httpdAddHeader __ANSI_PROTO((request*, const char*)); -void httpdSetContentType __ANSI_PROTO((request*, const char*)); -void httpdSetResponse __ANSI_PROTO((request*, const char*)); -void httpdEndRequest __ANSI_PROTO((request*)); - -httpd *httpdCreate __ANSI_PROTO(()); -void httpdFreeVariables __ANSI_PROTO((request*)); -void httpdDumpVariables __ANSI_PROTO((request*)); -void httpdOutput __ANSI_PROTO((request*, const char*)); -void httpdPrintf __ANSI_PROTO((request*, const char*, ...)); -void httpdProcessRequest __ANSI_PROTO((httpd*, request *)); -void httpdSendHeaders __ANSI_PROTO((request*)); -void httpdSetFileBase __ANSI_PROTO((httpd*, const char*)); -void httpdSetCookie __ANSI_PROTO((request*, const char*, const char*)); - -void httpdSetErrorLog __ANSI_PROTO((httpd*, FILE*)); -void httpdSetAccessLog __ANSI_PROTO((httpd*, FILE*)); -void httpdSetDefaultAcl __ANSI_PROTO((httpd*, httpAcl*)); - -httpVar *httpdGetVariableByName __ANSI_PROTO((request*, const char*)); -httpVar *httpdGetVariableByPrefix __ANSI_PROTO((request*, const char*)); -httpVar *httpdGetVariableByPrefixedName __ANSI_PROTO((request*, const char*, const char*)); -httpVar *httpdGetNextVariableByPrefix __ANSI_PROTO((httpVar*, const char*)); - -httpAcl *httpdAddAcl __ANSI_PROTO((httpd*, httpAcl*, char*, int)); - -void httpdAuthenticate __ANSI_PROTO((request*, const char*)); -void httpdForceAuthenticate __ANSI_PROTO((request*, const char*)); ->>>>>>> FETCH_HEAD /*********************************************************************** ** Standard header file footer. */ #ifdef __cplusplus -<<<<<<< HEAD } #endif /* __cplusplus */ #endif /* file inclusion */ -======= - } -#endif /* __cplusplus */ -#endif /* file inclusion */ - - ->>>>>>> FETCH_HEAD diff --git a/libhttpd/httpd_priv.h b/libhttpd/httpd_priv.h index 38634afc..b5a13cd2 100644 --- a/libhttpd/httpd_priv.h +++ b/libhttpd/httpd_priv.h @@ -22,10 +22,6 @@ ** libhttpd Private Header File */ -<<<<<<< HEAD -======= - ->>>>>>> FETCH_HEAD /*********************************************************************** ** Standard header preamble. Ensure singular inclusion, setup for ** function prototypes and c++ inclusion @@ -37,15 +33,9 @@ #if !defined(__ANSI_PROTO) #if defined(_WIN32) || defined(__STDC__) || defined(__cplusplus) -<<<<<<< HEAD #define __ANSI_PROTO(x) x #else #define __ANSI_PROTO(x) () -======= -# define __ANSI_PROTO(x) x -#else -# define __ANSI_PROTO(x) () ->>>>>>> FETCH_HEAD #endif #endif @@ -53,7 +43,6 @@ extern "C" { #endif -<<<<<<< HEAD #define LEVEL_NOTICE "notice" #define LEVEL_ERROR "error" @@ -92,42 +81,3 @@ extern "C" { } #endif #endif /* LIB_HTTPD_PRIV_H */ -======= - -#define LEVEL_NOTICE "notice" -#define LEVEL_ERROR "error" - -char * _httpd_unescape __ANSI_PROTO((char*)); -char *_httpd_escape __ANSI_PROTO((const char*)); -char _httpd_from_hex __ANSI_PROTO((char)); - - -void _httpd_catFile __ANSI_PROTO((request*, char*)); -void _httpd_send403 __ANSI_PROTO((request*)); -void _httpd_send404 __ANSI_PROTO((httpd*, request*)); -void _httpd_sendText __ANSI_PROTO((request*, char*)); -void _httpd_sendFile __ANSI_PROTO((httpd*, request*, char*)); -void _httpd_sendStatic __ANSI_PROTO((httpd*, request *, char*)); -void _httpd_sendHeaders __ANSI_PROTO((request*, int, int);) -void _httpd_sanitiseUrl __ANSI_PROTO((char*)); -void _httpd_freeVariables __ANSI_PROTO((httpVar*)); -void _httpd_formatTimeString __ANSI_PROTO((char*, int)); -void _httpd_storeData __ANSI_PROTO((request*, char*)); -void _httpd_writeAccessLog __ANSI_PROTO((httpd*, request*)); -void _httpd_writeErrorLog __ANSI_PROTO((httpd*, request *, char*, char*)); - - -int _httpd_net_read __ANSI_PROTO((int, char*, int)); -int _httpd_net_write __ANSI_PROTO((int, char*, int)); -int _httpd_readBuf __ANSI_PROTO((request*, char*, int)); -int _httpd_readChar __ANSI_PROTO((request*, char*)); -int _httpd_readLine __ANSI_PROTO((request*, char*, int)); -int _httpd_checkLastModified __ANSI_PROTO((request*, int)); -int _httpd_sendDirectoryEntry __ANSI_PROTO((httpd*, request *r, httpContent*, - char*)); - -httpContent *_httpd_findContentEntry __ANSI_PROTO((request*, httpDir*, char*)); -httpDir *_httpd_findContentDir __ANSI_PROTO((httpd*, char*, int)); - -#endif /* LIB_HTTPD_PRIV_H */ ->>>>>>> FETCH_HEAD diff --git a/libhttpd/ip_acl.c b/libhttpd/ip_acl.c index debc1f48..6b3e48b9 100644 --- a/libhttpd/ip_acl.c +++ b/libhttpd/ip_acl.c @@ -32,23 +32,14 @@ #include "httpd.h" #include "httpd_priv.h" -<<<<<<< HEAD -======= - ->>>>>>> FETCH_HEAD /************************************************************************** ** GLOBAL VARIABLES **************************************************************************/ -<<<<<<< HEAD -======= - ->>>>>>> FETCH_HEAD /************************************************************************** ** PRIVATE ROUTINES **************************************************************************/ -<<<<<<< HEAD static int scanCidr(val, result, length) char *val; @@ -119,96 +110,10 @@ _isInCidrBlock(httpd * server, request * r, int addr1, int len1, int addr2, int } } -======= -static int scanCidr(val, result, length) - char *val; - u_int *result, - *length; -{ - u_int res, res1, res2, res3, res4, res5; - char *cp; - - cp = val; - res1 = atoi(cp); - cp = strchr(cp,'.'); - if (!cp) - return(-1); - cp++; - res2 = atoi(cp); - cp = strchr(cp,'.'); - if (!cp) - return(-1); - cp++; - res3 = atoi(cp); - cp = strchr(cp,'.'); - if (!cp) - return(-1); - cp++; - res4 = atoi(cp); - cp = strchr(cp,'/'); - if (!cp) - { - res5 = 32; - } - else - { - cp++; - res5 = atoi(cp); - } - - if (res1>255 || res2>255 || res3>255 || res4>255 || res5>32) - { - return(-1); - } - res = (res1 << 24) + (res2 << 16) + (res3 << 8) + res4; - *result = res; - *length = res5; - return(0); -} - - -static int _isInCidrBlock(httpd *server, request *r, int addr1, int len1, - int addr2, int len2) -{ - int count, - mask; - - /* if (addr1 == 0 && len1 == 0) - { - return(1); - }*/ - - if(len2 < len1) - { - _httpd_writeErrorLog(server, r, LEVEL_ERROR, - "IP Address must be more specific than network block"); - return(0); - } - - mask = count = 0; - while(count < len1) - { - mask = (mask << 1) + 1; - count++; - } - mask = mask << (32 - len1); - if ( (addr1 & mask) == (addr2 & mask)) - { - return(1); - } - else - { - return(0); - } -} - - ->>>>>>> FETCH_HEAD /************************************************************************** ** PUBLIC ROUTINES **************************************************************************/ -<<<<<<< HEAD httpAcl * httpdAddAcl(server, acl, cidr, action) httpd *server; @@ -291,98 +196,4 @@ httpd *server; httpAcl *acl; { server->defaultAcl = acl; -======= -httpAcl *httpdAddAcl(server, acl, cidr, action) - httpd *server; - httpAcl *acl; - char *cidr; - int action; -{ - httpAcl *cur; - int addr, - len; - - /* - ** Check the ACL info is reasonable - */ - if(scanCidr(cidr, &addr, &len) < 0) - { - _httpd_writeErrorLog(server, NULL, LEVEL_ERROR, - "Invalid IP address format"); - return(NULL); - } - if (action != HTTP_ACL_PERMIT && action != HTTP_ACL_DENY) - { - _httpd_writeErrorLog(server, NULL, LEVEL_ERROR, - "Invalid acl action"); - return(NULL); - } - - /* - ** Find a spot to put this ACE - */ - if (acl) - { - cur = acl; - while(cur->next) - { - cur = cur->next; - } - cur->next = (httpAcl*)malloc(sizeof(httpAcl)); - cur = cur->next; - } - else - { - cur = (httpAcl*)malloc(sizeof(httpAcl)); - acl = cur; - } - - /* - ** Add the details and return - */ - cur->addr = addr; - cur->len = len; - cur->action = action; - cur->next = NULL; - return(acl); -} - - -int httpdCheckAcl(httpd *server, request *r, httpAcl *acl) -{ - httpAcl *cur; - int addr, len, - res, - action; - - - action = HTTP_ACL_DENY; - scanCidr(r->clientAddr, &addr, &len); - cur = acl; - while(cur) - { - res = _isInCidrBlock(server, r, cur->addr, cur->len, addr, len); - if (res == 1) - { - action = cur->action; - break; - } - cur = cur->next; - } - if (action == HTTP_ACL_DENY) - { - _httpd_send403(r); - _httpd_writeErrorLog(server, r, LEVEL_ERROR, - "Access denied by ACL"); - } - return(action); -} - - -void httpdSetDefaultAcl(server, acl) - httpd *server; - httpAcl *acl; -{ - server->defaultAcl = acl; ->>>>>>> FETCH_HEAD } diff --git a/libhttpd/protocol.c b/libhttpd/protocol.c index 3fe8d461..23680186 100644 --- a/libhttpd/protocol.c +++ b/libhttpd/protocol.c @@ -24,19 +24,11 @@ #include #include #include -<<<<<<< HEAD #include #if defined(_WIN32) #else #include -======= -#include -#include - -#if defined(_WIN32) -#else ->>>>>>> FETCH_HEAD #include #include #endif @@ -45,7 +37,6 @@ #include "httpd.h" #include "httpd_priv.h" -<<<<<<< HEAD int _httpd_net_read(sock, buf, len) int sock; @@ -287,272 +278,6 @@ char *str; *q = _httpd_from_hex(*p++) * 16; if (*p) *q = (*q + _httpd_from_hex(*p++)); -======= -int _httpd_net_read(sock, buf, len) - int sock; - char *buf; - int len; -{ -#if defined(_WIN32) - return( recv(sock, buf, len, 0)); -#else - /*return( read(sock, buf, len));*/ - /* XXX Select based IO */ - - int nfds; - fd_set readfds; - struct timeval timeout; - - FD_ZERO(&readfds); - FD_SET(sock, &readfds); - timeout.tv_sec = 10; - timeout.tv_usec = 0; - nfds = sock + 1; - - nfds = select(nfds, &readfds, NULL, NULL, &timeout); - - if (nfds > 0) { - return(read(sock, buf, len)); - } - return(nfds); -#endif -} - - -int _httpd_net_write(sock, buf, len) - int sock; - char *buf; - int len; -{ -#if defined(_WIN32) - return( send(sock, buf, len, 0)); -#else - return( write(sock, buf, len)); -#endif -} - -int _httpd_readChar(request *r, char *cp) -{ - if (r->readBufRemain == 0) - { - bzero(r->readBuf, HTTP_READ_BUF_LEN + 1); - r->readBufRemain = _httpd_net_read(r->clientSock, - r->readBuf, HTTP_READ_BUF_LEN); - if (r->readBufRemain < 1) - return(0); - r->readBuf[r->readBufRemain] = 0; - r->readBufPtr = r->readBuf; - } - *cp = *r->readBufPtr++; - r->readBufRemain--; - return(1); -} - - -int _httpd_readLine(request *r, char *destBuf, int len) -{ - char curChar, - *dst; - int count; - - - count = 0; - dst = destBuf; - while(count < len) - { - if (_httpd_readChar(r, &curChar) < 1) - return(0); - // Fixed by Mina - if we read binary junk it's probably not a regular HTTP client - //if (curChar == '\n') - if (curChar == '\n' || !isascii(curChar)) - { - *dst = 0; - return(1); - } - if (curChar == '\r') - { - continue; - } - else - { - *dst++ = curChar; - count++; - } - } - *dst = 0; - return(1); -} - - -int _httpd_readBuf(request *r, char *destBuf, int len) -{ - char curChar, - *dst; - int count; - - - count = 0; - dst = destBuf; - while(count < len) - { - if (_httpd_readChar(r, &curChar) < 1) - return(0); - *dst++ = curChar; - count++; - } - return(1); -} - -void _httpd_writeAccessLog(httpd *server, request *r) -{ - char dateBuf[30]; - struct tm *timePtr; - time_t clock; - int responseCode; - - - if (server->accessLog == NULL) - return; - clock = time(NULL); - timePtr = localtime(&clock); - strftime(dateBuf, 30, "%d/%b/%Y:%T %Z", timePtr); - responseCode = atoi(r->response.response); - fprintf(server->accessLog, "%s - - [%s] %s \"%s\" %d %d\n", - r->clientAddr, dateBuf, httpdRequestMethodName(r), - httpdRequestPath(r), responseCode, - r->response.responseLength); -} - -void _httpd_writeErrorLog(httpd *server, request *r, char *level, char *message) -{ - char dateBuf[30]; - struct tm *timePtr; - time_t clock; - - - if (server->errorLog == NULL) - return; - clock = time(NULL); - timePtr = localtime(&clock); - strftime(dateBuf, 30, "%a %b %d %T %Y", timePtr); - if (r != NULL && *r->clientAddr != 0) - { - fprintf(server->errorLog, "[%s] [%s] [client %s] %s\n", - dateBuf, level, r->clientAddr, message); - } - else - { - fprintf(server->errorLog, "[%s] [%s] %s\n", - dateBuf, level, message); - } -} - - - -int _httpd_decode (bufcoded, bufplain, outbufsize) - char * bufcoded; - char * bufplain; - int outbufsize; -{ - static char six2pr[64] = { - 'A','B','C','D','E','F','G','H','I','J','K','L','M', - 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', - 'a','b','c','d','e','f','g','h','i','j','k','l','m', - 'n','o','p','q','r','s','t','u','v','w','x','y','z', - '0','1','2','3','4','5','6','7','8','9','+','/' - }; - - static unsigned char pr2six[256]; - - /* single character decode */ -# define DEC(c) pr2six[(int)c] -# define _DECODE_MAXVAL 63 - - static int first = 1; - - int nbytesdecoded, j; - register char *bufin = bufcoded; - register char *bufout = bufplain; - register int nprbytes; - - /* - ** If this is the first call, initialize the mapping table. - ** This code should work even on non-ASCII machines. - */ - if(first) - { - first = 0; - for(j=0; j<256; j++) pr2six[j] = _DECODE_MAXVAL+1; - for(j=0; j<64; j++) pr2six[(int)six2pr[j]] = (unsigned char)j; - } - - /* Strip leading whitespace. */ - - while(*bufcoded==' ' || *bufcoded == '\t') bufcoded++; - - /* - ** Figure out how many characters are in the input buffer. - ** If this would decode into more bytes than would fit into - ** the output buffer, adjust the number of input bytes downwards. - */ - bufin = bufcoded; - while(pr2six[(int)*(bufin++)] <= _DECODE_MAXVAL); - nprbytes = bufin - bufcoded - 1; - nbytesdecoded = ((nprbytes+3)/4) * 3; - if(nbytesdecoded > outbufsize) - { - nprbytes = (outbufsize*4)/3; - } - bufin = bufcoded; - - while (nprbytes > 0) - { - *(bufout++)=(DEC(*bufin)<<2|DEC(bufin[1])>>4); - *(bufout++)=(DEC(bufin[1])<<4|DEC(bufin[2])>>2); - *(bufout++)=(DEC(bufin[2])<<6|DEC(bufin[3])); - bufin += 4; - nprbytes -= 4; - } - if(nprbytes & 03) - { - if(pr2six[(int)bufin[-2]] > _DECODE_MAXVAL) - { - nbytesdecoded -= 2; - } - else - { - nbytesdecoded -= 1; - } - } - bufplain[nbytesdecoded] = 0; - return(nbytesdecoded); -} - - - -char _httpd_from_hex (c) - char c; -{ - return c >= '0' && c <= '9' ? c - '0' - : c >= 'A' && c <= 'F'? c - 'A' + 10 - : c - 'a' + 10; /* accept small letters just in case */ -} - -char * _httpd_unescape(str) - char *str; -{ - char * p = str; - char * q = str; - static char blank[] = ""; - - if (!str) - return(blank); - while(*p) { - if (*p == '%') { - p++; - if (*p) *q = _httpd_from_hex(*p++) * 16; - if (*p) *q = (*q + _httpd_from_hex(*p++)); ->>>>>>> FETCH_HEAD q++; } else { if (*p == '+') { @@ -560,17 +285,12 @@ char * _httpd_unescape(str) p++; } else { *q++ = *p++; -<<<<<<< HEAD } -======= - } ->>>>>>> FETCH_HEAD } } *q++ = 0; return str; -<<<<<<< HEAD } void @@ -898,372 +618,10 @@ static unsigned char isAcceptable[96] = #define URL_XALPHAS (unsigned char) 1 #define URL_XPALPHAS (unsigned char) 2 /* Bit 0 xalpha -- see RFC 1630 -======= -} - - -void _httpd_freeVariables(var) - httpVar *var; -{ - httpVar *curVar, *lastVar; - - if (var == NULL) - return; - _httpd_freeVariables(var->nextVariable); - var->nextVariable = NULL; - curVar = var; - while(curVar) - { - lastVar = curVar; - curVar = curVar->nextValue; - free(lastVar->name); - free(lastVar->value); - free(lastVar); - } - return; -} - -void _httpd_storeData(request *r, char *query) -{ - char *cp, - *cp2, - *var, - *val, - *tmpVal; - - if (!query) - return; - - var = (char *)malloc(strlen(query)); - - cp = query; - cp2 = var; - bzero(var, strlen(query)); - val = NULL; - while(*cp) - { - if (*cp == '=') - { - cp++; - *cp2 = 0; - val = cp; - continue; - } - if (*cp == '&') - { - *cp = 0; - tmpVal = _httpd_unescape(val); - httpdAddVariable(r, var, tmpVal); - cp++; - cp2 = var; - val = NULL; - continue; - } - if (val) - { - cp++; - } - else - { - *cp2 = *cp++; - /* - if (*cp2 == '.') - { - strcpy(cp2,"_dot_"); - cp2 += 5; - } - else - { - */ - cp2++; - /* - } - */ - } - } - if (val != NULL) { - *cp = 0; - tmpVal = _httpd_unescape(val); - httpdAddVariable(r, var, tmpVal); - } - free(var); -} - - -void _httpd_formatTimeString(char *ptr, int clock) -{ - struct tm *timePtr; - time_t t; - - t = (clock == 0) ? time(NULL) : clock; - timePtr = gmtime(&t); - strftime(ptr, HTTP_TIME_STRING_LEN,"%a, %d %b %Y %T GMT",timePtr); -} - - -void _httpd_sendHeaders(request *r, int contentLength, int modTime) -{ - char tmpBuf[80], - timeBuf[HTTP_TIME_STRING_LEN]; - - if(r->response.headersSent) - return; - - r->response.headersSent = 1; - _httpd_net_write(r->clientSock, "HTTP/1.0 ", 9); - _httpd_net_write(r->clientSock, r->response.response, - strlen(r->response.response)); - _httpd_net_write(r->clientSock, r->response.headers, - strlen(r->response.headers)); - - _httpd_formatTimeString(timeBuf, 0); - _httpd_net_write(r->clientSock,"Date: ", 6); - _httpd_net_write(r->clientSock, timeBuf, strlen(timeBuf)); - _httpd_net_write(r->clientSock, "\n", 1); - - _httpd_net_write(r->clientSock, "Connection: close\n", 18); - _httpd_net_write(r->clientSock, "Content-Type: ", 14); - _httpd_net_write(r->clientSock, r->response.contentType, - strlen(r->response.contentType)); - _httpd_net_write(r->clientSock, "\n", 1); - - if (contentLength > 0) - { - _httpd_net_write(r->clientSock, "Content-Length: ", 16); - snprintf(tmpBuf, sizeof(tmpBuf), "%d", contentLength); - _httpd_net_write(r->clientSock, tmpBuf, strlen(tmpBuf)); - _httpd_net_write(r->clientSock, "\n", 1); - - _httpd_formatTimeString(timeBuf, modTime); - _httpd_net_write(r->clientSock, "Last-Modified: ", 15); - _httpd_net_write(r->clientSock, timeBuf, strlen(timeBuf)); - _httpd_net_write(r->clientSock, "\n", 1); - } - _httpd_net_write(r->clientSock, "\n", 1); -} - -httpDir *_httpd_findContentDir(server, dir, createFlag) - httpd *server; - char *dir; - int createFlag; -{ - char buffer[HTTP_MAX_URL], - *curDir; - httpDir *curItem, - *curChild; - - strncpy(buffer, dir, HTTP_MAX_URL); - buffer[HTTP_MAX_URL-1]=0; - curItem = server->content; - curDir = strtok(buffer,"/"); - while(curDir) - { - curChild = curItem->children; - while(curChild) - { - if (strcmp(curChild->name, curDir) == 0) - break; - curChild = curChild->next; - } - if (curChild == NULL) - { - if (createFlag == HTTP_TRUE) - { - curChild = malloc(sizeof(httpDir)); - bzero(curChild, sizeof(httpDir)); - curChild->name = strdup(curDir); - curChild->next = curItem->children; - curItem->children = curChild; - } - else - { - return(NULL); - } - } - curItem = curChild; - curDir = strtok(NULL,"/"); - } - return(curItem); -} - - -httpContent *_httpd_findContentEntry(request *r, httpDir *dir, char *entryName) -{ - httpContent *curEntry; - - curEntry = dir->entries; - while(curEntry) - { - if (curEntry->type == HTTP_WILDCARD || - curEntry->type ==HTTP_C_WILDCARD) - break; - if (*entryName == 0 && curEntry->indexFlag) - break; - if (strcmp(curEntry->name, entryName) == 0) - break; - curEntry = curEntry->next; - } - if (curEntry) - r->response.content = curEntry; - return(curEntry); -} - - -void _httpd_send304(request *r) -{ - httpdSetResponse(r, "304 Not Modified\n"); - _httpd_sendHeaders(r,0,0); -} - - -void _httpd_send403(request *r) -{ - httpdSetResponse(r, "403 Permission Denied\n"); - _httpd_sendHeaders(r,0,0); - _httpd_sendText(r, - "403 Permission Denied\n"); - _httpd_sendText(r, - "

Access to the request URL was denied!

\n"); -} - - -void _httpd_send404(httpd *server, request *r) -{ - char msg[HTTP_MAX_URL]; - - snprintf(msg, HTTP_MAX_URL, - "File does not exist: %s\n", r->request.path); - _httpd_writeErrorLog(server, r, LEVEL_ERROR, msg); - - if (server->handle404 && server->handle404->function) { - /* - * There's a custom C 404 handler defined with httpdAddC404Content - */ - (server->handle404->function)(server, r); - } - else { - /* - * Send stock 404 - */ - httpdSetResponse(r, "404 Not Found\n"); - _httpd_sendHeaders(r,0,0); - _httpd_sendText(r, - "404 Not Found\n"); - _httpd_sendText(r, - "

The request URL was not found!

\n"); - _httpd_sendText(r, "\n"); - } -} - - -void _httpd_catFile(request *r, char *path) -{ - int fd, - len; - char buf[HTTP_MAX_LEN]; - - fd = open(path,O_RDONLY); - if (fd < 0) - return; - len = read(fd, buf, HTTP_MAX_LEN); - while(len > 0) - { - r->response.responseLength += len; - _httpd_net_write(r->clientSock, buf, len); - len = read(fd, buf, HTTP_MAX_LEN); - } - close(fd); -} - - -void _httpd_sendStatic(httpd *server, request *r, char *data) -{ - if (_httpd_checkLastModified(r, server->startTime) == 0) - { - _httpd_send304(r); - } - _httpd_sendHeaders(r, server->startTime, strlen(data)); - httpdOutput(r, data); -} - - - -void _httpd_sendFile(httpd *server, request *r, char *path) -{ - char *suffix; - struct stat sbuf; - - suffix = strrchr(path, '.'); - if (suffix != NULL) - { - if (strcasecmp(suffix,".gif") == 0) - strcpy(r->response.contentType,"image/gif"); - if (strcasecmp(suffix,".jpg") == 0) - strcpy(r->response.contentType,"image/jpeg"); - if (strcasecmp(suffix,".xbm") == 0) - strcpy(r->response.contentType,"image/xbm"); - if (strcasecmp(suffix,".png") == 0) - strcpy(r->response.contentType,"image/png"); - } - if (stat(path, &sbuf) < 0) - { - _httpd_send404(server, r); - return; - } - if (_httpd_checkLastModified(r, sbuf.st_mtime) == 0) - { - _httpd_send304(r); - } - else - { - _httpd_sendHeaders(r, sbuf.st_size, sbuf.st_mtime); - _httpd_catFile(r, path); - } -} - - -int _httpd_sendDirectoryEntry(httpd *server, request *r, httpContent *entry, - char *entryName) -{ - char path[HTTP_MAX_URL]; - - snprintf(path, HTTP_MAX_URL, "%s/%s", entry->path, entryName); - _httpd_sendFile(server, r, path); - return(0); -} - - -void _httpd_sendText(request *r, char *msg) -{ - r->response.responseLength += strlen(msg); - _httpd_net_write(r->clientSock,msg,strlen(msg)); -} - - -int _httpd_checkLastModified(request *r, int modTime) -{ - char timeBuf[HTTP_TIME_STRING_LEN]; - - _httpd_formatTimeString(timeBuf, modTime); - if (strcmp(timeBuf, r->request.ifModified) == 0) - return(0); - return(1); -} - - -static unsigned char isAcceptable[96] = - -/* Overencodes */ -#define URL_XALPHAS (unsigned char) 1 -#define URL_XPALPHAS (unsigned char) 2 - -/* Bit 0 xalpha -- see HTFile.h ->>>>>>> FETCH_HEAD ** Bit 1 xpalpha -- as xalpha but with plus. ** Bit 2 ... path -- as xpalpha but with / */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ -<<<<<<< HEAD { 0, 7, 7, 0, 7, 0, 7, 7, 7, 7, 7, 6, 7, 7, 7, 4, /* 2x !"#$%&'()*+,-./ */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, /* 3x 0123456789:;<=>? */ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* 4x @ABCDEFGHIJKLMNO */ @@ -1302,52 +660,11 @@ const char *str; *q++ = hex[a & 15]; } else *q++ = *p; -======= - { 7,0,0,0,0,0,0,0,0,0,7,0,0,7,7,7, /* 2x !"#$%&'()*+,-./ */ - 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */ - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ - 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ - 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */ - 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0 }; /* 7X pqrstuvwxyz{\}~ DEL */ - -#define ACCEPTABLE(a) ( a>=32 && a<128 && ((isAcceptable[a-32]) & mask)) - -static char *hex = "0123456789ABCDEF"; - - -char *_httpd_escape(str) - const char *str; -{ - unsigned char mask = URL_XPALPHAS; - const char * p; - char * q; - char * result; - int unacceptable = 0; - for(p=str; *p; p++) - if (!ACCEPTABLE((unsigned char)*p)) - unacceptable +=2; - result = (char *) malloc(p-str + unacceptable + 1); - bzero(result,(p-str + unacceptable + 1)); - - if (result == NULL) - { - return(NULL); - } - for(q=result, p=str; *p; p++) { - unsigned char a = *p; - if (!ACCEPTABLE(a)) { - *q++ = '%'; /* Means hex commming */ - *q++ = hex[a >> 4]; - *q++ = hex[a & 15]; - } - else *q++ = *p; ->>>>>>> FETCH_HEAD } *q++ = 0; /* Terminate */ return result; } -<<<<<<< HEAD void _httpd_sanitiseUrl(url) char *url; @@ -1403,74 +720,4 @@ char *url; from++; } *to = 0; -======= - - -void _httpd_sanitiseUrl(url) - char *url; -{ - char *from, - *to, - *last; - - /* - ** Remove multiple slashes - */ - from = to = url; - while(*from) - { - if (*from == '/' && *(from+1) == '/') - { - from++; - continue; - } - *to = *from; - to++; - from++; - } - *to = 0; - - - /* - ** Get rid of ./ sequences - */ - from = to = url; - while(*from) - { - if (*from == '/' && *(from+1) == '.' && *(from+2)=='/') - { - from += 2; - continue; - } - *to = *from; - to++; - from++; - } - *to = 0; - - - /* - ** Catch use of /../ sequences and remove them. Must track the - ** path structure and remove the previous path element. - */ - from = to = last = url; - while(*from) - { - if (*from == '/' && *(from+1) == '.' && - *(from+2)=='.' && *(from+3)=='/') - { - to = last; - from += 3; - continue; - } - if (*from == '/') - { - last = to; - } - *to = *from; - to++; - from++; - } - *to = 0; ->>>>>>> FETCH_HEAD } diff --git a/libhttpd/version.c b/libhttpd/version.c index 89700a36..01df0b3a 100644 --- a/libhttpd/version.c +++ b/libhttpd/version.c @@ -18,10 +18,6 @@ ** */ -<<<<<<< HEAD char LIBHTTPD_VERSION[] = "1.4-wifidog", -======= -char LIBHTTPD_VERSION[] = "1.3", ->>>>>>> FETCH_HEAD LIBHTTPD_VENDOR[] = "Hughes Technologies Pty Ltd"; diff --git a/scripts/DOG_monitor.sh~ b/scripts/DOG_monitor.sh~ deleted file mode 100755 index b53acb6e..00000000 --- a/scripts/DOG_monitor.sh~ +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/sh -########################################################### -## -## Description: this scripts generate the interface traffic -## count file and clients rate file for the -## wifidog daemon,and monitor the wifidog daemon, -## if the wifidog was down,it will be start again. -## This scripts based on UCI and iptables,run on -## OpenWrt routers. -## Author: GaomingPan -## Lisence: GPL -## Date: 2015-09-12 -## Version: v1.2.0 -## -############################################################ - -############################################################ -## -## Function: iface_data_file_generator -## Description: generate the file that contains: interface -## name,Receive bytes,Transmit bytes,Rx rate in -## a second and Tx rate in a second. -## FileContentsFormat: -## ifacename RxBytes TxBytes dRx dTx -## -############################################################ -IFACE_DATA=/tmp/iface-data -T_IFACE_DATA=/tmp/.t_iface-data -DEV_FILE=/proc/net/dev -TMP=/tmp/.ftmp -TMP_D=/tmp/.ftmpd - -iface_data_file_generator() -{ - echo > $IFACE_DATA - echo > $T_IFACE_DATA - echo > $TMP - echo > $TMP_D - cat $DEV_FILE | sed 1d | sed 1d > $TMP - while read line - do - echo $line | awk '{print $1,$2,$10}' >> $T_IFACE_DATA - done < $TMP - sleep 1 - cat $DEV_FILE | sed 1d | sed 1d > $TMP - while read line - do - echo $line | awk '{print $1,$2,$10}' >> $IFACE_DATA - done < $TMP - sed '/^$/d' $T_IFACE_DATA > $TMP - cat $TMP > $T_IFACE_DATA - sed '/^$/d' $IFACE_DATA > $TMP - cat $TMP > $IFACE_DATA - echo > $TMP - i=$(awk 'END{print NR}' $IFACE_DATA) - while [ $i -gt 0 ] - do - read line < $IFACE_DATA - rx1=$(echo $line | awk '{print $2}') - tx1=$(echo $line | awk '{print $3}') - read line < $T_IFACE_DATA - rx2=$(echo $line | awk '{print $2}') - tx2=$(echo $line | awk '{print $3}') - cat $IFACE_DATA|sed 1d > $TMP - cat $TMP > $IFACE_DATA - cat $T_IFACE_DATA|sed 1d > $TMP - cat $TMP > $T_IFACE_DATA - drx=$(($rx1 - $rx2)) - dtx=$(($tx1 - $tx2)) - echo "$line $drx $dtx" >> $TMP_D - i=$(($i - 1)) - done - cat $TMP_D > $IFACE_DATA - -} - -########################################################## -## -## Function: clients_RxTxRate_generator -## Description: this function generator the client rate file. -## -########################################################### -UP_SPEED=/tmp/client.up.speed -DOWN_SPEED=/tmp/client.down.speed -MAC_IP=/tmp/mac-ip.client -I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') -CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') - -clients_RxTxRate_generator() -{ - cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP - iptables -N UPLOAD - iptables -N DOWNLOAD - while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP - sleep 1 - iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED - iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED - while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP - iptables -X UPLOAD - iptables -X DOWNLOAD -} - -################################################## -## -## Function: dog_daemon_monitor -## Description: monitor the wifidog daemon,if it -## was down,then start it. -## -################################################# -PID_NAME=wifidog -PID_FILE=/tmp/ps-info - -dog_daemon_monitor() -{ - ps > $PID_FILE - pid=$(cat $PID_FILE | grep $PID_NAME | awk '{print $1}') - - if [ -n "$pid" ] - then - return 1 - fi - - /usr/bin/wdctl stop > /dev/null - sleep 1 - /usr/bin/wifidog -d 1 & - - return 0 -} - -################################################## -## -## Function: man_loop -## Description: this is the mian function,do above -## things to refresh data. -## -################################################# -main_loop() -{ - while [ true ] - do - iface_data_file_generator - clients_RxTxRate_generator - dog_daemon_monitor - sleep $(($CHECK_INTERVAL - 3)) - done - } - -############################# -## -## now,do the loop -## -############################# -main_loop - diff --git a/scripts/GET_clients_rate.sh~ b/scripts/GET_clients_rate.sh~ deleted file mode 100755 index 148be403..00000000 --- a/scripts/GET_clients_rate.sh~ +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -###################################################################################################### -# -# Description: get the rate of clients,run in openwrt open router. -# Author: GaomingPan -# Version: v1.0.0 -# Lisence: GPL -# Date: 2015-09-08 -# -###################################################################################################### - -UP_SPEED=/tmp/client.up.speed -DOWN_SPEED=/tmp/client.down.speed -MAC_IP=/tmp/mac-ip.client -I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') -CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') - -while [ true ] - do - cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP - iptables -N UPLOAD - iptables -N DOWNLOAD - while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP - sleep 1 - iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED - iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED - while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP - iptables -X UPLOAD - iptables -X DOWNLOAD - sleep $(($CHECK_INTERVAL - 2)) - done - diff --git a/scripts/GET_settings.sh b/scripts/GET_settings.sh deleted file mode 100755 index e0d69735..00000000 --- a/scripts/GET_settings.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -############################################################################################################################### -# -# description: get the settings of wireless, -# lan,wan,reboot_info and dhcp. -# use in OpenWrt router,based on uci -# Version: 1.0.0 -# Author: GaomingPan -# 2015-07-29 -# -# Pram: $1 gw_id -# $2 cmd_id -# -################################################################################################################################ -TMP=/tmp/.tmpfile -STMP=/tmp/.stmpfile -RESULT_FILE=/tmp/routersettings -RESULT="" -echo "" > $RESULT_FILE -RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" -RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" -uci show wireless > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"lan\":{" -uci show network.lan > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"wan\":{" -uci show network.wan > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"dhcp\":{" -uci show dhcp > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," -RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}]}} - -rm $TMP $STMP -echo $RESULT > $RESULT_FILE -##### -# delete the single quote ' character,because some uci version will echo ' to the file. -# -sed -i 's/'\''//g' $RESULT_FILE - - diff --git a/scripts/GET_settings.sh~ b/scripts/GET_settings.sh~ deleted file mode 100755 index b297aaf1..00000000 --- a/scripts/GET_settings.sh~ +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh -# -# description: get the settings of wireless, -# lan,wan,reboot_info and dhcp. -# use in OpenWrt router,based on uci -# Version: 1.0.0 -# Author: GaomingPan -# 2015-07-29 -# -# Pram: $1 gw_id -# $2 cmd_id -# -TMP=/tmp/.tmpfile -STMP=/tmp/.stmpfile -RESULT_FILE=/tmp/routersettings -RESULT="" -echo "" > $RESULT_FILE -RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" -RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" -uci show wireless > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"lan\":{" -uci show network.lan > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"wan\":{" -uci show network.wan > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"dhcp\":{" -uci show dhcp > $TMP -while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP -RESULT=${RESULT%,} -RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," -RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}], -RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" -RESULT=${RESULT%,}]}} - -rm $TMP $STMP -echo $RESULT > $RESULT_FILE -##### -# delete the single quote ' character,because some uci version will echo ' to the file. -# -sed -i 's/'\''//g' $RESULT_FILE - - diff --git a/scripts/TEST_ServerIsAlive.sh~ b/scripts/TEST_ServerIsAlive.sh~ deleted file mode 100755 index 43e4a7eb..00000000 --- a/scripts/TEST_ServerIsAlive.sh~ +++ /dev/null @@ -1,15 +0,0 @@ -#! /bin/sh -###################################################################################### -# -# Description: this script is test the remote auth server is always working, -# if the server is down,then the wifidog will be stop,after server -# is up,then will start the wifidog. -# Auth: GaomingPan -# Version: v1.0.0 -# Date: 2015-09-05 -# -##################################################################################### - -SERVER_FILE_FOR_TEST=IsAlive.html -SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') -SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') diff --git a/scripts/auth.sh b/scripts/auth.sh deleted file mode 100755 index 492a392b..00000000 --- a/scripts/auth.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -#live-8 empire.x@qq.com 20150513 - -hostname=`uci get wifidog.wifidog.gateway_hostname` -#DATE=`date +%Y-%m-%d-%H:%M:%S` -sum=0 -#echo --- 开始检查 --- -while [[ $sum -lt 3 ]] -do - if /bin/ping -c 1 $hostname >/dev/null - then -#echo --- æœå¡å™¨å¯è¿æ¥ï¼Œå†åˆ¤æ–­è¿›ç¨‹æ˜¯å¦å­˜åœ¨ï¼Œè¿›å…¥è¿›ç¨‹å®ˆæ¤å·¥ä½œ --- - ps | grep wifidog | grep -v grep | grep wifidog && echo wifidog-Running.... || /etc/init.d/wifidog start - - uci get wifidog.wifidog.wifidog_enable | grep '0' && echo "" > /usr/lm/script/wifidogcron.sh - - exit 0 - fi - sum=$((sum+1)) -# sleep 1 -done - ps | grep wifidog | grep -v grep | grep wifidog && /etc/init.d/wifidog stop - - uci get wifidog.wifidog.wifidog_enable | grep '0' && echo "" > /usr/lm/script/wifidogcron.sh - diff --git a/scripts/authServerIsAlive.sh b/scripts/authServerIsAlive.sh deleted file mode 100755 index 94ff510b..00000000 --- a/scripts/authServerIsAlive.sh +++ /dev/null @@ -1,19 +0,0 @@ -#! /bin/sh -###################################################################################### -# -# Description: this script is test the remote auth server is always working, -# if the server is down,then the wifidog will be stop,after server -# is up,then will start the wifidog. -# Auth: GaomingPan -# Version: v1.0.0 -# Date: 2015-09-05 -# -##################################################################################### - -SERVER_FILE_FOR_TEST=IsAlive.html -SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') -SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') -SERVER_URL_FOR_TEST=$SERVER_BASE_PATH:$SERVER_PORT/$SERVER_FILE_FOR_TEST - - - diff --git a/scripts/authServerIsAlive.sh~ b/scripts/authServerIsAlive.sh~ deleted file mode 100755 index e7b6189e..00000000 --- a/scripts/authServerIsAlive.sh~ +++ /dev/null @@ -1,18 +0,0 @@ -#! /bin/sh -###################################################################################### -# -# Description: this script is test the remote auth server is always working, -# if the server is down,then the wifidog will be stop,after server -# is up,then will start the wifidog. -# Auth: GaomingPan -# Version: v1.0.0 -# Date: 2015-09-05 -# -##################################################################################### - -SERVER_FILE_FOR_TEST=IsAlive.html -SERVER_BASE_PATH=http://$(uci get wifidog_conf.authServer.hostname | awk '{print $2}') -SERVER_PORT=$(uci get wifidog_conf.authServer.httpPort | awk '{print $2}') -SERVER_URL_FOR_TEST=$SERVER_BASE_PATH:$SERVER_PORT/$SERVER_FILE_FOR_TEST - - diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf deleted file mode 100755 index 778646ae..00000000 --- a/scripts/conf/dog_post_conf +++ /dev/null @@ -1,9 +0,0 @@ - -config dog_post 'url' - option 'info_url' 'http://108.108.108.7:8080/ReWiFiAuth/wifidog/result' - option 'normal_url' 'http://108.108.108.7:8080/ReWiFiAuth/wifidog/result' - -config dog_post 'rmflag' - option 'info_rmflag' 'result' - option 'normal_rmflag' 'result' - diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf deleted file mode 100755 index 39b3d74f..00000000 --- a/scripts/conf/wifidog_conf +++ /dev/null @@ -1,72 +0,0 @@ -package 'wifidog_conf' - -config 'wifidog_conf' 'single' - option gatewayId '#GatewayID default is mac addr' - option externalInterface '# ExternalInterface eth0' - option gatewayInterface 'GatewayInterface br-lan' - option gatewayAddress '# GatewayAddress 192.168.1.1' - option htmlMessageFile '# HtmlMessageFile /opt/wifidog/etc/wifidog-.html' - option daemon '# Deamon 1' - option gatewayPort '# GatewayPort 2060' - option proxyPort '# ProxyPort 0' - option httpdName '# HTTPDName WiFiDog' - option httpdMaxConn '# HTTPDMaxConn 10' - option httpdRealm '# HTTPDRealm WiFiDog' - option httpdUserName '# HTTPDUserName admin' - option httpdPassword '# HTTPDPassword secret' - option checkInterval 'CheckInterval 30' - option clientTimeout 'ClientTimeout 5' - - -config 'wifidog_conf' 'authServer' - option 'hostname' 'Hostname 108.108.108.7' - option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' - option 'sslPort' '# SSLPort (Optional;Default:443)' - option 'httpPort' 'HTTPPort 8080' - option 'path' 'Path /ReWiFiAuth/wifidog/' - option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' - option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' - option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' - option 'pingScriptPathFragment' '# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.)' - option 'authScriptPathFragment' '# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.)' - -config 'wifidog_conf' 'trustedMACList' - option 'enable' '1' - list 'TrustedMACList' '11:22:33:44:55:66' - list 'TrustedMACList' 'aa:bb:cc:dd:ee:ff' - -config 'wifidog_conf' 'untrustedMACList' - option 'enable' '1' - list 'UntrustedMACList' 'aa:bb:cc:dd:ee:ff' - - -config 'wifidog_conf' 'whiteBlackList' - option 'white_enable' '0' - option 'black_enable' '0' - list 'WhiteList' 'www.baidu.com' - list 'WhiteList' 'www.taobao.com' - list 'BlackList' 'www.google.com' - list 'BlackList' 'www.hao123.com' - - -config 'wifidog_conf' 'firewallRule_global' - list 'FirewallRuleSet_global' '# FirewallRule block to 192.168.0.0/16 L' - list 'FirewallRuleSet_global' '# FirewallRule block to 172.16.0.0/12 L' - - -config 'wifidog_conf' 'firewallRule_validating_users' - list 'FirewallRuleSet_validating_users' 'FirewallRule allow to 0.0.0.0/0 L' - - -config 'wifidog_conf' 'firewallRule_known_users' - list 'FirewallRuleSet_known_users' 'FirewallRule allow to 0.0.0.0/0 L' - -config 'wifidog_conf' 'firewallRule_unknown_users' - list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 53 L' - list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 53 L' - list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 67 L' - list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 67 L' - -config 'wifidog_conf' 'firewallRule_locked_users' - list 'FirewallRuleSet_locked_users' 'FirewallRule block to 0.0.0.0/0 L' - diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh deleted file mode 100755 index d2192933..00000000 --- a/scripts/dog_conf_generator.sh +++ /dev/null @@ -1,180 +0,0 @@ -#!/bin/sh -############################################################################################################## -# -# Generates the wifidog config file based on UCI -# -# Author : GaomingPan -# Date : 2015-08-05 -# Version: 1.0.0 -# -############################################################################################################### - -version="1.0.0" - -WIFI_DOG_CONF_FILE=/etc/wifidog.conf -WIFI_DOG_CONF=/etc/config/wifidog_conf -SINGLE=wifidog_conf.single -AUTH_SERVER=wifidog_conf.authServer -TRUSTED_MAC_LIST=wifidog_conf.trustedMACList -UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList -WHITE_LIST=wifidog_conf.whiteBlackList -BLACK_LIST=wifidog_conf.whiteBlackList -FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global -FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users -FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users -FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users -FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users - - -generate_single() -{ - echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE -} - -generate_authServer() -{ - echo "AuthServer {" >> $WIFI_DOG_CONF_FILE - echo "$(uci show $AUTH_SERVER | sed 1d | \ - awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -generate_trustedMACList() -{ - enable=$(uci get "$TRUSTED_MAC_LIST.enable") - - if [ $enable -ne 1 ] - then - return - fi - - echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - -generate_untrustedMACList() -{ - enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") - - if [ $enable -ne 1 ] - then - return - fi - - echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - -generate_whiteList() -{ - white_enable=$(uci get "$WHITE_LIST.white_enable") - - if [ $white_enable -ne 1 ] - then - return - fi - - echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - - -generate_blackList() -{ - black_enable=$(uci get "$BLACK_LIST.black_enable") - - if [ $black_enable -ne 1 ] - then - return - fi - - echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - - -generate_firewallRule_global() -{ - echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - - - -generate_firewallRule_validating_users() -{ - echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -generate_firewallRule_known_users() -{ - echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - - -generate_firewallRule_unknown_users() -{ - echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -generate_firewallRule_locked_users() -{ - echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -conf_character_check() -{ - -##### -# delete the single quote ' character,because some uci version will echo ' to the -# config file. - sed -i 's/'\''//g' $WIFI_DOG_CONF_FILE -#### -# delete the blank character at the line header - sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE - -#### -# delete the blank character at the line tail - sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE - -} - -generate_wifidog_conf_file() -{ - echo "###########################################################" > $WIFI_DOG_CONF_FILE - echo "## this is wifidog config file" >> $WIFI_DOG_CONF_FILE - echo "## auto generate by dog_conf_generator.sh" >> $WIFI_DOG_CONF_FILE - echo "## Version: $version Based on UCI" >> $WIFI_DOG_CONF_FILE - echo "############################################################" >> $WIFI_DOG_CONF_FILE - - generate_single - generate_authServer - generate_trustedMACList - generate_untrustedMACList - generate_whiteList - generate_blackList - generate_firewallRule_global - generate_firewallRule_validating_users - generate_firewallRule_known_users - generate_firewallRule_unknown_users - generate_firewallRule_locked_users - - conf_character_check -} - - -#echo "------ starting generate wifidog config file --------" - -generate_wifidog_conf_file - -#echo "------ wifidog config file generate complete --------" - diff --git a/scripts/dog_conf_generator.sh~ b/scripts/dog_conf_generator.sh~ deleted file mode 100755 index bb57d931..00000000 --- a/scripts/dog_conf_generator.sh~ +++ /dev/null @@ -1,180 +0,0 @@ -#!/bin/sh -############################################################################################################## -# -# Generates the wifidog config file based on UCI -# -# Author : GaomingPan -# Date : 2015-08-05 -# Version: 1.0.0 -# -############################################################################################################### - -version="1.0.0" - -WIFI_DOG_CONF_FILE=/etc/wifidog.conf -WIFI_DOG_CONF=/etc/config/wifidog_conf -SINGLE=wifidog_conf.single -AUTH_SERVER=wifidog_conf.authServer -TRUSTED_MAC_LIST=wifidog_conf.trustedMACList -UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList -WHITE_LIST=wifidog_conf.whiteBlackList -BLACK_LIST=wifidog_conf.whiteBlackList -FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global -FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users -FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users -FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users -FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users - - -generate_single() -{ - echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE -} - -generate_authServer() -{ - echo "AuthServer {" >> $WIFI_DOG_CONF_FILE - echo "$(uci show $AUTH_SERVER | sed 1d | \ - awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -generate_trustedMACList() -{ - enable=$(uci get "$TRUSTED_MAC_LIST.enable") - - if [ $enable -ne 1 ] - then - return - fi - - echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - -generate_untrustedMACList() -{ - enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") - - if [ $enable -ne 1 ] - then - return - fi - - echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - -generate_whiteList() -{ - white_enable=$(uci get "$WHITE_LIST.white_enable") - - if [ $white_enable -ne 1 ] - then - return - fi - - echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - - -generate_blackList() -{ - black_enable=$(uci get "$BLACK_LIST.black_enable") - - if [ $black_enable -ne 1 ] - then - return - fi - - echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ - tr " " ",")" >> $WIFI_DOG_CONF_FILE -} - - -generate_firewallRule_global() -{ - echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - - - -generate_firewallRule_validating_users() -{ - echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -generate_firewallRule_known_users() -{ - echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - - -generate_firewallRule_unknown_users() -{ - echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -generate_firewallRule_locked_users() -{ - echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE - echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE - echo "}" >> $WIFI_DOG_CONF_FILE -} - -conf_character_check() -{ - -##### -# delete the single quote ' character,because some uci version will echo ' to the -# config file. - sed -i 's/'\''//g' $WIFI_DOG_CONF_FILE -#### -# delete the blank character at the line header - sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE - -#### -# delete the blank character at the line tail - sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE - -} - -generate_wifidog_conf_file() -{ - echo "###########################################################" > $WIFI_DOG_CONF_FILE - echo "## this is wifidog config file" >> $WIFI_DOG_CONF_FILE - echo "## auto generate by dog_conf_generator.sh" >> $WIFI_DOG_CONF_FILE - echo "## Version: $version Based on UCI" >> $WIFI_DOG_CONF_FILE - echo "############################################################" >> $WIFI_DOG_CONF_FILE - - generate_single - generate_authServer - generate_trustedMACList - generate_untrustedMACList - generate_whiteList - generate_blackList - generate_firewallRule_global - generate_firewallRule_validating_users - generate_firewallRule_known_users - generate_firewallRule_unknown_users - generate_firewallRule_locked_users - - conf_character_check -} - - -echo "------ starting generate wifidog config file --------" - -generate_wifidog_conf_file - -echo "------ wifidog config file generate complete --------" - diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey deleted file mode 100755 index 12a3d538..00000000 --- a/scripts/etc/devicekey +++ /dev/null @@ -1,6 +0,0 @@ -######################################################## -## ### -## this file is the device key, do NOT modify it. ### -## ### -######################################################## -ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file diff --git a/scripts/init.d/wifidog b/scripts/init.d/wifidog index 1bcb1f8e..37ea5715 100644 --- a/scripts/init.d/wifidog +++ b/scripts/init.d/wifidog @@ -14,11 +14,7 @@ IPT=/usr/sbin/iptables WD_DIR=/usr/bin -<<<<<<< HEAD OPTIONS="-d 4" -======= -OPTIONS="-d 1" ->>>>>>> FETCH_HEAD case "$1" in start) diff --git a/scripts/white_black_flush.sh b/scripts/white_black_flush.sh deleted file mode 100755 index c951267b..00000000 --- a/scripts/white_black_flush.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/sh - - -RUN_DOG_PID=`pidof wifidog` -GATEWAY_INTERFACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $NF}') -WHITE_LIST_URL=$(uci get wifidog_conf.whiteBlackList.WhiteList) -BLACK_LIST_URL=$(uci get wifidog_conf.whiteBlackList.BlackList) - -#touch files -mkdir -p /tmp/.white_black_list - -#compare -while [ true ] -do - - WHITE_LIST_URL=$(uci get wifidog_conf.whiteBlackList.WhiteList) - BLACK_LIST_URL=$(uci get wifidog_conf.whiteBlackList.BlackList) - - #detect - iptables -t nat -L WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -n --line-numbers | awk '{for(i=6;i /tmp/.white_black_list/.white_list - iptables -t mangle -L WiFiDog_"$GATEWAY_INTERFACE"_BlackList -n --line-numbers | awk '{for(i=6;i /tmp/.white_black_list/.black_list - - rm /tmp/.white_black_list/.white_list_tmp - for white_list in $WHITE_LIST_URL - do - nslookup $white_list | sed "1d" | sed "1d" | sed "1d" | sed "1d" | awk '{for(i=3;i> /tmp/.white_black_list/.white_list_tmp - done - invalid=`grep -e ".*0\.0\..*" /tmp/.white_black_list/.white_list_tmp -rn|cut -d : -f 1` - [ $invalid ] && sed -r -i "/"$invalid/"d" /tmp/.white_black_list/.white_list_tmp - - rm /tmp/.white_black_list/.black_list_tmp - for black_list in $BLACK_LIST_URL - do - nslookup $black_list |sed "1d"|sed "1d" |sed "1d" |sed "1d"|awk '{for(i=3;i> /tmp/.white_black_list/.black_list_tmp - done - invalid=`grep -e ".*0\.0\..*" /tmp/.white_black_list/.black_list_tmp -rn|cut -d : -f 1` - [ $invalid ] && sed -r -i "/"$invalid/"d" /tmp/.white_black_list/.black_list_tmp - - #white - while read line_new - do - i=0 - - while read line_old - do - if [ "$line_new" != "$line_old" ]; then - i=1 - else - i=0 - break - fi - done < /tmp/.white_black_list/.white_list - - if [ "$i" -eq "1" ]; then - iptables -t nat -A WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -d "$line_new" -j ACCEPT - iptables -t filter -A WiFiDog_"$GATEWAY_INTERFACE"_WhiteList -d "$line_new" -j ACCEPT - #echo "-------------------------------------------------------------------------------limeng white diff -------------------------------------------------------------------------" - fi - done < /tmp/.white_black_list/.white_list_tmp - - sleep 10 - - #black - while read line_new - do - i=0 - - while read line_old - do - if [ "$line_new" != "$line_old" ]; then - i=1 - else - i=0 - break - fi - done < /tmp/.white_black_list/.black_list - - if [ "$i" -eq "1" ]; then - iptables -t mangle -A WiFiDog_"$GATEWAY_INTERFACE"_BlackList -d "$line_new" -j DROP - #echo "-------------------------------------------------------------------------------limeng black diff -------------------------------------------------------------------------" - fi - done < /tmp/.white_black_list/.black_list_tmp - - sleep 10 -done - diff --git a/src/Makefile.am b/src/Makefile.am index 5426f042..fba84cf0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,17 +2,13 @@ # $Id$ # -<<<<<<< HEAD noinst_LIBRARIES = libgateway.a -======= ->>>>>>> FETCH_HEAD bin_PROGRAMS = wifidog \ wdctl AM_CPPFLAGS = \ -I${top_srcdir}/libhttpd/ \ -<<<<<<< HEAD -DSYSCONFDIR='"$(sysconfdir)"' \ -Wall \ -Wextra \ @@ -22,19 +18,6 @@ wifidog_LDADD = libgateway.a $(top_builddir)/libhttpd/libhttpd.la wifidog_SOURCES = main.c libgateway_a_SOURCES = commandline.c \ -======= - -DSYSCONFDIR='"$(sysconfdir)"' -wifidog_LDADD = $(top_builddir)/libhttpd/libhttpd.la - -# -#@breif GaomingPan add file: -# get_devinfo.h get_devinfo.c -# shell_command.h -# get_clientinfo.h get_clientinfo.c -# get_remote_shell.h get_remote_shell.c -# -wifidog_SOURCES = commandline.c \ ->>>>>>> FETCH_HEAD conf.c \ debug.c \ fw_iptables.c \ @@ -49,16 +32,9 @@ wifidog_SOURCES = commandline.c \ ping_thread.c \ safe.c \ httpd_thread.c \ -<<<<<<< HEAD simple_http.c \ pstring.c \ wd_util.c -======= - get_devinfo.c \ - get_clientinfo.c \ - get_remote_shell.c \ - device_key.c ->>>>>>> FETCH_HEAD noinst_HEADERS = commandline.h \ common.h \ @@ -77,18 +53,10 @@ noinst_HEADERS = commandline.h \ ping_thread.h \ safe.h \ httpd_thread.h \ -<<<<<<< HEAD simple_http.h \ pstring.h \ wd_util.h wdctl_LDADD = libgateway.a -======= - shell_command.h \ - get_devinfo.h \ - get_clientinfo.h \ - get_remote_shell.h \ - device_key.h ->>>>>>> FETCH_HEAD wdctl_SOURCES = wdctl.c diff --git a/src/auth.c b/src/auth.c index 2517a964..77b7d908 100644 --- a/src/auth.c +++ b/src/auth.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -51,23 +48,12 @@ #include "firewall.h" #include "client_list.h" #include "util.h" -<<<<<<< HEAD #include "wd_util.h" -======= - - -/* Defined in clientlist.c */ -extern pthread_mutex_t client_list_mutex; - -/* Defined in util.c */ -extern long served_this_session; ->>>>>>> FETCH_HEAD /** Launches a thread that periodically checks if any of the connections has timed out @param arg Must contain a pointer to a string containing the IP adress of the client to check to check @todo Also pass MAC adress? @todo This thread loops infinitely, need a watchdog to verify that it is still running? -<<<<<<< HEAD */ void thread_client_timeout_check(const void *arg) @@ -126,35 +112,6 @@ logout_client(t_client * client) } client_free_node(client); -======= -*/ -void -thread_client_timeout_check(const void *arg) -{ - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; - struct timespec timeout; - - while (1) { - /* Sleep for config.checkinterval seconds... */ - timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; - timeout.tv_nsec = 0; - - /* Mutex must be locked for pthread_cond_timedwait... */ - pthread_mutex_lock(&cond_mutex); - - /* Thread safe "sleep" */ - pthread_cond_timedwait(&cond, &cond_mutex, &timeout); - - /* No longer needs to be locked */ - pthread_mutex_unlock(&cond_mutex); - - debug(LOG_DEBUG, "Running fw_counter()"); - - fw_sync_with_authserver(); - - } ->>>>>>> FETCH_HEAD } /** Authenticates a single client against the central server and returns when done @@ -162,7 +119,6 @@ thread_client_timeout_check(const void *arg) @param r httpd request struct */ void -<<<<<<< HEAD authenticate_client(request * r) { t_client *client, *tmp; @@ -266,22 +222,22 @@ authenticate_client(request * r) "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac); fw_allow(client, FW_MARK_KNOWN); served_this_session++; - - - /** add parameter: - ** gw_address,mac (client's MAC address). - ** Added by GaomingPan. - ** */ - //safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); - safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", - auth_server->authserv_portal_script_path_fragment, - config->gw_id, - config->gw_address, - client->mac - ); - /************************************/ + +/** add parameter: + * *gw_address,mac (client's MAC address). + * * Added by GaomingPan. + * * */ +//safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); +safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_portal_script_path_fragment, + config->gw_id, + config->gw_address, + client->mac + ); + debug(LOG_INFO,"PortalQString: [[<< ============== \n\n %s ============== >>]]\n\n",urlFragment); + /************************************/ - + http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); free(urlFragment); break; @@ -308,136 +264,3 @@ authenticate_client(request * r) UNLOCK_CLIENT_LIST(); return; } -======= -authenticate_client(request *r) -{ - t_client *client; - t_authresponse auth_response; - char *mac, - *token; - char *urlFragment = NULL; - s_config *config = NULL; - t_auth_serv *auth_server = NULL; - - LOCK_CLIENT_LIST(); - - client = client_list_find_by_ip(r->clientAddr); - - if (client == NULL) { - debug(LOG_ERR, "authenticate_client(): Could not find client for %s", r->clientAddr); - UNLOCK_CLIENT_LIST(); - return; - } - - mac = safe_strdup(client->mac); - token = safe_strdup(client->token); - - UNLOCK_CLIENT_LIST(); - - /* - * At this point we've released the lock while we do an HTTP request since it could - * take multiple seconds to do and the gateway would effectively be frozen if we - * kept the lock. - */ - auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0); - - LOCK_CLIENT_LIST(); - - /* can't trust the client to still exist after n seconds have passed */ - client = client_list_find(r->clientAddr, mac); - - if (client == NULL) { - debug(LOG_ERR, "authenticate_client(): Could not find client node for %s (%s)", r->clientAddr, mac); - UNLOCK_CLIENT_LIST(); - free(token); - free(mac); - return; - } - - free(token); - free(mac); - - /* Prepare some variables we'll need below */ - config = config_get_config(); - auth_server = get_auth_server(); - - switch(auth_response.authcode) { - - case AUTH_ERROR: - /* Error talking to central server */ - debug(LOG_ERR, "Got %d from central server authenticating token %s from %s at %s", auth_response, client->token, client->ip, client->mac); - send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server"); - break; - - case AUTH_DENIED: - /* Central server said invalid token */ - debug(LOG_INFO, "Got DENIED from central server authenticating token %s from %s at %s - deleting from firewall and redirecting them to denied message", client->token, client->ip, client->mac); - fw_deny(client->ip, client->mac, FW_MARK_KNOWN); - safe_asprintf(&urlFragment, "%smessage=%s", - auth_server->authserv_msg_script_path_fragment, - GATEWAY_MESSAGE_DENIED - ); - http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message"); - free(urlFragment); - break; - - case AUTH_VALIDATION: - /* They just got validated for X minutes to check their email */ - debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s" - "- adding to firewall and redirecting them to activate message", client->token, - client->ip, client->mac); - client->fw_connection_state = FW_MARK_PROBATION; - fw_allow(client->ip, client->mac, FW_MARK_PROBATION); - safe_asprintf(&urlFragment, "%smessage=%s&gw_id=%s&gw_address=%s&mac=%s", - auth_server->authserv_msg_script_path_fragment, - GATEWAY_MESSAGE_ACTIVATE_ACCOUNT, - config->gw_id, - config->gw_address, - client->mac - ); - http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message"); - free(urlFragment); - break; - - case AUTH_ALLOWED: - /* Logged in successfully as a regular account */ - debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - " - "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac); - client->fw_connection_state = FW_MARK_KNOWN; - fw_allow(client->ip, client->mac, FW_MARK_KNOWN); - served_this_session++; - safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", - auth_server->authserv_portal_script_path_fragment, - config->gw_id, - config->gw_address, - client->mac - ); - http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); - free(urlFragment); - break; - - case AUTH_VALIDATION_FAILED: - /* Client had X minutes to validate account by email and didn't = too late */ - debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s " - "- redirecting them to failed_validation message", client->token, client->ip, client->mac); - safe_asprintf(&urlFragment, "%smessage=%s", - auth_server->authserv_msg_script_path_fragment, - GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED - ); - http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message"); - free(urlFragment); - break; - - default: - debug(LOG_WARNING, "I don't know what the validation code %d means for token %s from %s at %s - sending error message", auth_response.authcode, client->token, client->ip, client->mac); - send_http_page(r, "Internal Error", "We can not validate your request at this time"); - break; - - } - - UNLOCK_CLIENT_LIST(); - return; -} - - ->>>>>>> FETCH_HEAD diff --git a/src/auth.h b/src/auth.h index 6eb940b8..caf24934 100644 --- a/src/auth.h +++ b/src/auth.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -32,10 +29,7 @@ #define _AUTH_H_ #include "httpd.h" -<<<<<<< HEAD #include "client_list.h" -======= ->>>>>>> FETCH_HEAD /** * @brief Authentication codes returned by auth server. @@ -59,11 +53,8 @@ typedef struct _t_authresponse { t_authcode authcode; /**< Authentication code returned by the server */ } t_authresponse; -<<<<<<< HEAD /** @brief Logout a client and report to auth server. */ void logout_client(t_client *); -======= ->>>>>>> FETCH_HEAD /** @brief Authenticate a single client against the central server */ void authenticate_client(request *); diff --git a/src/centralserver.c b/src/centralserver.c index ba3128f7..22c87099 100644 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set sw=4 ts=4 sts=4 et : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -46,10 +43,7 @@ #include "common.h" #include "safe.h" #include "util.h" -<<<<<<< HEAD #include "wd_util.h" -======= ->>>>>>> FETCH_HEAD #include "auth.h" #include "conf.h" #include "debug.h" @@ -57,22 +51,7 @@ #include "firewall.h" #include "../config.h" -<<<<<<< HEAD #include "simple_http.h" -======= -#include "client_list.h" - -/** - * include my header file. - */ -#include "get_clientinfo.h" -#include "device_key.h" - -extern pthread_mutex_t client_list_mutex; - -extern pthread_mutex_t config_mutex; - ->>>>>>> FETCH_HEAD /** Initiates a transaction with the auth server, either to authenticate or to * update the traffic counters at the server @@ -85,7 +64,6 @@ extern pthread_mutex_t config_mutex; @param outgoing Current counter of the client's total outgoing traffic, in bytes */ t_authcode -<<<<<<< HEAD auth_server_request(t_authresponse * authresponse, const char *request_type, const char *ip, const char *mac, const char *token, unsigned long long int incoming, unsigned long long int outgoing, unsigned long long int incoming_delta, unsigned long long int outgoing_delta) { @@ -166,253 +144,10 @@ auth_server_request(t_authresponse * authresponse, const char *request_type, con } free(res); return (AUTH_ERROR); -======= -auth_server_request(t_authresponse *authresponse, const char *request_type, const char *ip, const char *mac, const char *token, unsigned long long int incoming, unsigned long long int outgoing) -{ - int sockfd; - ssize_t numbytes; - size_t totalbytes; - char buf[MAX_BUF]; - char *tmp; - char *safe_token; - int done, nfds; - fd_set readfds; - struct timeval timeout; - t_auth_serv *auth_server = NULL; - auth_server = get_auth_server(); - - /* Blanket default is error. */ - authresponse->authcode = AUTH_ERROR; - - sockfd = connect_auth_server(); - if (sockfd == -1) { - /* Could not connect to any auth server */ - return (AUTH_ERROR); - } - - /** - * TODO: XXX change the PHP so we can harmonize stage as request_type - * everywhere. - */ - memset(buf, 0, sizeof(buf)); - safe_token=httpdUrlEncode(token); - - /** - * here I add some my info about the client. - */ - t_clientinfo *client_info; - long online_time; - int go_speed,come_speed; - - - if(0 == strcmp(request_type,REQUEST_TYPE_COUNTERS) || 0 == strcmp(request_type,REQUEST_TYPE_LOGOUT)){ - - LOCK_CLIENT_LIST(); - if(0 != collect_client_info()){ - debug(LOG_ERR,"ERROR: at collect_client_info() failed."); - printf("ERROR: at collect_client_info() failed.\n"); - } - online_time = get_online_time(ip,mac); - UNLOCK_CLIENT_LIST(); - - client_info = get_client_info_by_ip(ip); - //client_info = get_client_info_by_mac(mac); - if(NULL == client_info){ - //debug(LOG_ERR,"ERROR: at get_client_info_by_ip(ip) failed."); - debug(LOG_ERR,"ERROR: at get_client_info_by_mac(mac) failed."); - //printf("ERROR: at get_client_info_by_ip(ip) failed.\n"); - } - - /******************************************/ - - - - if(NULL != client_info){ - - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, - safe_token, - incoming, - outgoing, - config_get_config()->gw_id, - - /**************************** - * my new info. - * */ - client_info->host_name, - client_info->go_speed, - client_info->come_speed, - online_time, - get_client_auth_flag(), - /**************************/ - - VERSION, - auth_server->authserv_hostname, - /* device key*/ - get_device_key() - ); - - } else{ - - get_unknown_client_speed(ip,&go_speed,&come_speed); - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, - safe_token, - incoming, - outgoing, - config_get_config()->gw_id, - - - /**************************** - * my new info. - * */ - "unknown",//client_info->host_name, - go_speed, //client_info->go_speed, - come_speed, //client_info->come_speed, - online_time, //online_time, - get_client_auth_flag(), - /**************************/ - - VERSION, - auth_server->authserv_hostname, - /* device key*/ - get_device_key() - ); - } - - /** clean up the clients info,free the memories. - * */ - clean_client_info(); - - }else{ - - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, - safe_token, - incoming, - outgoing, - config_get_config()->gw_id, - - /**************************** - * my new info. - * */ - "null",//client_info->host_name, - 0,//client_info->go_speed, - 0,//client_info->come_speed, - 0,//online_time, - "null",//get_client_auth_flag(), - /**************************/ - - VERSION, - auth_server->authserv_hostname, - /* device key*/ - get_device_key() - ); - } - - free(safe_token); - - //debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf); - debug(LOG_INFO, "\n\nSendingQString: [[<< %s >>]]\n\n", buf); - send(sockfd, buf, strlen(buf), 0); - - debug(LOG_DEBUG, "Reading response"); - numbytes = totalbytes = 0; - done = 0; - do { - FD_ZERO(&readfds); - FD_SET(sockfd, &readfds); - timeout.tv_sec = 30; /* XXX magic... 30 second is as good a timeout as any */ - timeout.tv_usec = 0; - nfds = sockfd + 1; - - nfds = select(nfds, &readfds, NULL, NULL, &timeout); - - if (nfds > 0) { - /** We don't have to use FD_ISSET() because there - * was only one fd. */ - numbytes = read(sockfd, buf + totalbytes, MAX_BUF - (totalbytes + 1)); - if (numbytes < 0) { - debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno)); - /* FIXME */ - close(sockfd); - return (AUTH_ERROR); - } - else if (numbytes == 0) { - done = 1; - } - else { - totalbytes += numbytes; - debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes); - } - } - else if (nfds == 0) { - debug(LOG_ERR, "Timed out reading data via select() from auth server"); - /* FIXME */ - close(sockfd); - return (AUTH_ERROR); - } - else if (nfds < 0) { - debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno)); - /* FIXME */ - close(sockfd); - return (AUTH_ERROR); - } - } while (!done); - - close(sockfd); - - buf[totalbytes] = '\0'; - debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf); - - if ((tmp = strstr(buf, "Auth: "))) { - if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) { - debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode); - return(authresponse->authcode); - } else { - debug(LOG_WARNING, "Auth server did not return expected authentication code"); - return(AUTH_ERROR); - } - } - else { - return(AUTH_ERROR); - } - - /* XXX Never reached because of the above if()/else pair. */ - return(AUTH_ERROR); ->>>>>>> FETCH_HEAD } /* Tries really hard to connect to an auth server. Returns a file descriptor, -1 on error */ -<<<<<<< HEAD int connect_auth_server() { @@ -430,31 +165,12 @@ connect_auth_server() mark_auth_online(); } return (sockfd); -======= -int connect_auth_server() { - int sockfd; - - LOCK_CONFIG(); - sockfd = _connect_auth_server(0); - UNLOCK_CONFIG(); - - if (sockfd == -1) { - debug(LOG_ERR, "Failed to connect to any of the auth servers"); - mark_auth_offline(); - } - else { - debug(LOG_DEBUG, "Connected to auth server"); - mark_auth_online(); - } - return (sockfd); ->>>>>>> FETCH_HEAD } /* Helper function called by connect_auth_server() to do the actual work including recursion * DO NOT CALL DIRECTLY @param level recursion level indicator must be 0 when not called by _connect_auth_server() */ -<<<<<<< HEAD int _connect_auth_server(int level) { @@ -626,162 +342,4 @@ _connect_auth_server(int level) return sockfd; } } -======= -int _connect_auth_server(int level) { - s_config *config = config_get_config(); - t_auth_serv *auth_server = NULL; - struct in_addr *h_addr; - int num_servers = 0; - char * hostname = NULL; - char * popular_servers[] = { - "www.google.com", - "www.yahoo.com", - NULL - }; - char ** popularserver; - char * ip; - struct sockaddr_in their_addr; - int sockfd; - - /* XXX level starts out at 0 and gets incremented by every iterations. */ - level++; - - /* - * Let's calculate the number of servers we have - */ - for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) { - num_servers++; - } - debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers); - - if (level > num_servers) { - /* - * We've called ourselves too many times - * This means we've cycled through all the servers in the server list - * at least once and none are accessible - */ - return (-1); - } - - /* - * Let's resolve the hostname of the top server to an IP address - */ - auth_server = config->auth_servers; - hostname = auth_server->authserv_hostname; - debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname); - h_addr = wd_gethostbyname(hostname); - if (!h_addr) { - /* - * DNS resolving it failed - * - * Can we resolve any of the popular servers ? - */ - debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname); - - for (popularserver = popular_servers; *popularserver; popularserver++) { - debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, *popularserver); - h_addr = wd_gethostbyname(*popularserver); - if (h_addr) { - debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] succeeded = [%s]", level, *popularserver, inet_ntoa(*h_addr)); - break; - } - else { - debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] failed", level, *popularserver); - } - } - - /* - * If we got any h_addr buffer for one of the popular servers, in other - * words, if one of the popular servers resolved, we'll assume the DNS - * works, otherwise we'll deal with net connection or DNS failure. - */ - if (h_addr) { - free (h_addr); - /* - * Yes - * - * The auth server's DNS server is probably dead. Try the next auth server - */ - debug(LOG_DEBUG, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname); - if (auth_server->last_ip) { - free(auth_server->last_ip); - auth_server->last_ip = NULL; - } - mark_auth_server_bad(auth_server); - return _connect_auth_server(level); - } - else { - /* - * No - * - * It's probably safe to assume that the internet connection is malfunctioning - * and nothing we can do will make it work - */ - mark_offline(); - debug(LOG_DEBUG, "Level %d: Failed to resolve auth server and all popular servers. " - "The internet connection is probably down", level); - return(-1); - } - } - else { - /* - * DNS resolving was successful - */ - ip = safe_strdup(inet_ntoa(*h_addr)); - debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip); - - if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) { - /* - * But the IP address is different from the last one we knew - * Update it - */ - debug(LOG_DEBUG, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip); - if (auth_server->last_ip) free(auth_server->last_ip); - auth_server->last_ip = ip; - - /* Update firewall rules */ - fw_clear_authservers(); - fw_set_authservers(); - } - else { - /* - * IP is the same as last time - */ - free(ip); - } - - /* - * Connect to it - */ - debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port); - their_addr.sin_family = AF_INET; - their_addr.sin_port = htons(auth_server->authserv_http_port); - their_addr.sin_addr = *h_addr; - memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero)); - free (h_addr); - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno)); - return(-1); - } - - if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { - /* - * Failed to connect - * Mark the server as bad and try the next one - */ - debug(LOG_DEBUG, "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", level, hostname, auth_server->authserv_http_port, strerror(errno)); - close(sockfd); - mark_auth_server_bad(auth_server); - return _connect_auth_server(level); /* Yay recursion! */ - } - else { - /* - * We have successfully connected - */ - debug(LOG_DEBUG, "Level %d: Successfully connected to auth server %s:%d", level, hostname, auth_server->authserv_http_port); - return sockfd; - } - } ->>>>>>> FETCH_HEAD } diff --git a/src/centralserver.h b/src/centralserver.h index b8eb3fe1..f50dce43 100644 --- a/src/centralserver.h +++ b/src/centralserver.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set sw=4 ts=4 sts=4 et : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -50,7 +47,6 @@ #define GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT "logged-out" /** @brief Initiates a transaction with the auth server */ -<<<<<<< HEAD t_authcode auth_server_request(t_authresponse * authresponse, const char *request_type, const char *ip, @@ -59,24 +55,8 @@ t_authcode auth_server_request(t_authresponse * authresponse, /** @brief Tries really hard to connect to an auth server. Returns a connected file descriptor or -1 on error */ int connect_auth_server(void); -======= -t_authcode auth_server_request(t_authresponse *authresponse, - const char *request_type, - const char *ip, - const char *mac, - const char *token, - unsigned long long int incoming, - unsigned long long int outgoing); - -/** @brief Tries really hard to connect to an auth server. Returns a connected file descriptor or -1 on error */ -int connect_auth_server(); ->>>>>>> FETCH_HEAD /** @brief Helper function called by connect_auth_server() to do the actual work including recursion - DO NOT CALL DIRECTLY */ int _connect_auth_server(int level); -<<<<<<< HEAD #endif /* _CENTRALSERVER_H_ */ -======= -#endif /* _CENTRALSERVER_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/client_list.c b/src/client_list.c index 751cafd3..df7bd610 100644 --- a/src/client_list.c +++ b/src/client_list.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,12 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* - * $Id$ - */ ->>>>>>> FETCH_HEAD /** @file client_list.c @brief Client List Functions @author Copyright (C) 2004 Alexandre Carmel-Veillex @@ -40,16 +31,9 @@ #include #include #include -<<<<<<< HEAD #include #include #include -======= -#include -#include -//#include -#include ->>>>>>> FETCH_HEAD #include @@ -58,7 +42,6 @@ #include "conf.h" #include "client_list.h" -<<<<<<< HEAD /** @internal * Holds a pointer to the first element of the list */ @@ -87,15 +70,6 @@ client_get_new(void) client = safe_malloc(sizeof(t_client)); return client; } -======= -/** Global mutex to protect access to the client list */ -pthread_mutex_t client_list_mutex = PTHREAD_MUTEX_INITIALIZER; - -/** @internal - * Holds a pointer to the first element of the list - */ -t_client *firstclient = NULL; ->>>>>>> FETCH_HEAD /** Get the first element of the list of connected clients */ @@ -114,7 +88,6 @@ client_list_init(void) firstclient = NULL; } -<<<<<<< HEAD /** Insert client at head of list. Lock should be held when calling this! * @param Pointer to t_client object. */ @@ -134,44 +107,21 @@ client_list_insert_client(t_client * client) /** Based on the parameters it receives, this function creates a new entry * in the connections list. All the memory allocation is done here. * Client is inserted at the head of the list. -======= -/** Based on the parameters it receives, this function creates a new entry - * in the connections list. All the memory allocation is done here. ->>>>>>> FETCH_HEAD * @param ip IP address * @param mac MAC address * @param token Token * @return Pointer to the client we just created */ -<<<<<<< HEAD t_client * client_list_add(const char *ip, const char *mac, const char *token) { t_client *curclient; curclient = client_get_new(); -======= -t_client * -client_list_append(const char *ip, const char *mac, const char *token) -{ - t_client *curclient, *prevclient; - - prevclient = NULL; - curclient = firstclient; - - while (curclient != NULL) { - prevclient = curclient; - curclient = curclient->next; - } - - curclient = safe_malloc(sizeof(t_client)); - memset(curclient, 0, sizeof(t_client)); ->>>>>>> FETCH_HEAD curclient->ip = safe_strdup(ip); curclient->mac = safe_strdup(mac); curclient->token = safe_strdup(token); -<<<<<<< HEAD curclient->counters.incoming_delta = curclient->counters.outgoing_delta = curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; @@ -268,28 +218,6 @@ client_list_find_by_client(t_client * client) c = c->next; } return NULL; -======= - curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; - curclient->counters.last_updated = time(NULL); - - /*@breif:record the element create time - * GaomingPan - * */ - curclient->record_time = time(NULL); - //printf("New client: mac-->%s\nip-->%s\nrecord_time-->%ld\n\n",mac,ip,curclient->record_time); - - - if (prevclient == NULL) { - firstclient = curclient; - } else { - prevclient->next = curclient; - } - - debug(LOG_INFO, "Added a new client to linked list: IP: %s Token: %s", - ip, token); - - return curclient; ->>>>>>> FETCH_HEAD } /** Finds a client by its IP and MAC, returns NULL if the client could not @@ -298,17 +226,10 @@ client_list_find_by_client(t_client * client) * @param mac MAC we are looking for in the linked list * @return Pointer to the client, or NULL if not found */ -<<<<<<< HEAD t_client * client_list_find(const char *ip, const char *mac) { t_client *ptr; -======= -t_client * -client_list_find(const char *ip, const char *mac) -{ - t_client *ptr; ->>>>>>> FETCH_HEAD ptr = firstclient; while (NULL != ptr) { @@ -326,17 +247,10 @@ client_list_find(const char *ip, const char *mac) * @param ip IP we are looking for in the linked list * @return Pointer to the client, or NULL if not found */ -<<<<<<< HEAD t_client * client_list_find_by_ip(const char *ip) { t_client *ptr; -======= -t_client * -client_list_find_by_ip(const char *ip) -{ - t_client *ptr; ->>>>>>> FETCH_HEAD ptr = firstclient; while (NULL != ptr) { @@ -354,17 +268,10 @@ client_list_find_by_ip(const char *ip) * @param mac Mac we are looking for in the linked list * @return Pointer to the client, or NULL if not found */ -<<<<<<< HEAD t_client * client_list_find_by_mac(const char *mac) { t_client *ptr; -======= -t_client * -client_list_find_by_mac(const char *mac) -{ - t_client *ptr; ->>>>>>> FETCH_HEAD ptr = firstclient; while (NULL != ptr) { @@ -383,11 +290,7 @@ client_list_find_by_mac(const char *mac) t_client * client_list_find_by_token(const char *token) { -<<<<<<< HEAD t_client *ptr; -======= - t_client *ptr; ->>>>>>> FETCH_HEAD ptr = firstclient; while (NULL != ptr) { @@ -399,7 +302,6 @@ client_list_find_by_token(const char *token) return NULL; } -<<<<<<< HEAD /** Destroy the client list. Including all free... * DOES NOT UPDATE firstclient or anything else. * @param list List to destroy (first item) @@ -416,8 +318,6 @@ client_list_destroy(t_client * list) } } -======= ->>>>>>> FETCH_HEAD /** @internal * @brief Frees the memory used by a t_client structure * This function frees the memory used by the t_client structure in the @@ -425,11 +325,7 @@ client_list_destroy(t_client * list) * @param client Points to the client to be freed */ void -<<<<<<< HEAD client_free_node(t_client * client) -======= -_client_list_free_node(t_client * client) ->>>>>>> FETCH_HEAD { if (client->mac != NULL) @@ -454,7 +350,6 @@ _client_list_free_node(t_client * client) void client_list_delete(t_client * client) { -<<<<<<< HEAD client_list_remove(client); client_free_node(client); } @@ -468,9 +363,6 @@ void client_list_remove(t_client * client) { t_client *ptr; -======= - t_client *ptr; ->>>>>>> FETCH_HEAD ptr = firstclient; @@ -478,10 +370,6 @@ client_list_remove(t_client * client) debug(LOG_ERR, "Node list empty!"); } else if (ptr == client) { firstclient = ptr->next; -<<<<<<< HEAD -======= - _client_list_free_node(client); ->>>>>>> FETCH_HEAD } else { /* Loop forward until we reach our point in the list. */ while (ptr->next != NULL && ptr->next != client) { @@ -490,15 +378,8 @@ client_list_remove(t_client * client) /* If we reach the end before finding out element, complain. */ if (ptr->next == NULL) { debug(LOG_ERR, "Node to delete could not be found."); -<<<<<<< HEAD - } else { - ptr->next = client->next; -======= - /* Free element. */ } else { ptr->next = client->next; - _client_list_free_node(client); ->>>>>>> FETCH_HEAD } } } diff --git a/src/client_list.h b/src/client_list.h index 59a4a203..ebc1c192 100644 --- a/src/client_list.h +++ b/src/client_list.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -31,7 +28,6 @@ #ifndef _CLIENT_LIST_H_ #define _CLIENT_LIST_H_ -<<<<<<< HEAD /** Global mutex to protect access to the client list */ extern pthread_mutex_t client_list_mutex; @@ -46,21 +42,10 @@ typedef struct _t_counters { unsigned long long incoming_delta; /**< @brief Incoming data after last report*/ unsigned long long outgoing_delta; /**< @brief Outgoing data after last report*/ time_t last_updated; /**< @brief Last update of the counters */ -======= -/** Counters struct for a client's bandwidth usage (in bytes) - */ -typedef struct _t_counters { - unsigned long long incoming; /**< @brief Incoming data total*/ - unsigned long long outgoing; /**< @brief Outgoing data total*/ - unsigned long long incoming_history; /**< @brief Incoming data before wifidog restarted*/ - unsigned long long outgoing_history; /**< @brief Outgoing data before wifidog restarted*/ - time_t last_updated; /**< @brief Last update of the counters */ ->>>>>>> FETCH_HEAD } t_counters; /** Client node for the connected client linked list. */ -<<<<<<< HEAD typedef struct _t_client { struct _t_client *next; /**< @brief Pointer to the next client */ unsigned long long id; /**< @brief Unique ID per client */ @@ -80,36 +65,11 @@ typedef struct _t_client { t_client *client_get_new(void); /** @brief Get the first element of the list of connected clients */ -======= -typedef struct _t_client { - struct _t_client *next; /**< @brief Pointer to the next client */ - char *ip; /**< @brief Client Ip address */ - char *mac; /**< @brief Client Mac address */ - char *token; /**< @brief Client token */ - unsigned int fw_connection_state; /**< @brief Connection state in the - firewall */ - int fd; /**< @brief Client HTTP socket (valid only - during login before one of the - _http_* function is called */ - t_counters counters; /**< @brief Counters for input/output of - the client. */ - - /*@breif:record the element create time - * GaomingPan - * */ - time_t record_time; - -} t_client; - -/** @brief Get the first element of the list of connected clients - */ ->>>>>>> FETCH_HEAD t_client *client_get_first_client(void); /** @brief Initializes the client list */ void client_list_init(void); -<<<<<<< HEAD /** @brief Insert client at head of list */ void client_list_insert_client(t_client *); @@ -149,26 +109,6 @@ void client_list_remove(t_client *); /** @brief Free memory associated with a client */ void client_free_node(t_client *); -======= -/** @brief Adds a new client to the connections list */ -t_client *client_list_append(const char *ip, const char *mac, const char *token); - -/** @brief Finds a client by its IP and MAC */ -t_client *client_list_find(const char *ip, const char *mac); - -/** @brief Finds a client only by its IP */ -t_client *client_list_find_by_ip(const char *ip); /* needed by fw_iptables.c, auth.c - * and wdctl_thread.c */ - -/** @brief Finds a client only by its Mac */ -t_client *client_list_find_by_mac(const char *mac); /* needed by wdctl_thread.c */ - -/** @brief Finds a client by its token */ -t_client *client_list_find_by_token(const char *token); - -/** @brief Deletes a client from the connections list */ -void client_list_delete(t_client *client); ->>>>>>> FETCH_HEAD #define LOCK_CLIENT_LIST() do { \ debug(LOG_DEBUG, "Locking client list"); \ @@ -182,8 +122,4 @@ void client_list_delete(t_client *client); debug(LOG_DEBUG, "Client list unlocked"); \ } while (0) -<<<<<<< HEAD #endif /* _CLIENT_LIST_H_ */ -======= -#endif /* _CLIENT_LIST_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/commandline.c b/src/commandline.c index b4411c07..fdcfe501 100644 --- a/src/commandline.c +++ b/src/commandline.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,10 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* $Id$ */ ->>>>>>> FETCH_HEAD /** @file commandline.c @brief Command line argument handling @author Copyright (C) 2004 Philippe April @@ -40,10 +33,7 @@ #include "debug.h" #include "safe.h" #include "conf.h" -<<<<<<< HEAD #include "commandline.h" -======= ->>>>>>> FETCH_HEAD #include "../config.h" @@ -52,23 +42,14 @@ */ char ** restartargv = NULL; -<<<<<<< HEAD /** -======= -static void usage(void); - -/* ->>>>>>> FETCH_HEAD * A flag to denote whether we were restarted via a parent wifidog, or started normally * 0 means normally, otherwise it will be populated by the PID of the parent */ pid_t restart_orig_pid = 0; -<<<<<<< HEAD static void usage(void); -======= ->>>>>>> FETCH_HEAD /** @internal * @brief Print usage * @@ -77,7 +58,6 @@ static void usage(void); static void usage(void) { -<<<<<<< HEAD fprintf(stdout, "Usage: wifidog [options]\n"); fprintf(stdout, "\n"); fprintf(stdout, "options:\n"); @@ -94,26 +74,11 @@ usage(void) fprintf(stdout, " -a Path to /proc/net/arp replacement - mainly useful for debugging.\n"); fprintf(stdout, " -p Save pid to file\n"); fprintf(stdout, "\n"); -======= - printf("Usage: wifidog [options]\n"); - printf("\n"); - printf(" -c [filename] Use this config file\n"); - printf(" -f Run in foreground\n"); - printf(" -d Debug level\n"); - printf(" -s Log to syslog\n"); - printf(" -w Wdctl socket path\n"); - printf(" -h Print usage\n"); - printf(" -v Print version information\n"); - printf(" -x pid Used internally by WiFiDog when re-starting itself *DO NOT ISSUE THIS SWITCH MANUAlLY*\n"); - printf(" -i Internal socket path used when re-starting self\n"); - printf("\n"); ->>>>>>> FETCH_HEAD } /** Uses getopt() to parse the command line and set configuration values * also populates restartargv */ -<<<<<<< HEAD void parse_commandline(int argc, char **argv) { @@ -237,109 +202,3 @@ parse_commandline(int argc, char **argv) restartargv[i++] = NULL; restartargv[i++] = NULL; } -======= -void parse_commandline(int argc, char **argv) { - int c; - int skiponrestart; - int i; - - s_config *config = config_get_config(); - - //MAGIC 3: Our own -x, the pid, and NULL : - restartargv = safe_malloc((argc + 3) * sizeof(char*)); - i=0; - restartargv[i++] = safe_strdup(argv[0]); - - while (-1 != (c = getopt(argc, argv, "c:hfd:sw:vx:i:"))) { - - skiponrestart = 0; - - switch(c) { - - case 'h': - usage(); - exit(1); - break; - - case 'c': - if (optarg) { - strncpy(config->configfile, optarg, sizeof(config->configfile)); - } - break; - - case 'w': - if (optarg) { - free(config->wdctl_sock); - config->wdctl_sock = safe_strdup(optarg); - } - break; - - case 'f': - skiponrestart = 1; - config->daemon = 0; - break; - - case 'd': - if (optarg) { - config->debuglevel = atoi(optarg); - } - break; - - case 's': - config->log_syslog = 1; - break; - - case 'v': - printf("This is WiFiDog version " VERSION "\n"); - exit(1); - break; - - case 'x': - skiponrestart = 1; - if (optarg) { - restart_orig_pid = atoi(optarg); - } - else { - printf("The expected PID to the -x switch was not supplied!"); - exit(1); - } - break; - - case 'i': - if (optarg) { - free(config->internal_sock); - config->internal_sock = safe_strdup(optarg); - } - break; - - default: - usage(); - exit(1); - break; - - } - - if (!skiponrestart) { - /* Add it to restartargv */ - safe_asprintf(&(restartargv[i++]), "-%c", c); - if (optarg) { - restartargv[i++] = safe_strdup(optarg); - } - } - - } - - /* Finally, we should add the -x, pid and NULL to restartargv - * HOWEVER we cannot do it here, since this is called before we fork to background - * so we'll leave this job to gateway.c after forking is completed - * so that the correct PID is assigned - * - * We add 3 nulls, and the first 2 will be overridden later - */ - restartargv[i++] = NULL; - restartargv[i++] = NULL; - restartargv[i++] = NULL; - -} - ->>>>>>> FETCH_HEAD diff --git a/src/commandline.h b/src/commandline.h index ba1958e3..b8bef7c7 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -31,7 +28,6 @@ #ifndef _COMMANDLINE_H_ #define _COMMANDLINE_H_ -<<<<<<< HEAD /* * Holds an argv that could be passed to exec*() if we restart ourselves */ @@ -47,9 +43,3 @@ extern pid_t restart_orig_pid; void parse_commandline(int, char **); #endif /* _COMMANDLINE_H_ */ -======= -/** @brief Parses the command line and set the config accordingly */ -void parse_commandline(int, char**); - -#endif /* _COMMANDLINE_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/conf.c b/src/conf.c index 51c73d97..89998cd1 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -47,17 +44,10 @@ #include "http.h" #include "auth.h" #include "firewall.h" -<<<<<<< HEAD #include "config.h" #include "util.h" -======= - -#include "util.h" - - ->>>>>>> FETCH_HEAD /** @internal * Holds the current configuration of the gateway */ static s_config config; @@ -75,7 +65,6 @@ static int missing_parms; /** @internal The different configuration options */ typedef enum { -<<<<<<< HEAD oBadOption, oDaemon, oDebugLevel, @@ -115,50 +104,11 @@ typedef enum { oSSLCertPath, oSSLAllowedCipherList, oSSLUseSNI, -======= - oBadOption, - oDaemon, - oDebugLevel, - oExternalInterface, - oGatewayID, - oGatewayInterface, - oGatewayAddress, - oGatewayPort, - oAuthServer, - oAuthServHostname, - oAuthServSSLAvailable, - oAuthServSSLPort, - oAuthServHTTPPort, - oAuthServPath, - oAuthServLoginScriptPathFragment, - oAuthServPortalScriptPathFragment, - oAuthServMsgScriptPathFragment, - oAuthServPingScriptPathFragment, - oAuthServAuthScriptPathFragment, - oHTTPDMaxConn, - oHTTPDName, - oHTTPDRealm, - oHTTPDUsername, - oHTTPDPassword, - oClientTimeout, - oCheckInterval, - oWdctlSocket, - oSyslogFacility, - oFirewallRule, - oFirewallRuleSet, - oTrustedMACList, - oUntrustedMACList, /*gaomingpan*/ - oHtmlMessageFile, - oProxyPort, - oWhiteList, /*limeng*/ - oBlackList, ->>>>>>> FETCH_HEAD } OpCodes; /** @internal The config file keywords for the different configuration options */ static const struct { -<<<<<<< HEAD const char *name; OpCodes opcode; } keywords[] = { @@ -214,56 +164,6 @@ static void validate_popular_servers(void); static void add_popular_server(const char *); static OpCodes config_parse_token(const char *, const char *, int); -======= - const char *name; - OpCodes opcode; -} keywords[] = { - { "daemon", oDaemon }, - { "debuglevel", oDebugLevel }, - { "externalinterface", oExternalInterface }, - { "gatewayid", oGatewayID }, - { "gatewayinterface", oGatewayInterface }, - { "gatewayaddress", oGatewayAddress }, - { "gatewayport", oGatewayPort }, - { "authserver", oAuthServer }, - { "httpdmaxconn", oHTTPDMaxConn }, - { "httpdname", oHTTPDName }, - { "httpdrealm", oHTTPDRealm }, - { "httpdusername", oHTTPDUsername }, - { "httpdpassword", oHTTPDPassword }, - { "clienttimeout", oClientTimeout }, - { "checkinterval", oCheckInterval }, - { "syslogfacility", oSyslogFacility }, - { "wdctlsocket", oWdctlSocket }, - { "hostname", oAuthServHostname }, - { "sslavailable", oAuthServSSLAvailable }, - { "sslport", oAuthServSSLPort }, - { "httpport", oAuthServHTTPPort }, - { "path", oAuthServPath }, - { "loginscriptpathfragment", oAuthServLoginScriptPathFragment }, - { "portalscriptpathfragment", oAuthServPortalScriptPathFragment }, - { "msgscriptpathfragment", oAuthServMsgScriptPathFragment }, - { "pingscriptpathfragment", oAuthServPingScriptPathFragment }, - { "authscriptpathfragment", oAuthServAuthScriptPathFragment }, - { "firewallruleset", oFirewallRuleSet }, - { "firewallrule", oFirewallRule }, - { "trustedmaclist", oTrustedMACList }, - { "untrustedMACList", oUntrustedMACList}, /*gaomingpan*/ - { "htmlmessagefile", oHtmlMessageFile }, - { "proxyport", oProxyPort }, - { "whitelist", oWhiteList}, /*limeng*/ - { "blacklist", oBlackList}, - { NULL, oBadOption }, -}; - -static void config_notnull(const void *parm, const char *parmname); -static int parse_boolean_value(char *); -static void parse_auth_server(FILE *, const char *, int *); -static int _parse_firewall_rule(const char *ruleset, char *leftover); -static void parse_firewall_ruleset(const char *, FILE *, const char *, int *); - -static OpCodes config_parse_token(const char *cp, const char *filename, int linenum); ->>>>>>> FETCH_HEAD /** Accessor for the current gateway configuration @return: A pointer to the current config. The pointer isn't opaque, but should be treated as READ-ONLY @@ -278,7 +178,6 @@ config_get_config(void) void config_init(void) { -<<<<<<< HEAD debug(LOG_DEBUG, "Setting default config parameters"); config.configfile = safe_strdup(DEFAULT_CONFIGFILE); config.htmlmsgfile = safe_strdup(DEFAULT_HTMLMSGFILE); @@ -314,37 +213,6 @@ config_init(void) debugconf.debuglevel = DEFAULT_DEBUGLEVEL; debugconf.syslog_facility = DEFAULT_SYSLOG_FACILITY; debugconf.log_syslog = DEFAULT_LOG_SYSLOG; -======= - debug(LOG_DEBUG, "Setting default config parameters"); - strncpy(config.configfile, DEFAULT_CONFIGFILE, sizeof(config.configfile)); - config.htmlmsgfile = safe_strdup(DEFAULT_HTMLMSGFILE); - config.debuglevel = DEFAULT_DEBUGLEVEL; - config.httpdmaxconn = DEFAULT_HTTPDMAXCONN; - config.external_interface = NULL; - config.gw_id = DEFAULT_GATEWAYID; - config.gw_interface = NULL; - config.gw_address = NULL; - config.gw_port = DEFAULT_GATEWAYPORT; - config.auth_servers = NULL; - config.httpdname = NULL; - config.httpdrealm = DEFAULT_HTTPDNAME; - config.httpdusername = NULL; - config.httpdpassword = NULL; - config.clienttimeout = DEFAULT_CLIENTTIMEOUT; - config.checkinterval = DEFAULT_CHECKINTERVAL; - config.syslog_facility = DEFAULT_SYSLOG_FACILITY; - config.daemon = -1; - config.log_syslog = DEFAULT_LOG_SYSLOG; - config.wdctl_sock = safe_strdup(DEFAULT_WDCTL_SOCK); - config.internal_sock = safe_strdup(DEFAULT_INTERNAL_SOCK); - config.rulesets = NULL; - config.trustedmaclist = NULL; - config.untrustedmaclist = NULL; /*gaomingpan*/ - config.proxy_port = 0; - config.white_list = NULL; /*limeng*/ - config.black_list = NULL; - ->>>>>>> FETCH_HEAD } /** @@ -353,16 +221,12 @@ config_init(void) void config_init_override(void) { -<<<<<<< HEAD if (config.daemon == -1) { config.daemon = DEFAULT_DAEMON; if (config.daemon > 0) { debugconf.log_stderr = 0; } } -======= - if (config.daemon == -1) config.daemon = DEFAULT_DAEMON; ->>>>>>> FETCH_HEAD } /** @internal @@ -371,7 +235,6 @@ Parses a single token from the config file static OpCodes config_parse_token(const char *cp, const char *filename, int linenum) { -<<<<<<< HEAD int i; for (i = 0; keywords[i].name; i++) @@ -380,24 +243,12 @@ config_parse_token(const char *cp, const char *filename, int linenum) debug(LOG_ERR, "%s: line %d: Bad configuration option: %s", filename, linenum, cp); return oBadOption; -======= - int i; - - for (i = 0; keywords[i].name; i++) - if (strcasecmp(cp, keywords[i].name) == 0) - return keywords[i].opcode; - - debug(LOG_ERR, "%s: line %d: Bad configuration option: %s", - filename, linenum, cp); - return oBadOption; ->>>>>>> FETCH_HEAD } /** @internal Parses auth server information */ static void -<<<<<<< HEAD parse_auth_server(FILE * file, const char *filename, int *linenum) { char *host = NULL, @@ -551,157 +402,6 @@ parse_auth_server(FILE * file, const char *filename, int *linenum) } debug(LOG_DEBUG, "Auth server added"); -======= -parse_auth_server(FILE *file, const char *filename, int *linenum) -{ - char *host = NULL, - *path = NULL, - *loginscriptpathfragment = NULL, - *portalscriptpathfragment = NULL, - *msgscriptpathfragment = NULL, - *pingscriptpathfragment = NULL, - *authscriptpathfragment = NULL, - line[MAX_BUF], - *p1, - *p2; - int http_port, - ssl_port, - ssl_available, - opcode; - t_auth_serv *new, - *tmp; - - /* Defaults */ - path = safe_strdup(DEFAULT_AUTHSERVPATH); - loginscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVLOGINPATHFRAGMENT); - portalscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVPORTALPATHFRAGMENT); - msgscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVMSGPATHFRAGMENT); - pingscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVPINGPATHFRAGMENT); - authscriptpathfragment = safe_strdup(DEFAULT_AUTHSERVAUTHPATHFRAGMENT); - http_port = DEFAULT_AUTHSERVPORT; - ssl_port = DEFAULT_AUTHSERVSSLPORT; - ssl_available = DEFAULT_AUTHSERVSSLAVAILABLE; - - - /* Parsing loop */ - while (memset(line, 0, MAX_BUF) && fgets(line, MAX_BUF - 1, file) && (strchr(line, '}') == NULL)) { - (*linenum)++; /* increment line counter. */ - - /* skip leading blank spaces */ - for (p1 = line; isblank(*p1); p1++); - - /* End at end of line */ - if ((p2 = strchr(p1, '#')) != NULL) { - *p2 = '\0'; - } else if ((p2 = strchr(p1, '\r')) != NULL) { - *p2 = '\0'; - } else if ((p2 = strchr(p1, '\n')) != NULL) { - *p2 = '\0'; - } - - /* next, we coopt the parsing of the regular config */ - if (strlen(p1) > 0) { - p2 = p1; - /* keep going until word boundary is found. */ - while ((*p2 != '\0') && (!isblank(*p2))) - p2++; - - /* Terminate first word. */ - *p2 = '\0'; - p2++; - - /* skip all further blanks. */ - while (isblank(*p2)) - p2++; - - /* Get opcode */ - opcode = config_parse_token(p1, filename, *linenum); - - switch (opcode) { - case oAuthServHostname: - host = safe_strdup(p2); - break; - case oAuthServPath: - free(path); - path = safe_strdup(p2); - break; - case oAuthServLoginScriptPathFragment: - free(loginscriptpathfragment); - loginscriptpathfragment = safe_strdup(p2); - break; - case oAuthServPortalScriptPathFragment: - free(portalscriptpathfragment); - portalscriptpathfragment = safe_strdup(p2); - break; - case oAuthServMsgScriptPathFragment: - free(msgscriptpathfragment); - msgscriptpathfragment = safe_strdup(p2); - break; - case oAuthServPingScriptPathFragment: - free(pingscriptpathfragment); - pingscriptpathfragment = safe_strdup(p2); - break; - case oAuthServAuthScriptPathFragment: - free(authscriptpathfragment); - authscriptpathfragment = safe_strdup(p2); - break; - case oAuthServSSLPort: - ssl_port = atoi(p2); - break; - case oAuthServHTTPPort: - http_port = atoi(p2); - break; - case oAuthServSSLAvailable: - ssl_available = parse_boolean_value(p2); - if (ssl_available < 0) - ssl_available = 0; - break; - case oBadOption: - default: - debug(LOG_ERR, "Bad option on line %d " - "in %s.", *linenum, - filename); - debug(LOG_ERR, "Exiting..."); - exit(-1); - break; - } - } - } - - /* only proceed if we have an host and a path */ - if (host == NULL) - return; - - debug(LOG_DEBUG, "Adding %s:%d (SSL: %d) %s to the auth server list", - host, http_port, ssl_port, path); - - /* Allocate memory */ - new = safe_malloc(sizeof(t_auth_serv)); - - /* Fill in struct */ - memset(new, 0, sizeof(t_auth_serv)); /*< Fill all with NULL */ - new->authserv_hostname = host; - new->authserv_use_ssl = ssl_available; - new->authserv_path = path; - new->authserv_login_script_path_fragment = loginscriptpathfragment; - new->authserv_portal_script_path_fragment = portalscriptpathfragment; - new->authserv_msg_script_path_fragment = msgscriptpathfragment; - new->authserv_ping_script_path_fragment = pingscriptpathfragment; - new->authserv_auth_script_path_fragment = authscriptpathfragment; - new->authserv_http_port = http_port; - new->authserv_ssl_port = ssl_port; - - /* If it's the first, add to config, else append to last server */ - if (config.auth_servers == NULL) { - config.auth_servers = new; - } else { - for (tmp = config.auth_servers; tmp->next != NULL; - tmp = tmp->next); - tmp->next = new; - } - - debug(LOG_DEBUG, "Auth server added"); ->>>>>>> FETCH_HEAD } /** @@ -731,7 +431,6 @@ Advance to the next word Parses firewall rule set information */ static void -<<<<<<< HEAD parse_firewall_ruleset(const char *ruleset, FILE * file, const char *filename, int *linenum) { char line[MAX_BUF], *p1, *p2; @@ -791,71 +490,6 @@ parse_firewall_ruleset(const char *ruleset, FILE * file, const char *filename, i } debug(LOG_DEBUG, "Firewall Rule Set %s added.", ruleset); -======= -parse_firewall_ruleset(const char *ruleset, FILE *file, const char *filename, int *linenum) -{ - char line[MAX_BUF], - *p1, - *p2; - int opcode; - - debug(LOG_DEBUG, "Adding Firewall Rule Set %s", ruleset); - - /* Parsing loop */ - while (memset(line, 0, MAX_BUF) && fgets(line, MAX_BUF - 1, file) && (strchr(line, '}') == NULL)) { - (*linenum)++; /* increment line counter. */ - - /* skip leading blank spaces */ - for (p1 = line; isblank(*p1); p1++); - - /* End at end of line */ - if ((p2 = strchr(p1, '#')) != NULL) { - *p2 = '\0'; - } else if ((p2 = strchr(p1, '\r')) != NULL) { - *p2 = '\0'; - } else if ((p2 = strchr(p1, '\n')) != NULL) { - *p2 = '\0'; - } - - /* next, we coopt the parsing of the regular config */ - if (strlen(p1) > 0) { - p2 = p1; - /* keep going until word boundary is found. */ - while ((*p2 != '\0') && (!isblank(*p2))) - p2++; - - /* Terminate first word. */ - *p2 = '\0'; - p2++; - - /* skip all further blanks. */ - while (isblank(*p2)) - p2++; - - /* Get opcode */ - opcode = config_parse_token(p1, filename, *linenum); - - debug(LOG_DEBUG, "p1 = [%s]; p2 = [%s]", p1, p2); - - switch (opcode) { - case oFirewallRule: - _parse_firewall_rule(ruleset, p2); - break; - - case oBadOption: - default: - debug(LOG_ERR, "Bad option on line %d " - "in %s.", *linenum, - filename); - debug(LOG_ERR, "Exiting..."); - exit(-1); - break; - } - } - } - - debug(LOG_DEBUG, "Firewall Rule Set %s added.", ruleset); ->>>>>>> FETCH_HEAD } /** @internal @@ -864,7 +498,6 @@ Helper for parse_firewall_ruleset. Parses a single rule in a ruleset static int _parse_firewall_rule(const char *ruleset, char *leftover) { -<<<<<<< HEAD int i; t_firewall_target target = TARGET_REJECT; /**< firewall target */ int all_nums = 1; /**< If 0, port contained non-numerics */ @@ -989,151 +622,11 @@ _parse_firewall_rule(const char *ruleset, char *leftover) } return 1; -======= - int i; - t_firewall_target target = TARGET_REJECT; /**< firewall target */ - int all_nums = 1; /**< If 0, port contained non-numerics */ - int finished = 0; /**< reached end of line */ - char *token = NULL; /**< First word */ - char *port = NULL; /**< port to open/block */ - char *protocol = NULL; /**< protocol to block, tcp/udp/icmp */ - char *mask = NULL; /**< Netmask */ - char *other_kw = NULL; /**< other key word */ - t_firewall_ruleset *tmpr; - t_firewall_ruleset *tmpr2; - t_firewall_rule *tmp; - t_firewall_rule *tmp2; - - debug(LOG_DEBUG, "leftover: %s", leftover); - - /* lower case */ - for (i = 0; *(leftover + i) != '\0' - && (*(leftover + i) = tolower((unsigned char)*(leftover + i))); i++); - - token = leftover; - TO_NEXT_WORD(leftover, finished); - - /* Parse token */ - if (!strcasecmp(token, "block") || finished) { - target = TARGET_REJECT; - } else if (!strcasecmp(token, "drop")) { - target = TARGET_DROP; - } else if (!strcasecmp(token, "allow")) { - target = TARGET_ACCEPT; - } else if (!strcasecmp(token, "log")) { - target = TARGET_LOG; - } else if (!strcasecmp(token, "ulog")) { - target = TARGET_ULOG; - } else { - debug(LOG_ERR, "Invalid rule type %s, expecting " - "\"block\",\"drop\",\"allow\",\"log\" or \"ulog\"", token); - return -1; - } - - /* Parse the remainder */ - /* Get the protocol */ - if (strncmp(leftover, "tcp", 3) == 0 - || strncmp(leftover, "udp", 3) == 0 - || strncmp(leftover, "icmp", 4) == 0) { - protocol = leftover; - TO_NEXT_WORD(leftover, finished); - } - - /* should be exactly "port" */ - if (strncmp(leftover, "port", 4) == 0) { - TO_NEXT_WORD(leftover, finished); - /* Get port now */ - port = leftover; - TO_NEXT_WORD(leftover, finished); - for (i = 0; *(port + i) != '\0'; i++) - if (!isdigit((unsigned char)*(port + i))) - all_nums = 0; /*< No longer only digits */ - if (!all_nums) { - debug(LOG_ERR, "Invalid port %s", port); - return -3; /*< Fail */ - } - } - - /* Now, further stuff is optional */ - if (!finished) { - /* should be exactly "to" */ - other_kw = leftover; - TO_NEXT_WORD(leftover, finished); - if (strcmp(other_kw, "to") || finished) { - debug(LOG_ERR, "Invalid or unexpected keyword %s, " - "expecting \"to\"", other_kw); - return -4; /*< Fail */ - } - - /* Get port now */ - mask = leftover; - TO_NEXT_WORD(leftover, finished); - all_nums = 1; - for (i = 0; *(mask + i) != '\0'; i++) - if (!isdigit((unsigned char)*(mask + i)) && (*(mask + i) != '.') - && (*(mask + i) != '/')) - all_nums = 0; /*< No longer only digits */ - if (!all_nums) { - debug(LOG_ERR, "Invalid mask %s", mask); - return -3; /*< Fail */ - } - } - - /* Generate rule record */ - tmp = safe_malloc(sizeof(t_firewall_rule)); - memset((void *)tmp, 0, sizeof(t_firewall_rule)); - tmp->target = target; - if (protocol != NULL) - tmp->protocol = safe_strdup(protocol); - if (port != NULL) - tmp->port = safe_strdup(port); - if (mask == NULL) - tmp->mask = safe_strdup("0.0.0.0/0"); - else - tmp->mask = safe_strdup(mask); - - debug(LOG_DEBUG, "Adding Firewall Rule %s %s port %s to %s", token, tmp->protocol, tmp->port, tmp->mask); - - /* Append the rule record */ - if (config.rulesets == NULL) { - config.rulesets = safe_malloc(sizeof(t_firewall_ruleset)); - memset(config.rulesets, 0, sizeof(t_firewall_ruleset)); - config.rulesets->name = safe_strdup(ruleset); - tmpr = config.rulesets; - } else { - tmpr2 = tmpr = config.rulesets; - while (tmpr != NULL && (strcmp(tmpr->name, ruleset) != 0)) { - tmpr2 = tmpr; - tmpr = tmpr->next; - } - if (tmpr == NULL) { - /* Rule did not exist */ - tmpr = safe_malloc(sizeof(t_firewall_ruleset)); - memset(tmpr, 0, sizeof(t_firewall_ruleset)); - tmpr->name = safe_strdup(ruleset); - tmpr2->next = tmpr; - } - } - - /* At this point, tmpr == current ruleset */ - if (tmpr->rules == NULL) { - /* No rules... */ - tmpr->rules = tmp; - } else { - tmp2 = tmpr->rules; - while (tmp2->next != NULL) - tmp2 = tmp2->next; - tmp2->next = tmp; - } - - return 1; ->>>>>>> FETCH_HEAD } t_firewall_rule * get_ruleset(const char *ruleset) { -<<<<<<< HEAD t_firewall_ruleset *tmp; for (tmp = config.rulesets; tmp != NULL && strcmp(tmp->name, ruleset) != 0; tmp = tmp->next) ; @@ -1142,17 +635,6 @@ get_ruleset(const char *ruleset) return NULL; return (tmp->rules); -======= - t_firewall_ruleset *tmp; - - for (tmp = config.rulesets; tmp != NULL - && strcmp(tmp->name, ruleset) != 0; tmp = tmp->next); - - if (tmp == NULL) - return NULL; - - return(tmp->rules); ->>>>>>> FETCH_HEAD } /** @@ -1161,7 +643,6 @@ get_ruleset(const char *ruleset) void config_read(const char *filename) { -<<<<<<< HEAD FILE *fd; char line[MAX_BUF], *s, *p1, *p2, *rawarg = NULL; int linenum = 0, opcode, value; @@ -1351,159 +832,6 @@ config_read(const char *filename) } fclose(fd); -======= - FILE *fd; - char line[MAX_BUF], *s, *p1, *p2; - int linenum = 0, opcode, value, len; - - debug(LOG_INFO, "Reading configuration file '%s'", filename); - - if (!(fd = fopen(filename, "r"))) { - debug(LOG_ERR, "Could not open configuration file '%s', " - "exiting...", filename); - exit(1); - } - - while (!feof(fd) && fgets(line, MAX_BUF, fd)) { - linenum++; - s = line; - - if (s[strlen(s) - 1] == '\n') - s[strlen(s) - 1] = '\0'; - - if ((p1 = strchr(s, ' '))) { - p1[0] = '\0'; - } else if ((p1 = strchr(s, '\t'))) { - p1[0] = '\0'; - } - - if (p1) { - p1++; - - // Trim leading spaces - len = strlen(p1); - while (*p1 && len) { - if (*p1 == ' ') - p1++; - else - break; - len = strlen(p1); - } - - - if ((p2 = strchr(p1, ' '))) { - p2[0] = '\0'; - } else if ((p2 = strstr(p1, "\r\n"))) { - p2[0] = '\0'; - } else if ((p2 = strchr(p1, '\n'))) { - p2[0] = '\0'; - } - } - - if (p1 && p1[0] != '\0') { - /* Strip trailing spaces */ - - if ((strncmp(s, "#", 1)) != 0) { - debug(LOG_DEBUG, "Parsing token: %s, " - "value: %s", s, p1); - opcode = config_parse_token(s, filename, linenum); - - switch(opcode) { - case oDaemon: - if (config.daemon == -1 && ((value = parse_boolean_value(p1)) != -1)) { - config.daemon = value; - } - break; - case oExternalInterface: - config.external_interface = safe_strdup(p1); - break; - case oGatewayID: - config.gw_id = safe_strdup(p1); - break; - case oGatewayInterface: - config.gw_interface = safe_strdup(p1); - break; - case oGatewayAddress: - config.gw_address = safe_strdup(p1); - break; - case oGatewayPort: - sscanf(p1, "%d", &config.gw_port); - break; - case oAuthServer: - parse_auth_server(fd, filename, - &linenum); - break; - case oFirewallRuleSet: - parse_firewall_ruleset(p1, fd, filename, &linenum); - break; - case oTrustedMACList: - parse_trusted_mac_list(p1); - break; - /*gaomingpan*/ - case oUntrustedMACList: - parse_untrusted_mac_list(p1); - break; - case oHTTPDName: - config.httpdname = safe_strdup(p1); - break; - case oHTTPDMaxConn: - sscanf(p1, "%d", &config.httpdmaxconn); - break; - case oHTTPDRealm: - config.httpdrealm = safe_strdup(p1); - break; - case oHTTPDUsername: - config.httpdusername = safe_strdup(p1); - break; - case oHTTPDPassword: - config.httpdpassword = safe_strdup(p1); - break; - case oBadOption: - debug(LOG_ERR, "Bad option on line %d " - "in %s.", linenum, - filename); - debug(LOG_ERR, "Exiting..."); - exit(-1); - break; - case oCheckInterval: - sscanf(p1, "%d", &config.checkinterval); - break; - case oWdctlSocket: - free(config.wdctl_sock); - config.wdctl_sock = safe_strdup(p1); - break; - case oClientTimeout: - sscanf(p1, "%d", &config.clienttimeout); - break; - case oSyslogFacility: - sscanf(p1, "%d", &config.syslog_facility); - break; - case oHtmlMessageFile: - config.htmlmsgfile = safe_strdup(p1); - break; - case oProxyPort: - sscanf(p1, "%d", &config.proxy_port); - break; - /*limeng*/ - case oWhiteList: - parse_white_list(p1); - break; - case oBlackList: - parse_black_list(p1); - break; - - } - } - } - } - - if (config.httpdusername && !config.httpdpassword) { - debug(LOG_ERR, "HTTPDUserName requires a HTTPDPassword to be set."); - exit(-1); - } - - fclose(fd); ->>>>>>> FETCH_HEAD } /** @internal @@ -1512,7 +840,6 @@ Parses a boolean value from the config file static int parse_boolean_value(char *line) { -<<<<<<< HEAD if (strcasecmp(line, "yes") == 0) { return 1; } @@ -1673,203 +1000,10 @@ parse_popular_servers(const char *ptr) free(ptrcopy); } -======= - if (strcasecmp(line, "yes") == 0) { - return 1; - } - if (strcasecmp(line, "no") == 0) { - return 0; - } - if (strcmp(line, "1") == 0) { - return 1; - } - if (strcmp(line, "0") == 0) { - return 0; - } - - return -1; -} - -void parse_trusted_mac_list(const char *ptr) { - char *ptrcopy = NULL; - char *possiblemac = NULL; - char *mac = NULL; - t_trusted_mac *p = NULL; - - debug(LOG_DEBUG, "Parsing string [%s] for trusted MAC addresses", ptr); - - mac = safe_malloc(18); - - /* strsep modifies original, so let's make a copy */ - ptrcopy = safe_strdup(ptr); - - while ((possiblemac = strsep(&ptrcopy, ", "))) { - if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { - /* Copy mac to the list */ - - debug(LOG_DEBUG, "Adding MAC address [%s] to trusted list", mac); - - if (config.trustedmaclist == NULL) { - config.trustedmaclist = safe_malloc(sizeof(t_trusted_mac)); - config.trustedmaclist->mac = safe_strdup(mac); - config.trustedmaclist->next = NULL; - } - else { - /* Advance to the last entry */ - for (p = config.trustedmaclist; p->next != NULL; p = p->next); - p->next = safe_malloc(sizeof(t_trusted_mac)); - p = p->next; - p->mac = safe_strdup(mac); - p->next = NULL; - } - - } - } - - free(ptrcopy); - - free(mac); - -} - -/*gaomingpan*/ -void parse_untrusted_mac_list(const char *ptr) -{ - char *ptrcopy = NULL; - char *possiblemac = NULL; - char *mac = NULL; - t_untrusted_mac *p = NULL; - - debug(LOG_DEBUG, "Parsing string [%s] for untrusted MAC addresses", ptr); - - mac = safe_malloc(18); - - /* strsep modifies original, so let's make a copy */ - ptrcopy = safe_strdup(ptr); - - while ((possiblemac = strsep(&ptrcopy, ", "))) { - if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { - /* Copy mac to the list */ - - debug(LOG_DEBUG, "Adding MAC address [%s] to untrusted list", mac); - - if (config.untrustedmaclist == NULL) { - config.untrustedmaclist = safe_malloc(sizeof(t_trusted_mac)); - config.untrustedmaclist->mac = safe_strdup(mac); - config.untrustedmaclist->next = NULL; - } - else { - /* Advance to the last entry */ - for (p = config.untrustedmaclist; p->next != NULL; p = p->next); - p->next = safe_malloc(sizeof(t_untrusted_mac)); - p = p->next; - p->mac = safe_strdup(mac); - p->next = NULL; - } - - } - } - - free(ptrcopy); - - free(mac); -} - - - -/*limeng*/ -void parse_white_list(const char *ptr) { - char *ptrcopy = NULL; - char *possiblewhitelist = NULL; - char *ip = NULL; - t_white_list *p = NULL; - - debug(LOG_DEBUG, "Parsing string [%s] for white list addresses", ptr); - - ip = safe_malloc(512); - - /* strsep modifies original, so let's make a copy */ - ptrcopy = safe_strdup(ptr); - - while ((possiblewhitelist = strsep(&ptrcopy, ", "))) { - if (sscanf(possiblewhitelist, " %s[A-Za-z0-9.]", ip) == 1) { - /* Copy white list to the list */ - - debug(LOG_DEBUG, "Adding ip address [%s] to white list", ip); - - if (config.white_list == NULL) { - config.white_list = safe_malloc(sizeof(t_white_list)); - config.white_list->ip = safe_strdup(ip); - config.white_list->next = NULL; - } - else { - /* Advance to the last entry */ - for (p = config.white_list; p->next != NULL; p = p->next); - p->next = safe_malloc(sizeof(t_white_list)); - p = p->next; - p->ip = safe_strdup(ip); - p->next = NULL; - } - - } - } - - free(ptrcopy); - - free(ip); - -} - -void parse_black_list(const char *ptr) { - char *ptrcopy = NULL; - char *possibleblacklist = NULL; - char *ip = NULL; - t_black_list *p = NULL; - - debug(LOG_DEBUG, "Parsing string [%s] for black list addresses", ptr); - - ip = safe_malloc(512); - - /* strsep modifies original, so let's make a copy */ - ptrcopy = safe_strdup(ptr); - - while ((possibleblacklist = strsep(&ptrcopy, ", "))) { - if (sscanf(possibleblacklist, " %s[A-Za-z0-9.]", ip) == 1) { - /* Copy black list to the list */ - - debug(LOG_DEBUG, "Adding ip address [%s] to black list", ip); - - if (config.black_list == NULL) { - config.black_list = safe_malloc(sizeof(t_black_list)); - config.black_list->ip = safe_strdup(ip); - config.black_list->next = NULL; - } - else { - /* Advance to the last entry */ - for (p = config.black_list; p->next != NULL; p = p->next); - p->next = safe_malloc(sizeof(t_black_list)); - p = p->next; - p->ip = safe_strdup(ip); - p->next = NULL; - } - - } - } - - free(ptrcopy); - - free(ip); - -} - - - ->>>>>>> FETCH_HEAD /** Verifies if the configuration is complete and valid. Terminates the program if it isn't */ void config_validate(void) { -<<<<<<< HEAD config_notnull(config.gw_interface, "GatewayInterface"); config_notnull(config.auth_servers, "AuthServer"); validate_popular_servers(); @@ -1891,15 +1025,6 @@ validate_popular_servers(void) add_popular_server("www.google.com"); add_popular_server("www.yahoo.com"); } -======= - config_notnull(config.gw_interface, "GatewayInterface"); - config_notnull(config.auth_servers, "AuthServer"); - - if (missing_parms) { - debug(LOG_ERR, "Configuration is not complete, exiting..."); - exit(-1); - } ->>>>>>> FETCH_HEAD } /** @internal @@ -1908,17 +1033,10 @@ validate_popular_servers(void) static void config_notnull(const void *parm, const char *parmname) { -<<<<<<< HEAD if (parm == NULL) { debug(LOG_ERR, "%s is not set", parmname); missing_parms = 1; } -======= - if (parm == NULL) { - debug(LOG_ERR, "%s is not set", parmname); - missing_parms = 1; - } ->>>>>>> FETCH_HEAD } /** @@ -1928,13 +1046,8 @@ t_auth_serv * get_auth_server(void) { -<<<<<<< HEAD /* This is as good as atomic */ return config.auth_servers; -======= - /* This is as good as atomic */ - return config.auth_servers; ->>>>>>> FETCH_HEAD } /** @@ -1942,7 +1055,6 @@ get_auth_server(void) * as bad. Basically, the "bad" server becomes the last one on the list. */ void -<<<<<<< HEAD mark_auth_server_bad(t_auth_serv * bad_server) { t_auth_serv *tmp; @@ -1957,21 +1069,5 @@ mark_auth_server_bad(t_auth_serv * bad_server) /* Set the next pointe to NULL in the last element */ bad_server->next = NULL; } -======= -mark_auth_server_bad(t_auth_serv *bad_server) -{ - t_auth_serv *tmp; - - if (config.auth_servers == bad_server && bad_server->next != NULL) { - /* Go to the last */ - for (tmp = config.auth_servers; tmp->next != NULL; tmp = tmp->next); - /* Set bad server as last */ - tmp->next = bad_server; - /* Remove bad server from start of list */ - config.auth_servers = bad_server->next; - /* Set the next pointe to NULL in the last element */ - bad_server->next = NULL; - } ->>>>>>> FETCH_HEAD } diff --git a/src/conf.h b/src/conf.h index 442aa29d..f9ce3404 100644 --- a/src/conf.h +++ b/src/conf.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -31,7 +28,6 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -<<<<<<< HEAD /*@{*/ /** Defines */ @@ -43,25 +39,6 @@ #define DEFAULT_CONFIGFILE SYSCONFDIR"/wifidog.conf" #define DEFAULT_HTMLMSGFILE SYSCONFDIR"/wifidog-msg.html" #endif -======= -/*@{*/ -/** Defines */ -/** How many times should we try detecting the interface with the default route - * (in seconds). If set to 0, it will keep retrying forever */ -#define NUM_EXT_INTERFACE_DETECT_RETRY 0 -/** How often should we try to detect the interface with the default route - * if it isn't up yet (interval in seconds) */ -#define EXT_INTERFACE_DETECT_RETRY_INTERVAL 1 - -/** Defaults configuration values */ -#ifndef SYSCONFDIR - #define DEFAULT_CONFIGFILE "/etc/wifidog.conf" - #define DEFAULT_HTMLMSGFILE "/etc/wifidog-msg.html" -#else - #define DEFAULT_CONFIGFILE SYSCONFDIR"/wifidog.conf" - #define DEFAULT_HTMLMSGFILE SYSCONFDIR"/wifidog-msg.html" -#endif ->>>>>>> FETCH_HEAD #define DEFAULT_DAEMON 1 #define DEFAULT_DEBUGLEVEL LOG_INFO #define DEFAULT_HTTPDMAXCONN 10 @@ -69,14 +46,8 @@ #define DEFAULT_GATEWAYPORT 2060 #define DEFAULT_HTTPDNAME "WiFiDog" #define DEFAULT_CLIENTTIMEOUT 5 -<<<<<<< HEAD #define DEFAULT_CHECKINTERVAL 60 #define DEFAULT_LOG_SYSLOG 0 -======= -//#define DEFAULT_CHECKINTERVAL 60 -#define DEFAULT_CHECKINTERVAL 30 -#define DEFAULT_LOG_SYSLOG 1 ->>>>>>> FETCH_HEAD #define DEFAULT_SYSLOG_FACILITY LOG_DAEMON #define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" #define DEFAULT_INTERNAL_SOCK "/tmp/wifidog.sock" @@ -91,7 +62,6 @@ #define DEFAULT_AUTHSERVMSGPATHFRAGMENT "gw_message.php?" #define DEFAULT_AUTHSERVPINGPATHFRAGMENT "ping/?" #define DEFAULT_AUTHSERVAUTHPATHFRAGMENT "auth/?" -<<<<<<< HEAD #define DEFAULT_AUTHSERVSSLCERTPATH "/etc/ssl/certs/" /** Note that DEFAULT_AUTHSERVSSLNOPEERVER must be 0 or 1, even if the config file syntax is yes or no */ #define DEFAULT_AUTHSERVSSLPEERVER 1 /* 0 means: Enable peer verification */ @@ -114,15 +84,11 @@ * Mutex for the configuration file, used by the auth_servers related * functions. */ extern pthread_mutex_t config_mutex; -======= -/*@}*/ ->>>>>>> FETCH_HEAD /** * Information about the authentication server */ typedef struct _auth_serv_t { -<<<<<<< HEAD char *authserv_hostname; /**< @brief Hostname of the central server */ char *authserv_path; /**< @brief Path where wifidog resides */ char *authserv_login_script_path_fragment; /**< @brief This is the script the user will be sent to for login. */ @@ -136,21 +102,6 @@ typedef struct _auth_serv_t { listens on */ int authserv_use_ssl; /**< @brief Use SSL or not */ char *last_ip; /**< @brief Last ip used by authserver */ -======= - char *authserv_hostname; /**< @brief Hostname of the central server */ - char *authserv_path; /**< @brief Path where wifidog resides */ - char *authserv_login_script_path_fragment; /**< @brief This is the script the user will be sent to for login. */ - char *authserv_portal_script_path_fragment; /**< @brief This is the script the user will be sent to after a successfull login. */ - char *authserv_msg_script_path_fragment; /**< @brief This is the script the user will be sent to upon error to read a readable message. */ - char *authserv_ping_script_path_fragment; /**< @brief This is the ping heartbeating script. */ - char *authserv_auth_script_path_fragment; /**< @brief This is the script that talks the wifidog gateway protocol. */ - int authserv_http_port; /**< @brief Http port the central server - listens on */ - int authserv_ssl_port; /**< @brief Https port the central server - listens on */ - int authserv_use_ssl; /**< @brief Use SSL or not */ - char *last_ip; /**< @brief Last ip used by authserver */ ->>>>>>> FETCH_HEAD struct _auth_serv_t *next; } t_auth_serv; @@ -169,18 +120,11 @@ typedef enum { * Firewall rules */ typedef struct _firewall_rule_t { -<<<<<<< HEAD t_firewall_target target; /**< @brief t_firewall_target */ char *protocol; /**< @brief tcp, udp, etc ... */ char *port; /**< @brief Port to block/allow */ char *mask; /**< @brief Mask for the rule *destination* */ int mask_is_ipset; /**< @brief *destination* is ipset */ -======= - t_firewall_target target; /**< @brief t_firewall_target */ - char *protocol; /**< @brief tcp, udp, etc ... */ - char *port; /**< @brief Port to block/allow */ - char *mask; /**< @brief Mask for the rule *destination* */ ->>>>>>> FETCH_HEAD struct _firewall_rule_t *next; } t_firewall_rule; @@ -188,67 +132,31 @@ typedef struct _firewall_rule_t { * Firewall rulesets */ typedef struct _firewall_ruleset_t { -<<<<<<< HEAD char *name; t_firewall_rule *rules; struct _firewall_ruleset_t *next; -======= - char *name; - t_firewall_rule *rules; - struct _firewall_ruleset_t *next; ->>>>>>> FETCH_HEAD } t_firewall_ruleset; /** * Trusted MAC Addresses */ typedef struct _trusted_mac_t { -<<<<<<< HEAD char *mac; -======= - char *mac; ->>>>>>> FETCH_HEAD struct _trusted_mac_t *next; } t_trusted_mac; /** -<<<<<<< HEAD * Popular Servers */ typedef struct _popular_server_t { char *hostname; struct _popular_server_t *next; } t_popular_server; -======= - * gaomingpan - * untrusted mac addresses - * */ -typedef struct _untrusted_mac_t { - char *mac; - struct _untrusted_mac_t *next; -} t_untrusted_mac; - -/*limeng*/ -/** - * Trusted White list Addresses - */ -typedef struct _white_list_t { - char *ip; - struct _white_list_t *next; -} t_white_list; - -typedef struct _black_list_t { - char *ip; - struct _black_list_t *next; -} t_black_list; - ->>>>>>> FETCH_HEAD /** * Configuration structure */ typedef struct { -<<<<<<< HEAD char *configfile; /**< @brief name of the config file */ char *htmlmsgfile; /**< @brief name of the HTML file used for messages */ char *wdctl_sock; /**< @brief wdctl path to socket */ @@ -290,45 +198,6 @@ typedef struct { char *arp_table_path; /**< @brief Path to custom ARP table, formatted like /proc/net/arp */ t_popular_server *popular_servers; /**< @brief list of popular servers */ -======= - char configfile[255]; /**< @brief name of the config file */ - char *htmlmsgfile; /**< @brief name of the HTML file used for messages */ - char *wdctl_sock; /**< @brief wdctl path to socket */ - char *internal_sock; /**< @brief internal path to socket */ - int daemon; /**< @brief if daemon > 0, use daemon mode */ - int debuglevel; /**< @brief Debug information verbosity */ - char *external_interface; /**< @brief External network interface name for - firewall rules */ - char *gw_id; /**< @brief ID of the Gateway, sent to central - server */ - char *gw_interface; /**< @brief Interface we will accept connections on */ - char *gw_address; /**< @brief Internal IP address for our web - server */ - int gw_port; /**< @brief Port the webserver will run on */ - - t_auth_serv *auth_servers; /**< @brief Auth servers list */ - char *httpdname; /**< @brief Name the web server will return when - replying to a request */ - int httpdmaxconn; /**< @brief Used by libhttpd, not sure what it - does */ - char *httpdrealm; /**< @brief HTTP Authentication realm */ - char *httpdusername; /**< @brief Username for HTTP authentication */ - char *httpdpassword; /**< @brief Password for HTTP authentication */ - int clienttimeout; /**< @brief How many CheckIntervals before a client - must be re-authenticated */ - int checkinterval; /**< @brief Frequency the the client timeout check - thread will run. */ - int log_syslog; /**< @brief boolean, wether to log to syslog */ - int syslog_facility; /**< @brief facility to use when using syslog for - logging */ - int proxy_port; /**< @brief Transparent proxy port (0 to disable) */ - /*limeng*/ - t_white_list *white_list; /**< @brief White list */ - t_black_list *black_list; /**< @brief black list */ - t_firewall_ruleset *rulesets; /**< @brief firewall rules */ - t_trusted_mac *trustedmaclist; /**< @brief list of trusted macs */ - t_untrusted_mac *untrustedmaclist; /**< @brief list of untrusted macs*/ ->>>>>>> FETCH_HEAD } s_config; /** @brief Get the current gateway configuration */ @@ -355,17 +224,6 @@ void mark_auth_server_bad(t_auth_serv *); /** @brief Fetch a firewall rule set. */ t_firewall_rule *get_ruleset(const char *); -<<<<<<< HEAD -======= -void parse_trusted_mac_list(const char *); - -/*gaomingpan*/ -void parse_untrusted_mac_list(const char *); - -/* limeng */ -void parse_white_list(const char *); -void parse_black_list(const char *) ; ->>>>>>> FETCH_HEAD #define LOCK_CONFIG() do { \ debug(LOG_DEBUG, "Locking config"); \ @@ -379,8 +237,4 @@ void parse_black_list(const char *) ; debug(LOG_DEBUG, "Config unlocked"); \ } while (0) -<<<<<<< HEAD #endif /* _CONFIG_H_ */ -======= -#endif /* _CONFIG_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/debug.c b/src/debug.c index 11340999..83c87cd9 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,10 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* $Id$ */ ->>>>>>> FETCH_HEAD /** @file debug.c @brief Debug output routines @author Copyright (C) 2004 Philippe April @@ -37,7 +30,6 @@ #include #include #include -<<<<<<< HEAD #include #include "debug.h" @@ -48,10 +40,6 @@ debugconf_t debugconf = { .log_syslog = 0, .syslog_facility = 0 }; -======= - -#include "conf.h" ->>>>>>> FETCH_HEAD /** @internal Do not use directly, use the debug macro */ @@ -60,7 +48,6 @@ _debug(const char *filename, int line, int level, const char *format, ...) { char buf[28]; va_list vlist; -<<<<<<< HEAD time_t ts; sigset_t block_chld; @@ -74,23 +61,10 @@ _debug(const char *filename, int line, int level, const char *format, ...) if (level <= LOG_WARNING) { fprintf(stderr, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), filename, line); -======= - s_config *config = config_get_config(); - time_t ts; - - time(&ts); - - if (config->debuglevel >= level) { - - if (level <= LOG_WARNING) { - fprintf(stderr, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), - filename, line); ->>>>>>> FETCH_HEAD va_start(vlist, format); vfprintf(stderr, format, vlist); va_end(vlist); fputc('\n', stderr); -<<<<<<< HEAD } else if (debugconf.log_stderr) { fprintf(stderr, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), filename, line); @@ -102,32 +76,12 @@ _debug(const char *filename, int line, int level, const char *format, ...) if (debugconf.log_syslog) { openlog("wifidog", LOG_PID, debugconf.syslog_facility); -======= - } else if (!config->daemon) { - fprintf(stdout, "[%d][%.24s][%u](%s:%d) ", level, ctime_r(&ts, buf), getpid(), - filename, line); - va_start(vlist, format); - vfprintf(stdout, format, vlist); - va_end(vlist); - fputc('\n', stdout); - fflush(stdout); - } - - if (config->log_syslog) { - openlog("wifidog", LOG_PID, config->syslog_facility); ->>>>>>> FETCH_HEAD va_start(vlist, format); vsyslog(level, format, vlist); va_end(vlist); closelog(); } -<<<<<<< HEAD sigprocmask(SIG_UNBLOCK, &block_chld, NULL); } } -======= - } -} - ->>>>>>> FETCH_HEAD diff --git a/src/debug.h b/src/debug.h index 5197a23a..ad40ce51 100644 --- a/src/debug.h +++ b/src/debug.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,10 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* $Id$ */ ->>>>>>> FETCH_HEAD /** @file debug.h @brief Debug output routines @author Copyright (C) 2004 Philippe April @@ -34,7 +27,6 @@ #ifndef _DEBUG_H_ #define _DEBUG_H_ -<<<<<<< HEAD typedef struct _debug_conf { int debuglevel; /**< @brief Debug information verbosity */ int log_stderr; /**< @brief Output log to stdout */ @@ -48,18 +40,10 @@ extern debugconf_t debugconf; * The messages will include the filename and line number, and will be sent to syslog if so configured in the config file * @param level Debug level * @param format... sprintf like format string -======= -/** @brief Used to output messages. - *The messages will include the finlname and line number, and will be sent to syslog if so configured in the config file ->>>>>>> FETCH_HEAD */ #define debug(level, format...) _debug(__FILE__, __LINE__, level, format) /** @internal */ -<<<<<<< HEAD void _debug(const char *, int, int, const char *, ...); -======= -void _debug(const char *filename, int line, int level, const char *format, ...); ->>>>>>> FETCH_HEAD #endif /* _DEBUG_H_ */ diff --git a/src/device_key.c b/src/device_key.c deleted file mode 100755 index 040b7e7f..00000000 --- a/src/device_key.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * device_key.c - * - * Created on: Aug 14, 2015 - * Author: GaomingPan - */ - -#include -#include -#include - -#include "device_key.h" - -/** - * the global device key char array. - * */ -static char device_key[64] = {0}; - - -/* @breif get the global device key.the key will be use as auth key - * @PARAMETER: void - * @RETURN_VALUE: a none NULL char pointer - * GaomingPan lonely-test:yes - * */ -char * get_device_key() -{ - return device_key; -} - - - - -/* @breif get the device key from a configure file - * @PARAMETER: void - * @RETURN_VALUE: success return zero and set the KEY in the device key global array, - * failed return a none zero number. - * GaomingPan lonely-test:yes - * */ -int init_device_key() -{ - FILE *fp; - char *line = NULL; - size_t len = 0; - ssize_t read_len; - - fp = fopen(DEVICE_KEY_FILE,"r"); - if(NULL == fp) - { - return -1; - } - while((read_len = getline(&line,&len,fp)) != -1) - { - if('#' == line[0] || ' ' == line[0] || '\t' == line[0]) - continue; - else - { - sprintf(device_key,"%s",line); - free(line); - fclose(fp); - return 0; - } - } - free(line); - fclose(fp); - return -2; -} diff --git a/src/device_key.h b/src/device_key.h deleted file mode 100755 index 08b11b47..00000000 --- a/src/device_key.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * device_key.h - * - * Created on: Aug 14, 2015 - * Author: GaomingPan - */ - -#ifndef SRC_DEVICE_KEY_H_ -#define SRC_DEVICE_KEY_H_ - - -#define DEVICE_KEY_FILE "/etc/.devicekey" - -/* @breif get the global device key.the key will be use as auth key - * @PARAMETER: void - * @RETURN_VALUE: a none NULL char pointer - * GaomingPan lonely-test:yes - * */ -char * get_device_key(); - - - -/* @breif get the device key from a configure file - * @PARAMETER: void - * @RETURN_VALUE: success return zero and set the KEY in the device key global array, - * failed return a none zero number. - * GaomingPan lonely-test:yes - * */ -int init_device_key(); - -#endif /* SRC_DEVICE_KEY_H_ */ diff --git a/src/firewall.c b/src/firewall.c index e3a62147..211af351 100644 --- a/src/firewall.c +++ b/src/firewall.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,12 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* - * $Id$ - */ ->>>>>>> FETCH_HEAD /** @internal @file firewall.c @brief Firewall update functions @@ -44,11 +35,6 @@ #include #include #include -<<<<<<< HEAD -======= -//#include -#include ->>>>>>> FETCH_HEAD #include @@ -57,34 +43,12 @@ #include #include #include -<<<<<<< HEAD #include #include #include "httpd.h" #include "safe.h" #include "util.h" -======= -#include -#include -#include - -#ifdef __linux__ -#include -#include -#include -#include -#endif - -#if defined(__NetBSD__) -#include -#include -#include -#endif - -#include "httpd.h" -#include "safe.h" ->>>>>>> FETCH_HEAD #include "debug.h" #include "conf.h" #include "firewall.h" @@ -92,7 +56,6 @@ #include "auth.h" #include "centralserver.h" #include "client_list.h" -<<<<<<< HEAD #include "commandline.h" static int _fw_deny_raw(const char *, const char *, const int); @@ -137,33 +100,6 @@ fw_allow_host(const char *host) debug(LOG_DEBUG, "Allowing %s", host); return iptables_fw_access_host(FW_ACCESS_ALLOW, host); -======= - -#include "get_clientinfo.h" - - -extern pthread_mutex_t client_list_mutex; - -/* from commandline.c */ -extern pid_t restart_orig_pid; - - - -/** - * Allow a client access through the firewall by adding a rule in the firewall to MARK the user's packets with the proper - * rule by providing his IP and MAC address - * @param ip IP address to allow - * @param mac MAC address to allow - * @param fw_connection_state fw_connection_state Tag - * @return Return code of the command - */ -int -fw_allow(const char *ip, const char *mac, int fw_connection_state) -{ - debug(LOG_DEBUG, "Allowing %s %s with fw_connection_state %d", ip, mac, fw_connection_state); - - return iptables_fw_access(FW_ACCESS_ALLOW, ip, mac, fw_connection_state); ->>>>>>> FETCH_HEAD } /** @@ -174,7 +110,6 @@ fw_allow(const char *ip, const char *mac, int fw_connection_state) * @return Return code of the command */ int -<<<<<<< HEAD fw_deny(t_client * client) { int fw_connection_state = client->fw_connection_state; @@ -213,19 +148,11 @@ fw_set_authup(void) debug(LOG_DEBUG, "Marking auth server up again"); return iptables_fw_auth_reachable(); -======= -fw_deny(const char *ip, const char *mac, int fw_connection_state) -{ - debug(LOG_DEBUG, "Denying %s %s with fw_connection_state %d", ip, mac, fw_connection_state); - - return iptables_fw_access(FW_ACCESS_DENY, ip, mac, fw_connection_state); ->>>>>>> FETCH_HEAD } /* XXX DCY */ /** * Get an IP's MAC address from the ARP cache. -<<<<<<< HEAD * Go through all the entries in config->arp_table_path until we find the * requested IP address and return the MAC address bound to it. * @todo Make this function portable (using shell scripts?) @@ -240,26 +167,10 @@ arp_get(const char *req_ip) s_config *config = config_get_config(); if (!(proc = fopen(config->arp_table_path, "r"))) { -======= - * Go through all the entries in /proc/net/arp until we find the requested - * IP address and return the MAC address bound to it. - * @todo Make this function portable (using shell scripts?) - */ -char * -arp_get(const char *req_ip) -{ - FILE *proc; - char ip[16]; - char mac[18]; - char * reply = NULL; - - if (!(proc = fopen("/proc/net/arp", "r"))) { ->>>>>>> FETCH_HEAD return NULL; } /* Skip first line */ -<<<<<<< HEAD while (!feof(proc) && fgetc(proc) != '\n') ; /* Find ip, copy mac in reply */ @@ -269,17 +180,6 @@ arp_get(const char *req_ip) reply = safe_strdup(mac); break; } -======= - while (!feof(proc) && fgetc(proc) != '\n'); - - /* Find ip, copy mac in reply */ - reply = NULL; - while (!feof(proc) && (fscanf(proc, " %15[0-9.] %*s %*s %17[A-Fa-f0-9:] %*s %*s", ip, mac) == 2)) { - if (strcmp(ip, req_ip) == 0) { - reply = safe_strdup(mac); - break; - } ->>>>>>> FETCH_HEAD } fclose(proc); @@ -292,32 +192,17 @@ arp_get(const char *req_ip) int fw_init(void) { -<<<<<<< HEAD int result = 0; int new_fw_state; t_client *client = NULL; if (!init_icmp_socket()) { -======= - int flags, oneopt = 1, zeroopt = 0; - int result = 0; - t_client * client = NULL; - - debug(LOG_INFO, "Creating ICMP socket"); - if ((icmp_fd = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1 || - (flags = fcntl(icmp_fd, F_GETFL, 0)) == -1 || - fcntl(icmp_fd, F_SETFL, flags | O_NONBLOCK) == -1 || - setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) || - setsockopt(icmp_fd, SOL_SOCKET, SO_DONTROUTE, &zeroopt, sizeof(zeroopt)) == -1) { - debug(LOG_ERR, "Cannot create ICMP raw socket."); ->>>>>>> FETCH_HEAD return 0; } debug(LOG_INFO, "Initializing Firewall"); result = iptables_fw_init(); -<<<<<<< HEAD if (restart_orig_pid) { debug(LOG_INFO, "Restoring firewall rules for clients inherited from parent"); LOCK_CLIENT_LIST(); @@ -332,20 +217,6 @@ fw_init(void) } return result; -======= - if (restart_orig_pid) { - debug(LOG_INFO, "Restoring firewall rules for clients inherited from parent"); - LOCK_CLIENT_LIST(); - client = client_get_first_client(); - while (client) { - fw_allow(client->ip, client->mac, client->fw_connection_state); - client = client->next; - } - UNLOCK_CLIENT_LIST(); - } - - return result; ->>>>>>> FETCH_HEAD } /** Remove all auth server firewall whitelist rules @@ -353,13 +224,8 @@ fw_init(void) void fw_clear_authservers(void) { -<<<<<<< HEAD debug(LOG_INFO, "Clearing the authservers list"); iptables_fw_clear_authservers(); -======= - debug(LOG_INFO, "Clearing the authservers list"); - iptables_fw_clear_authservers(); ->>>>>>> FETCH_HEAD } /** Add the necessary firewall rules to whitelist the authservers @@ -367,13 +233,8 @@ fw_clear_authservers(void) void fw_set_authservers(void) { -<<<<<<< HEAD debug(LOG_INFO, "Setting the authservers list"); iptables_fw_set_authservers(); -======= - debug(LOG_INFO, "Setting the authservers list"); - iptables_fw_set_authservers(); ->>>>>>> FETCH_HEAD } /** Remove the firewall rules @@ -383,15 +244,7 @@ fw_set_authservers(void) int fw_destroy(void) { -<<<<<<< HEAD close_icmp_socket(); -======= - if (icmp_fd != 0) { - debug(LOG_INFO, "Closing ICMP socket"); - close(icmp_fd); - } - ->>>>>>> FETCH_HEAD debug(LOG_INFO, "Removing Firewall rules"); return iptables_fw_destroy(); } @@ -402,22 +255,14 @@ fw_destroy(void) void fw_sync_with_authserver(void) { -<<<<<<< HEAD t_authresponse authresponse; t_client *p1, *p2, *worklist, *tmp; -======= - t_authresponse authresponse; - char *token, *ip, *mac; - t_client *p1, *p2; - unsigned long long incoming, outgoing; ->>>>>>> FETCH_HEAD s_config *config = config_get_config(); if (-1 == iptables_fw_counters_update()) { debug(LOG_ERR, "Could not get counters from firewall!"); return; } -<<<<<<< HEAD LOCK_CLIENT_LIST(); @@ -432,26 +277,10 @@ fw_sync_with_authserver(void) for (p1 = p2 = worklist; NULL != p1; p1 = p2) { p2 = p1->next; -======= - set_client_auth_flag(); - LOCK_CLIENT_LIST(); - - for (p1 = p2 = client_get_first_client(); NULL != p1; p1 = p2) { - p2 = p1->next; - - ip = safe_strdup(p1->ip); - token = safe_strdup(p1->token); - mac = safe_strdup(p1->mac); - outgoing = p1->counters.outgoing; - incoming = p1->counters.incoming; - - UNLOCK_CLIENT_LIST(); ->>>>>>> FETCH_HEAD /* Ping the client, if he responds it'll keep activity on the link. * However, if the firewall blocks it, it will not help. The suggested * way to deal witht his is to keep the DHCP lease time extremely * short: Shorter than config->checkinterval * config->clienttimeout */ -<<<<<<< HEAD icmp_ping(p1->ip); /* Update the counters on the remote server only if we have an auth server */ if (config->auth_servers != NULL) { @@ -554,174 +383,4 @@ fw_sync_with_authserver(void) } client_list_destroy(worklist); -======= - icmp_ping(ip); - /* Update the counters on the remote server only if we have an auth server */ - if (config->auth_servers != NULL) { - auth_server_request(&authresponse, REQUEST_TYPE_COUNTERS, ip, mac, token, incoming, outgoing); - } - LOCK_CLIENT_LIST(); - - if (!(p1 = client_list_find(ip, mac))) { - debug(LOG_ERR, "Node %s was freed while being re-validated!", ip); - } else { - time_t current_time=time(NULL); - debug(LOG_INFO, "Checking client %s for timeout: Last updated %ld (%ld seconds ago), timeout delay %ld seconds, current time %ld, ", - p1->ip, p1->counters.last_updated, current_time-p1->counters.last_updated, config->checkinterval * config->clienttimeout, current_time); - if (p1->counters.last_updated + - (config->checkinterval * config->clienttimeout) - <= current_time) { - /* Timing out user */ - debug(LOG_INFO, "%s - Inactive for more than %ld seconds, removing client and denying in firewall", - p1->ip, config->checkinterval * config->clienttimeout); - fw_deny(p1->ip, p1->mac, p1->fw_connection_state); - client_list_delete(p1); - - /* Advertise the logout if we have an auth server */ - if (config->auth_servers != NULL) { - UNLOCK_CLIENT_LIST(); - auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token, 0, 0); - LOCK_CLIENT_LIST(); - } - } else { - /* - * This handles any change in - * the status this allows us - * to change the status of a - * user while he's connected - * - * Only run if we have an auth server - * configured! - */ - if (config->auth_servers != NULL) { - switch (authresponse.authcode) { - case AUTH_DENIED: - debug(LOG_NOTICE, "%s - Denied. Removing client and firewall rules", p1->ip); - fw_deny(p1->ip, p1->mac, p1->fw_connection_state); - client_list_delete(p1); - break; - - case AUTH_VALIDATION_FAILED: - debug(LOG_NOTICE, "%s - Validation timeout, now denied. Removing client and firewall rules", p1->ip); - fw_deny(p1->ip, p1->mac, p1->fw_connection_state); - client_list_delete(p1); - break; - - case AUTH_ALLOWED: - if (p1->fw_connection_state != FW_MARK_KNOWN) { - debug(LOG_INFO, "%s - Access has changed to allowed, refreshing firewall and clearing counters", p1->ip); - //WHY did we deny, then allow!?!? benoitg 2007-06-21 - //fw_deny(p1->ip, p1->mac, p1->fw_connection_state); - - if (p1->fw_connection_state != FW_MARK_PROBATION) { - p1->counters.incoming = p1->counters.outgoing = 0; - } - else { - //We don't want to clear counters if the user was in validation, it probably already transmitted data.. - debug(LOG_INFO, "%s - Skipped clearing counters after all, the user was previously in validation", p1->ip); - } - p1->fw_connection_state = FW_MARK_KNOWN; - fw_allow(p1->ip, p1->mac, p1->fw_connection_state); - } - break; - - case AUTH_VALIDATION: - /* - * Do nothing, user - * is in validation - * period - */ - debug(LOG_INFO, "%s - User in validation period", p1->ip); - break; - - case AUTH_ERROR: - debug(LOG_WARNING, "Error communicating with auth server - leaving %s as-is for now", p1->ip); - break; - - default: - debug(LOG_ERR, "I do not know about authentication code %d", authresponse.authcode); - break; - } - } - } - } - - free(token); - free(ip); - free(mac); - } - UNLOCK_CLIENT_LIST(); -} - -void -icmp_ping(const char *host) -{ - struct sockaddr_in saddr; -#if defined(__linux__) || defined(__NetBSD__) - struct { - struct ip ip; - struct icmp icmp; - } packet; -#endif - unsigned int i, j; - int opt = 2000; - unsigned short id = rand16(); - - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_family = AF_INET; - inet_aton(host, &saddr.sin_addr); -#if defined(HAVE_SOCKADDR_SA_LEN) || defined(__NetBSD__) - saddr.sin_len = sizeof(struct sockaddr_in); -#endif - -#if defined(__linux__) || defined(__NetBSD__) - memset(&packet.icmp, 0, sizeof(packet.icmp)); - packet.icmp.icmp_type = ICMP_ECHO; - packet.icmp.icmp_id = id; - - for (j = 0, i = 0; i < sizeof(struct icmp) / 2; i++) - j += ((unsigned short *)&packet.icmp)[i]; - - while (j >> 16) - j = (j & 0xffff) + (j >> 16); - - packet.icmp.icmp_cksum = (j == 0xffff) ? j : ~j; - - if (setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == -1) - debug(LOG_ERR, "setsockopt(): %s", strerror(errno)); - - if (sendto(icmp_fd, (char *)&packet.icmp, sizeof(struct icmp), 0, - (const struct sockaddr *)&saddr, sizeof(saddr)) == -1) - debug(LOG_ERR, "sendto(): %s", strerror(errno)); - - opt = 1; - if (setsockopt(icmp_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) == -1) - debug(LOG_ERR, "setsockopt(): %s", strerror(errno)); -#endif - - return; -} - -unsigned short rand16(void) { - static int been_seeded = 0; - - if (!been_seeded) { - unsigned int seed = 0; - struct timeval now; - - /* not a very good seed but what the heck, it needs to be quickly acquired */ - gettimeofday(&now, NULL); - seed = now.tv_sec ^ now.tv_usec ^ (getpid() << 16); - - srand(seed); - been_seeded = 1; - } - - /* Some rand() implementations have less randomness in low bits - * than in high bits, so we only pay attention to the high ones. - * But most implementations don't touch the high bit, so we - * ignore that one. - **/ - return( (unsigned short) (rand() >> 15) ); ->>>>>>> FETCH_HEAD } diff --git a/src/firewall.h b/src/firewall.h index e474d7d3..fcc2d5de 100644 --- a/src/firewall.h +++ b/src/firewall.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -31,7 +28,6 @@ #ifndef _FIREWALL_H_ #define _FIREWALL_H_ -<<<<<<< HEAD #include "client_list.h" /** Used by fw_iptables.c */ @@ -41,15 +37,6 @@ typedef enum _t_fw_marks { @todo: VERIFY THAT THIS IS ACCURATE*/ FW_MARK_KNOWN = 2, /**< @brief The client is known to the firewall */ FW_MARK_AUTH_IS_DOWN = 253, /**< @brief The auth servers are down */ -======= -int icmp_fd; - -/** Used by fw_iptables.c */ -typedef enum _t_fw_marks { - FW_MARK_PROBATION = 1, /**< @brief The client is in probation period and must be authenticated - @todo: VERIFY THAT THIS IS ACCURATE*/ - FW_MARK_KNOWN = 2, /**< @brief The client is known to the firewall */ ->>>>>>> FETCH_HEAD FW_MARK_LOCKED = 254 /**< @brief The client has been locked out */ } t_fw_marks; @@ -66,7 +53,6 @@ void fw_set_authservers(void); int fw_destroy(void); /** @brief Allow a user through the firewall*/ -<<<<<<< HEAD int fw_allow(t_client *, int); /** @brief Allow a host through the firewall*/ @@ -80,29 +66,11 @@ int fw_set_authdown(void); /** @brief Remove passthrough for clients when auth server is up */ int fw_set_authup(void); -======= -int fw_allow(const char *ip, const char *mac, int profile); - -/** @brief Deny a client access through the firewall*/ -int fw_deny(const char *ip, const char *mac, int profile); ->>>>>>> FETCH_HEAD /** @brief Refreshes the entire client list */ void fw_sync_with_authserver(void); /** @brief Get an IP's MAC address from the ARP cache.*/ -<<<<<<< HEAD char *arp_get(const char *); #endif /* _FIREWALL_H_ */ -======= -char *arp_get(const char *req_ip); - -/** @brief ICMP Ping an IP */ -void icmp_ping(const char *host); - -/** @brief cheap random */ -unsigned short rand16(void); - -#endif /* _FIREWALL_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/fw_iptables.c b/src/fw_iptables.c index daa99327..b3ec1089 100644 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -52,39 +49,12 @@ #include "util.h" #include "client_list.h" -<<<<<<< HEAD -======= -//#include "get_devinfo.h" - -/*limeng*/ -#include - ->>>>>>> FETCH_HEAD static int iptables_do_command(const char *format, ...); static char *iptables_compile(const char *, const char *, const t_firewall_rule *); static void iptables_load_ruleset(const char *, const char *, const char *); -<<<<<<< HEAD /** Used to supress the error output of the firewall during destruction */ -======= -extern pthread_mutex_t client_list_mutex; -extern pthread_mutex_t config_mutex; - -static char dev_extern_iface[64]; - - -/** @brief Get extern interface - * this function use at get_devinfo.c*/ -char *get_dev_extern_iface() -{ - return dev_extern_iface; -} - - -/** -Used to supress the error output of the firewall during destruction */ ->>>>>>> FETCH_HEAD static int fw_quiet = 0; /** @internal @@ -98,7 +68,6 @@ static int fw_quiet = 0; static void iptables_insert_gateway_id(char **input) { -<<<<<<< HEAD char *token; const s_config *config; char *buffer; @@ -115,25 +84,6 @@ iptables_insert_gateway_id(char **input) free(*input); *input = buffer; -======= - char *token; - const s_config *config; - char *buffer; - - if (strstr(*input, "$ID$")==NULL) - return; - - - while ((token=strstr(*input, "$ID$"))!=NULL) - /* This string may look odd but it's standard POSIX and ISO C */ - memcpy(token, "%1$s", 4); - - config = config_get_config(); - safe_asprintf(&buffer, *input, config->gw_interface); - - free(*input); - *input=buffer; ->>>>>>> FETCH_HEAD } /** @internal @@ -141,7 +91,6 @@ iptables_insert_gateway_id(char **input) static int iptables_do_command(const char *format, ...) { -<<<<<<< HEAD va_list vlist; char *fmt_cmd; char *cmd; @@ -171,37 +120,6 @@ iptables_do_command(const char *format, ...) free(cmd); return rc; -======= - va_list vlist; - char *fmt_cmd; - char *cmd; - int rc; - - va_start(vlist, format); - safe_vasprintf(&fmt_cmd, format, vlist); - va_end(vlist); - - safe_asprintf(&cmd, "iptables %s", fmt_cmd); - free(fmt_cmd); - - iptables_insert_gateway_id(&cmd); - - debug(LOG_DEBUG, "Executing command: %s", cmd); - - rc = execute(cmd, fw_quiet); - - if (rc!=0) { - // If quiet, do not display the error - if (fw_quiet == 0) - debug(LOG_ERR, "iptables command failed(%d): %s", rc, cmd); - else if (fw_quiet == 1) - debug(LOG_DEBUG, "iptables command failed(%d): %s", rc, cmd); - } - - free(cmd); - - return rc; ->>>>>>> FETCH_HEAD } /** @@ -212,7 +130,6 @@ iptables_do_command(const char *format, ...) * @arg chain Chain that the command will be (-A)ppended to. * @arg rule Definition of a rule into a struct, from conf.c. */ -<<<<<<< HEAD static char * iptables_compile(const char *table, const char *chain, const t_firewall_rule * rule) { @@ -269,55 +186,6 @@ iptables_compile(const char *table, const char *chain, const t_firewall_rule * r /* XXX The buffer command, an automatic variable, will get cleaned * off of the stack when we return, so we strdup() it. */ return (safe_strdup(command)); -======= - static char * -iptables_compile(const char * table, const char *chain, const t_firewall_rule *rule) -{ - char command[MAX_BUF], - *mode; - - memset(command, 0, MAX_BUF); - - switch (rule->target){ - case TARGET_DROP: - mode = safe_strdup("DROP"); - break; - case TARGET_REJECT: - mode = safe_strdup("REJECT"); - break; - case TARGET_ACCEPT: - mode = safe_strdup("ACCEPT"); - break; - case TARGET_LOG: - mode = safe_strdup("LOG"); - break; - case TARGET_ULOG: - mode = safe_strdup("ULOG"); - break; - } - - snprintf(command, sizeof(command), "-t %s -A %s ",table, chain); - if (rule->mask != NULL) { - snprintf((command + strlen(command)), (sizeof(command) - - strlen(command)), "-d %s ", rule->mask); - } - if (rule->protocol != NULL) { - snprintf((command + strlen(command)), (sizeof(command) - - strlen(command)), "-p %s ", rule->protocol); - } - if (rule->port != NULL) { - snprintf((command + strlen(command)), (sizeof(command) - - strlen(command)), "--dport %s ", rule->port); - } - snprintf((command + strlen(command)), (sizeof(command) - - strlen(command)), "-j %s", mode); - - free(mode); - - /* XXX The buffer command, an automatic variable, will get cleaned - * off of the stack when we return, so we strdup() it. */ - return(safe_strdup(command)); ->>>>>>> FETCH_HEAD } /** @@ -327,7 +195,6 @@ iptables_compile(const char * table, const char *chain, const t_firewall_rule *r * @arg table Table containing the chain. * @arg chain IPTables chain the rules go into */ -<<<<<<< HEAD static void iptables_load_ruleset(const char *table, const char *ruleset, const char *chain) { @@ -370,52 +237,10 @@ iptables_fw_set_authservers(void) } } -======= - static void -iptables_load_ruleset(const char * table, const char *ruleset, const char *chain) -{ - t_firewall_rule *rule; - char *cmd; - - debug(LOG_DEBUG, "Load ruleset %s into table %s, chain %s", ruleset, table, chain); - - for (rule = get_ruleset(ruleset); rule != NULL; rule = rule->next) { - cmd = iptables_compile(table, chain, rule); - debug(LOG_DEBUG, "Loading rule \"%s\" into table %s, chain %s", cmd, table, chain); - iptables_do_command(cmd); - free(cmd); - } - - debug(LOG_DEBUG, "Ruleset %s loaded into table %s, chain %s", ruleset, table, chain); -} - - void -iptables_fw_clear_authservers(void) -{ - iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); -} - - void -iptables_fw_set_authservers(void) -{ - const s_config *config; - t_auth_serv *auth_server; - - config = config_get_config(); - - for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { - if (auth_server->last_ip && strcmp(auth_server->last_ip, "0.0.0.0") != 0) { - iptables_do_command("-t filter -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_AUTHSERVERS " -d %s -j ACCEPT", auth_server->last_ip); - } - } ->>>>>>> FETCH_HEAD } /** Initialize the firewall rules */ -<<<<<<< HEAD int iptables_fw_init(void) { @@ -578,231 +403,10 @@ iptables_fw_init(void) return 1; } -======= - int -iptables_fw_init(void) -{ - const s_config *config; - char * ext_interface = NULL; - int gw_port = 0; - t_trusted_mac *p; - t_white_list *p0; - t_black_list *p1; - t_untrusted_mac *p3; - int proxy_port; - fw_quiet = 0; - - LOCK_CONFIG(); - config = config_get_config(); - gw_port = config->gw_port; - if (config->external_interface) { - ext_interface = safe_strdup(config->external_interface); - - memset(dev_extern_iface,0,64); - sprintf(dev_extern_iface,"%s",ext_interface); - debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); - } else { - ext_interface = get_ext_iface(); - - memset(dev_extern_iface,0,64); - sprintf(dev_extern_iface,"%s",ext_interface); - debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); - } - - if (ext_interface == NULL) { - UNLOCK_CONFIG(); - debug(LOG_ERR, "FATAL: no external interface"); - return 0; - } - /* - * - * Everything in the MANGLE table - * - */ - - /* Create new chains */ - iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED); - iptables_do_command("-t mangle -N " TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t mangle -N " TABLE_WIFIDOG_INCOMING); - /* gaomingpan:Untrusted mac chains*/ - iptables_do_command("-t mangle -N " TABLE_WIFIDOG_UNTRUSTED); - /* limeng */ - iptables_do_command("-t mangle -N " TABLE_WIFIDOG_BLACKLIST); - - /* Assign links and rules to these new chains */ - iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); - iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, config->gw_interface);//this rule will be inserted before the prior one - iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, config->gw_interface); - - for (p = config->trustedmaclist; p != NULL; p = p->next) - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN); - - /*gaomingpan untrusted mac list*/ - iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_UNTRUSTED, config->gw_interface); - for (p3 = config->untrustedmaclist; p3 != NULL; p3 = p3->next){ - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_UNTRUSTED " -m mac --mac-source %s --j MARK --set-mark %d", p3->mac,FW_MARK_LOCKED); - debug(LOG_INFO,"Untrusted mac: %s ",p3->mac); - } - /* limeng */ - iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_BLACKLIST, config->gw_interface); - for (p1 = config->black_list; p1 != NULL; p1 = p1->next) - { - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); - } - - /* - * - * Everything in the NAT table - * - */ - - /* Create new chains */ - iptables_do_command("-t nat -N " TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER); - iptables_do_command("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t nat -N " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t nat -N " TABLE_WIFIDOG_UNKNOWN); - iptables_do_command("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS); - /* limeng */ - iptables_do_command("-t nat -N " TABLE_WIFIDOG_WHITELIST); - - /* Assign links and rules to these new chains */ - iptables_do_command("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface); - - iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, config->gw_address); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT"); - - iptables_do_command("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET); - - if((proxy_port=config_get_config()->proxy_port) != 0){ - debug(LOG_DEBUG,"Proxy port set, setting proxy rule"); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_KNOWN, proxy_port); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_PROBATION, proxy_port); - } - - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); - - iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port); - /* limeng */ - iptables_do_command("-t nat -I" TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_WHITELIST); - for (p0 = config->white_list; p0 != NULL; p0 = p0->next) - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); - - /* - * - * Everything in the FILTER table - * - */ - - /* Create new chains */ - iptables_do_command("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t filter -N " TABLE_WIFIDOG_LOCKED); - iptables_do_command("-t filter -N " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t filter -N " TABLE_WIFIDOG_VALIDATE); - iptables_do_command("-t filter -N " TABLE_WIFIDOG_KNOWN); - iptables_do_command("-t filter -N " TABLE_WIFIDOG_UNKNOWN); - /* limeng */ - iptables_do_command("-t filter -N " TABLE_WIFIDOG_WHITELIST); - - /* Assign links and rules to these new chains */ - - /* Insert at the beginning */ - iptables_do_command("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, config->gw_interface); - - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP"); - - /* XXX: Why this? it means that connections setup after authentication - stay open even after the connection is done... - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/ - - //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23 - //iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface); - - /* TCPMSS rule for PPPoE */ - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface); - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS); - iptables_fw_set_authservers(); - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED); - iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED); - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL); - iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL); - iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL); - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION); - iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE); - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%u -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN); - iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN); - - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN); - iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN); - iptables_do_command("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable"); - - /* limeng */ - iptables_do_command("-t filter -I" TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_WHITELIST); - for (p0 = config->white_list; p0 != NULL; p0 = p0->next) - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); - - UNLOCK_CONFIG(); - return 1; -} - -void iptables_white_black_list_update(void) -{ - //static time_t timer_old; - //static time_t timer_new; - time_t sec; - struct tm * curTime; - sec = time(NULL); - curTime = localtime(&sec); - static int sec_old = 0; - - t_white_list *p0 = NULL; - t_black_list *p1 = NULL; - const s_config *config; - - if(curTime->tm_sec != sec_old) - { - sec_old = curTime->tm_sec; - - if(curTime->tm_sec == 0 && curTime->tm_min == 0 && curTime->tm_hour == 4) - { - LOCK_CONFIG(); - config = config_get_config(); - - iptables_do_command("-t mangle -F " TABLE_WIFIDOG_BLACKLIST); - for (p1 = config->black_list; p1 != NULL; p1 = p1->next) - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_BLACKLIST " -d %s -j DROP ", p1->ip); - - iptables_do_command("-t nat -F " TABLE_WIFIDOG_WHITELIST); - for (p0 = config->white_list; p0 != NULL; p0 = p0->next) - iptables_do_command("-t nat -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); - - iptables_do_command("-t filter -F " TABLE_WIFIDOG_WHITELIST); - for (p0 = config->white_list; p0 != NULL; p0 = p0->next) - iptables_do_command("-t filter -A " TABLE_WIFIDOG_WHITELIST " -d %s -j ACCEPT ", p0->ip); - } - - UNLOCK_CONFIG(); - } -} - - ->>>>>>> FETCH_HEAD /** Remove the firewall rules * This is used when we do a clean shutdown of WiFiDog and when it starts to make * sure there are no rules left over */ -<<<<<<< HEAD int iptables_fw_destroy(void) { @@ -884,88 +488,6 @@ iptables_fw_destroy(void) iptables_do_command("-t filter -X " CHAIN_AUTH_IS_DOWN); return 1; -======= - int -iptables_fw_destroy(void) -{ - fw_quiet = 1; - - debug(LOG_DEBUG, "Destroying our iptables entries"); - - /* - * - * Everything in the MANGLE table - * - */ - debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); - iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_TRUSTED); - iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_UNTRUSTED);/*gaomingpan: untrusted macs*/ - iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_OUTGOING); - iptables_fw_destroy_mention("mangle", "POSTROUTING", TABLE_WIFIDOG_INCOMING); - iptables_fw_destroy_mention("mangle", "PREROUTING", TABLE_WIFIDOG_BLACKLIST); - - iptables_do_command("-t mangle -F " TABLE_WIFIDOG_TRUSTED); - iptables_do_command("-t mangle -F " TABLE_WIFIDOG_UNTRUSTED); /*gaomingpan: untrusted macs*/ - iptables_do_command("-t mangle -F " TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t mangle -F " TABLE_WIFIDOG_INCOMING); - iptables_do_command("-t mangle -F " TABLE_WIFIDOG_BLACKLIST); - - iptables_do_command("-t mangle -X " TABLE_WIFIDOG_TRUSTED); - iptables_do_command("-t mangle -X " TABLE_WIFIDOG_UNTRUSTED); /*gaomingpan: untrusted macs*/ - iptables_do_command("-t mangle -X " TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t mangle -X " TABLE_WIFIDOG_INCOMING); - iptables_do_command("-t mangle -X " TABLE_WIFIDOG_BLACKLIST); - - /* - * - * Everything in the NAT table - * - */ - debug(LOG_DEBUG, "Destroying chains in the NAT table"); - iptables_fw_destroy_mention("nat", "PREROUTING", TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_ROUTER); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_UNKNOWN); - iptables_do_command("-t nat -F " TABLE_WIFIDOG_WHITELIST); - - iptables_do_command("-t nat -X " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t nat -X " TABLE_WIFIDOG_OUTGOING); - iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_ROUTER); - iptables_do_command("-t nat -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t nat -X " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t nat -X " TABLE_WIFIDOG_UNKNOWN); - iptables_do_command("-t nat -X " TABLE_WIFIDOG_WHITELIST); - - /* - * - * Everything in the FILTER table - * - */ - debug(LOG_DEBUG, "Destroying chains in the FILTER table"); - iptables_fw_destroy_mention("filter", "FORWARD", TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_LOCKED); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_VALIDATE); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_KNOWN); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_UNKNOWN); - iptables_do_command("-t filter -F " TABLE_WIFIDOG_WHITELIST); - - iptables_do_command("-t filter -X " TABLE_WIFIDOG_WIFI_TO_INTERNET); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_AUTHSERVERS); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_LOCKED); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_GLOBAL); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_VALIDATE); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_KNOWN); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_UNKNOWN); - iptables_do_command("-t filter -X " TABLE_WIFIDOG_WHITELIST); - - return 1; ->>>>>>> FETCH_HEAD } /* @@ -975,7 +497,6 @@ iptables_fw_destroy(void) * @param mention A word to find and delete in rules in the given table+chain */ int -<<<<<<< HEAD iptables_fw_destroy_mention(const char *table, const char *chain, const char *mention) { FILE *p = NULL; @@ -1203,185 +724,4 @@ iptables_fw_counters_update(void) pclose(output); return 1; -======= -iptables_fw_destroy_mention( - const char * table, - const char * chain, - const char * mention - ) { - FILE *p = NULL; - char *command = NULL; - char *command2 = NULL; - char line[MAX_BUF]; - char rulenum[10]; - char *victim = safe_strdup(mention); - int deleted = 0; - - iptables_insert_gateway_id(&victim); - - debug(LOG_DEBUG, "Attempting to destroy all mention of %s from %s.%s", victim, table, chain); - - safe_asprintf(&command, "iptables -t %s -L %s -n --line-numbers -v", table, chain); - iptables_insert_gateway_id(&command); - - if ((p = popen(command, "r"))) { - /* Skip first 2 lines */ - while (!feof(p) && fgetc(p) != '\n'); - while (!feof(p) && fgetc(p) != '\n'); - /* Loop over entries */ - while (fgets(line, sizeof(line), p)) { - /* Look for victim */ - if (strstr(line, victim)) { - /* Found victim - Get the rule number into rulenum*/ - if (sscanf(line, "%9[0-9]", rulenum) == 1) { - /* Delete the rule: */ - debug(LOG_DEBUG, "Deleting rule %s from %s.%s because it mentions %s", rulenum, table, chain, victim); - safe_asprintf(&command2, "-t %s -D %s %s", table, chain, rulenum); - iptables_do_command(command2); - free(command2); - deleted = 1; - /* Do not keep looping - the captured rulenums will no longer be accurate */ - break; - } - } - } - pclose(p); - } - - free(command); - free(victim); - - if (deleted) { - /* Recurse just in case there are more in the same table+chain */ - iptables_fw_destroy_mention(table, chain, mention); - } - - return (deleted); -} - -/** Set if a specific client has access through the firewall */ - int -iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag) -{ - int rc; - - fw_quiet = 0; - - switch(type) { - case FW_ACCESS_ALLOW: - iptables_do_command("-t mangle -A " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); - rc = iptables_do_command("-t mangle -A " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); - break; - case FW_ACCESS_DENY: - iptables_do_command("-t mangle -D " TABLE_WIFIDOG_OUTGOING " -s %s -m mac --mac-source %s -j MARK --set-mark %d", ip, mac, tag); - rc = iptables_do_command("-t mangle -D " TABLE_WIFIDOG_INCOMING " -d %s -j ACCEPT", ip); - break; - default: - rc = -1; - break; - } - - return rc; -} - -/** Update the counters of all the clients in the client list */ - int -iptables_fw_counters_update(void) -{ - FILE *output; - char *script, - ip[16], - rc; - unsigned long long int counter; - t_client *p1; - struct in_addr tempaddr; - - /* Look for outgoing traffic */ - safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING); - iptables_insert_gateway_id(&script); - output = popen(script, "r"); - free(script); - if (!output) { - debug(LOG_ERR, "popen(): %s", strerror(errno)); - return -1; - } - - /* skip the first two lines */ - while (('\n' != fgetc(output)) && !feof(output)) - ; - while (('\n' != fgetc(output)) && !feof(output)) - ; - while (output && !(feof(output))) { - rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); - //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); - if (2 == rc && EOF != rc) { - /* Sanity*/ - if (!inet_aton(ip, &tempaddr)) { - debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); - continue; - } - debug(LOG_DEBUG, "Read outgoing traffic for %s: Bytes=%llu", ip, counter); - LOCK_CLIENT_LIST(); - if ((p1 = client_list_find_by_ip(ip))) { - if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) { - p1->counters.outgoing = p1->counters.outgoing_history + counter; - p1->counters.last_updated = time(NULL); - debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes. Updated last_updated to %d", ip, counter, p1->counters.last_updated); - } - } else { - debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); - debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); - iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); - debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); - iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); - } - UNLOCK_CLIENT_LIST(); - } - } - pclose(output); - - /* Look for incoming traffic */ - safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING); - iptables_insert_gateway_id(&script); - output = popen(script, "r"); - free(script); - if (!output) { - debug(LOG_ERR, "popen(): %s", strerror(errno)); - return -1; - } - - /* skip the first two lines */ - while (('\n' != fgetc(output)) && !feof(output)) - ; - while (('\n' != fgetc(output)) && !feof(output)) - ; - while (output && !(feof(output))) { - rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); - if (2 == rc && EOF != rc) { - /* Sanity*/ - if (!inet_aton(ip, &tempaddr)) { - debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip); - continue; - } - debug(LOG_DEBUG, "Read incoming traffic for %s: Bytes=%llu", ip, counter); - LOCK_CLIENT_LIST(); - if ((p1 = client_list_find_by_ip(ip))) { - if ((p1->counters.incoming - p1->counters.incoming_history) < counter) { - p1->counters.incoming = p1->counters.incoming_history + counter; - debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter); - } - } else { - debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip); - debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING); - iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip); - debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING); - iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip); - } - UNLOCK_CLIENT_LIST(); - } - } - pclose(output); - - return 1; ->>>>>>> FETCH_HEAD } diff --git a/src/fw_iptables.h b/src/fw_iptables.h index aa0961f2..83d890b7 100644 --- a/src/fw_iptables.h +++ b/src/fw_iptables.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -33,7 +30,6 @@ #include "firewall.h" -<<<<<<< HEAD /*@{*/ /**Iptable chain names used by WifiDog */ #define CHAIN_OUTGOING "WiFiDog_$ID$_Outgoing" @@ -49,28 +45,6 @@ #define CHAIN_TRUSTED "WiFiDog_$ID$_Trusted" #define CHAIN_AUTH_IS_DOWN "WiFiDog_$ID$_AuthIsDown" /*@}*/ -======= -/*@{*/ -/**Iptable table names used by WifiDog */ -#define TABLE_WIFIDOG_OUTGOING "WiFiDog_$ID$_Outgoing" -#define TABLE_WIFIDOG_WIFI_TO_INTERNET "WiFiDog_$ID$_WIFI2Internet" -#define TABLE_WIFIDOG_WIFI_TO_ROUTER "WiFiDog_$ID$_WIFI2Router" -#define TABLE_WIFIDOG_INCOMING "WiFiDog_$ID$_Incoming" -#define TABLE_WIFIDOG_AUTHSERVERS "WiFiDog_$ID$_AuthServers" -#define TABLE_WIFIDOG_GLOBAL "WiFiDog_$ID$_Global" -#define TABLE_WIFIDOG_VALIDATE "WiFiDog_$ID$_Validate" -#define TABLE_WIFIDOG_KNOWN "WiFiDog_$ID$_Known" -#define TABLE_WIFIDOG_UNKNOWN "WiFiDog_$ID$_Unknown" -#define TABLE_WIFIDOG_LOCKED "WiFiDog_$ID$_Locked" -#define TABLE_WIFIDOG_TRUSTED "WiFiDog_$ID$_Trusted" -/*gaomingpan*/ -#define TABLE_WIFIDOG_UNTRUSTED "WiFiDog_$ID$_Untrusted" -/* limeng */ -#define TABLE_WIFIDOG_WHITELIST "WiFiDog_$ID$_WhiteList" -#define TABLE_WIFIDOG_BLACKLIST "WiFiDog_$ID$_BlackList" - -/*@}*/ ->>>>>>> FETCH_HEAD /** Used by iptables_fw_access to select if the client should be granted of denied access */ typedef enum fw_access_t_ { @@ -80,11 +54,6 @@ typedef enum fw_access_t_ { /** @brief Initialize the firewall */ int iptables_fw_init(void); -<<<<<<< HEAD -======= -void iptables_white_black_list_update(void); - ->>>>>>> FETCH_HEAD /** @brief Initializes the authservers table */ void iptables_fw_set_authservers(void); @@ -96,16 +65,11 @@ void iptables_fw_clear_authservers(void); int iptables_fw_destroy(void); /** @brief Helper function for iptables_fw_destroy */ -<<<<<<< HEAD int iptables_fw_destroy_mention(const char *table, const char *chain, const char *mention); -======= -int iptables_fw_destroy_mention( const char * table, const char * chain, const char * mention); ->>>>>>> FETCH_HEAD /** @brief Define the access of a specific client */ int iptables_fw_access(fw_access_t type, const char *ip, const char *mac, int tag); -<<<<<<< HEAD /** @brief Define the access of a host */ int iptables_fw_access_host(fw_access_t type, const char *host); @@ -119,14 +83,3 @@ int iptables_fw_auth_reachable(void); int iptables_fw_counters_update(void); #endif /* _IPTABLES_H_ */ -======= -/** @brief All counters in the client list */ -int iptables_fw_counters_update(void); - - -/** @brief Get extern interface - * this function use at get_devinfo.c*/ -char *get_dev_extern_iface(); - -#endif /* _IPTABLES_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/gateway.c b/src/gateway.c index e5f6a9ca..d5eb6ebc 100644 --- a/src/gateway.c +++ b/src/gateway.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,10 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* $Id$ */ ->>>>>>> FETCH_HEAD /** @internal @file gateway.c @brief Main loop @@ -67,50 +60,24 @@ #include "httpd_thread.h" #include "util.h" -<<<<<<< HEAD -======= - -#include "get_remote_shell.h" -#include "device_key.h" - ->>>>>>> FETCH_HEAD /** XXX Ugly hack * We need to remember the thread IDs of threads that simulate wait with pthread_cond_timedwait * so we can explicitly kill them in the termination handler */ static pthread_t tid_fw_counter = 0; -<<<<<<< HEAD static pthread_t tid_ping = 0; time_t started_time = 0; -======= -static pthread_t tid_ping = 0; ->>>>>>> FETCH_HEAD /* The internal web server */ httpd * webserver = NULL; -<<<<<<< HEAD -======= -/* from commandline.c */ -extern char ** restartargv; -extern pid_t restart_orig_pid; -t_client *firstclient; - -/* from client_list.c */ -extern pthread_mutex_t client_list_mutex; - -/* Time when wifidog started */ -time_t started_time = 0; - ->>>>>>> FETCH_HEAD /* Appends -x, the current PID, and NULL to restartargv * see parse_commandline in commandline.c for details * * Why is restartargv global? Shouldn't it be at most static to commandline.c * and this function static there? -Alex @ 8oct2006 */ -<<<<<<< HEAD void append_x_restartargv(void) { @@ -120,22 +87,12 @@ append_x_restartargv(void) restartargv[i++] = safe_strdup("-x"); safe_asprintf(&(restartargv[i++]), "%d", getpid()); -======= -void append_x_restartargv(void) { - int i; - - for (i=0; restartargv[i]; i++); - - restartargv[i++] = safe_strdup("-x"); - safe_asprintf(&(restartargv[i++]), "%d", getpid()); ->>>>>>> FETCH_HEAD } /* @internal * @brief During gateway restart, connects to the parent process via the internal socket * Downloads from it the active client list */ -<<<<<<< HEAD void get_clients_from_parent(void) { @@ -272,152 +229,6 @@ get_clients_from_parent(void) debug(LOG_INFO, "Client list downloaded successfully from parent"); close(sock); -======= -void get_clients_from_parent(void) { - int sock; - struct sockaddr_un sa_un; - s_config * config = NULL; - char linebuffer[MAX_BUF]; - int len = 0; - char *running1 = NULL; - char *running2 = NULL; - char *token1 = NULL; - char *token2 = NULL; - char onechar; - char *command = NULL; - char *key = NULL; - char *value = NULL; - t_client * client = NULL; - t_client * lastclient = NULL; - - config = config_get_config(); - - debug(LOG_INFO, "Connecting to parent to download clients"); - - /* Connect to socket */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); - memset(&sa_un, 0, sizeof(sa_un)); - sa_un.sun_family = AF_UNIX; - strncpy(sa_un.sun_path, config->internal_sock, (sizeof(sa_un.sun_path) - 1)); - - if (connect(sock, (struct sockaddr *)&sa_un, strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { - debug(LOG_ERR, "Failed to connect to parent (%s) - client list not downloaded", strerror(errno)); - return; - } - - debug(LOG_INFO, "Connected to parent. Downloading clients"); - - LOCK_CLIENT_LIST(); - - command = NULL; - memset(linebuffer, 0, sizeof(linebuffer)); - len = 0; - client = NULL; - /* Get line by line */ - while (read(sock, &onechar, 1) == 1) { - if (onechar == '\n') { - /* End of line */ - onechar = '\0'; - } - linebuffer[len++] = onechar; - - if (!onechar) { - /* We have a complete entry in linebuffer - parse it */ - debug(LOG_DEBUG, "Received from parent: [%s]", linebuffer); - running1 = linebuffer; - while ((token1 = strsep(&running1, "|")) != NULL) { - if (!command) { - /* The first token is the command */ - command = token1; - } - else { - /* Token1 has something like "foo=bar" */ - running2 = token1; - key = value = NULL; - while ((token2 = strsep(&running2, "=")) != NULL) { - if (!key) { - key = token2; - } - else if (!value) { - value = token2; - } - } - } - - if (strcmp(command, "CLIENT") == 0) { - /* This line has info about a client in the client list */ - if (!client) { - /* Create a new client struct */ - client = safe_malloc(sizeof(t_client)); - memset(client, 0, sizeof(t_client)); - } - } - - if (key && value) { - if (strcmp(command, "CLIENT") == 0) { - /* Assign the key into the appropriate slot in the connection structure */ - if (strcmp(key, "ip") == 0) { - client->ip = safe_strdup(value); - } - else if (strcmp(key, "mac") == 0) { - client->mac = safe_strdup(value); - } - else if (strcmp(key, "token") == 0) { - client->token = safe_strdup(value); - } - else if (strcmp(key, "fw_connection_state") == 0) { - client->fw_connection_state = atoi(value); - } - else if (strcmp(key, "fd") == 0) { - client->fd = atoi(value); - } - else if (strcmp(key, "counters_incoming") == 0) { - client->counters.incoming_history = atoll(value); - client->counters.incoming = client->counters.incoming_history; - } - else if (strcmp(key, "counters_outgoing") == 0) { - client->counters.outgoing_history = atoll(value); - client->counters.outgoing = client->counters.outgoing_history; - } - else if (strcmp(key, "counters_last_updated") == 0) { - client->counters.last_updated = atol(value); - }/*get record_time from parents*/ - else if (strcmp(key, "record_time") == 0) { - client->record_time = atol(value); - } - else { - debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); - } - } - } - } - - /* End of parsing this command */ - if (client) { - /* Add this client to the client list */ - if (!firstclient) { - firstclient = client; - lastclient = firstclient; - } - else { - lastclient->next = client; - lastclient = client; - } - } - - /* Clean up */ - command = NULL; - memset(linebuffer, 0, sizeof(linebuffer)); - len = 0; - client = NULL; - } - } - - UNLOCK_CLIENT_LIST(); - debug(LOG_INFO, "Client list downloaded successfully from parent"); - - close(sock); ->>>>>>> FETCH_HEAD } /**@internal @@ -430,7 +241,6 @@ void get_clients_from_parent(void) { void sigchld_handler(int s) { -<<<<<<< HEAD int status; pid_t rc; @@ -480,55 +290,6 @@ termination_handler(int s) debug(LOG_NOTICE, "Exiting..."); exit(s == 0 ? 1 : 0); -======= - int status; - pid_t rc; - - debug(LOG_DEBUG, "Handler for SIGCHLD called. Trying to reap a child"); - - rc = waitpid(-1, &status, WNOHANG); - - debug(LOG_DEBUG, "Handler for SIGCHLD reaped child PID %d", rc); -} - -/** Exits cleanly after cleaning up the firewall. - * Use this function anytime you need to exit after firewall initialization */ -void -termination_handler(int s) -{ - static pthread_mutex_t sigterm_mutex = PTHREAD_MUTEX_INITIALIZER; - - debug(LOG_INFO, "Handler for termination caught signal %d", s); - - /* Makes sure we only call fw_destroy() once. */ - if (pthread_mutex_trylock(&sigterm_mutex)) { - debug(LOG_INFO, "Another thread already began global termination handler. I'm exiting"); - pthread_exit(NULL); - } - else { - debug(LOG_INFO, "Cleaning up and exiting"); - } - - debug(LOG_INFO, "Flushing firewall rules..."); - fw_destroy(); - - /* XXX Hack - * Aparently pthread_cond_timedwait under openwrt prevents signals (and therefore - * termination handler) from happening so we need to explicitly kill the threads - * that use that - */ - if (tid_fw_counter) { - debug(LOG_INFO, "Explicitly killing the fw_counter thread"); - pthread_kill(tid_fw_counter, SIGKILL); - } - if (tid_ping) { - debug(LOG_INFO, "Explicitly killing the ping thread"); - pthread_kill(tid_ping, SIGKILL); - } - - debug(LOG_NOTICE, "Exiting..."); - exit(s == 0 ? 1 : 0); ->>>>>>> FETCH_HEAD } /** @internal @@ -537,7 +298,6 @@ termination_handler(int s) static void init_signals(void) { -<<<<<<< HEAD struct sigaction sa; debug(LOG_DEBUG, "Initializing signal handlers"); @@ -583,53 +343,6 @@ init_signals(void) debug(LOG_ERR, "sigaction(): %s", strerror(errno)); exit(1); } -======= - struct sigaction sa; - - debug(LOG_DEBUG, "Initializing signal handlers"); - - sa.sa_handler = sigchld_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - if (sigaction(SIGCHLD, &sa, NULL) == -1) { - debug(LOG_ERR, "sigaction(): %s", strerror(errno)); - exit(1); - } - - /* Trap SIGPIPE */ - /* This is done so that when libhttpd does a socket operation on - * a disconnected socket (i.e.: Broken Pipes) we catch the signal - * and do nothing. The alternative is to exit. SIGPIPE are harmless - * if not desirable. - */ - sa.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &sa, NULL) == -1) { - debug(LOG_ERR, "sigaction(): %s", strerror(errno)); - exit(1); - } - - sa.sa_handler = termination_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - - /* Trap SIGTERM */ - if (sigaction(SIGTERM, &sa, NULL) == -1) { - debug(LOG_ERR, "sigaction(): %s", strerror(errno)); - exit(1); - } - - /* Trap SIGQUIT */ - if (sigaction(SIGQUIT, &sa, NULL) == -1) { - debug(LOG_ERR, "sigaction(): %s", strerror(errno)); - exit(1); - } - - /* Trap SIGINT */ - if (sigaction(SIGINT, &sa, NULL) == -1) { - debug(LOG_ERR, "sigaction(): %s", strerror(errno)); - exit(1); - } ->>>>>>> FETCH_HEAD } /**@internal @@ -638,7 +351,6 @@ init_signals(void) static void main_loop(void) { -<<<<<<< HEAD int result; pthread_t tid; s_config *config = config_get_config(); @@ -836,223 +548,3 @@ gw_main(int argc, char **argv) return (0); /* never reached */ } -======= - int result; - pthread_t tid; - s_config *config = config_get_config(); - request *r; - void **params; - - /* Set the time when wifidog started */ - if (!started_time) { - debug(LOG_INFO, "Setting started_time"); - started_time = time(NULL); - } - else if (started_time < MINIMUM_STARTED_TIME) { - debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); - started_time = time(NULL); - } - - /* If we don't have the Gateway IP address, get it. Can't fail. */ - if (!config->gw_address) { - debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); - if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { - debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); - exit(1); - } - debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); - } - - /* If we don't have the Gateway ID, construct it from the internal MAC address. - * "Can't fail" so exit() if the impossible happens. */ - if (!config->gw_id) { - debug(LOG_DEBUG, "Finding MAC address of %s", config->gw_interface); - if ((config->gw_id = get_iface_mac(config->gw_interface)) == NULL) { - debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); - exit(1); - } - debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_id); - } - - /* Initializes the web server */ - debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); - if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { - debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); - exit(1); - } - - /**************************************************/ - /**** init my post url config *****/ - if(0 != init_post_http_url_config() ) - { - debug(LOG_ERR, "ERROR: Failed to initialize init_post_http_url_config"); - //exit(1); - } - /*init device key*/ - if(0 != init_device_key()) - { - debug(LOG_ERR,"ERROR:Failed to initalize device key."); - } - /*get ap mac*/ - if(0 != get_apmac(NULL)) - { - debug(LOG_ERR,"ERROR:Failed to get ap MAC."); - } - /*********************************/ - - debug(LOG_DEBUG, "Assigning callbacks to web server"); - httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog); - httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog); - httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about); - httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status); - httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth); - - httpdAddC404Content(webserver, http_callback_404); - - /* Reset the firewall (if WiFiDog crashed) */ - fw_destroy(); - /* Then initialize it */ - if (!fw_init()) { - debug(LOG_ERR, "FATAL: Failed to initialize firewall"); - exit(1); - } - - /* Start clean up thread */ - result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); - if (result != 0) { - debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting"); - termination_handler(0); - } - pthread_detach(tid_fw_counter); - - /* Start control thread */ - result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); - if (result != 0) { - debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); - termination_handler(0); - } - pthread_detach(tid); - - /* Start heartbeat thread */ - result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL); - if (result != 0) { - debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting"); - termination_handler(0); - } - pthread_detach(tid_ping); - - debug(LOG_NOTICE, "Waiting for connections"); - while(1) { - r = httpdGetConnection(webserver, NULL); - - /* We can't convert this to a switch because there might be - * values that are not -1, 0 or 1. */ - if (webserver->lastError == -1) { - /* Interrupted system call */ - continue; /* restart loop */ - } - else if (webserver->lastError < -1) { - /* - * FIXME - * An error occurred - should we abort? - * reboot the device ? - */ - debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); - termination_handler(0); - } - else if (r != NULL) { - /* - * We got a connection - * - * We should create another thread - */ - debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); - /* The void**'s are a simulation of the normal C - * function calling sequence. */ - params = safe_malloc(2 * sizeof(void *)); - *params = webserver; - *(params + 1) = r; - - result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); - if (result != 0) { - debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); - termination_handler(0); - } - pthread_detach(tid); - } - else { - /* webserver->lastError should be 2 */ - /* XXX We failed an ACL.... No handling because - * we don't set any... */ - } - - /* limeng */ - iptables_white_black_list_update(); - } - - /* never reached */ -} - -/** Reads the configuration file and then starts the main loop */ -int main(int argc, char **argv) { - - s_config *config = config_get_config(); - config_init(); - - parse_commandline(argc, argv); - - /* Initialize the config */ - config_read(config->configfile); - config_validate(); - - /* Initializes the linked list of connected clients */ - client_list_init(); - - /* Init the signals to catch chld/quit/etc */ - init_signals(); - - - if (restart_orig_pid) { - /* - * We were restarted and our parent is waiting for us to talk to it over the socket - */ - get_clients_from_parent(); - - /* - * At this point the parent will start destroying itself and the firewall. Let it finish it's job before we continue - */ - while (kill(restart_orig_pid, 0) != -1) { - debug(LOG_INFO, "Waiting for parent PID %d to die before continuing loading", restart_orig_pid); - sleep(1); - } - - debug(LOG_INFO, "Parent PID %d seems to be dead. Continuing loading."); - } - - if (config->daemon) { - - debug(LOG_INFO, "Forking into background"); - - switch(safe_fork()) { - case 0: /* child */ - setsid(); - append_x_restartargv(); - main_loop(); - break; - - default: /* parent */ - exit(0); - break; - } - } - else { - append_x_restartargv(); - main_loop(); - } - - return(0); /* never reached */ -} - - - ->>>>>>> FETCH_HEAD diff --git a/src/gateway.h b/src/gateway.h index b334c4df..98939618 100644 --- a/src/gateway.h +++ b/src/gateway.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -30,7 +27,6 @@ #ifndef _GATEWAY_H_ #define _GATEWAY_H_ -<<<<<<< HEAD #include @@ -48,10 +44,3 @@ int gw_main(int, char **); void termination_handler(int s); #endif /* _GATEWAY_H_ */ -======= - -/** @brief exits cleanly and clear the firewall rules. */ -void termination_handler(int s); - -#endif /* _GATEWAY_H_ */ ->>>>>>> FETCH_HEAD diff --git a/src/get_clientinfo.c b/src/get_clientinfo.c deleted file mode 100755 index 4dd5c914..00000000 --- a/src/get_clientinfo.c +++ /dev/null @@ -1,370 +0,0 @@ -/* - * get_clientinfo.c - * - * Created on: Jul 13, 2015 - * Author: GaomingPan - */ - - -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include - -#include "util.h" -#include "debug.h" -#include "conf.h" -#include "client_list.h" -#include "../config.h" - - -#include "shell_command.h" -#include "get_clientinfo.h" - - -static t_clientinfo *first_client_info = NULL; - -static char client_auth_flag[7] = {0}; - -/* @breif get client host name,income speed and outgo speed,based on shell command. - * this functions take at least 1 second to run,because of execute the shell - * command have to sleep 1 second to collect client speed. - * @PARAMETER:void - * @RETURN_VALUE:zero is success,others is error. - * @Note: after this function be called and you got some clients information,you should - * call clean_client_info() function to clean up,just like the fopen() and fclose(). - * GaomingPan lonely-test:yes - * */ -int collect_client_info() -{ - FILE *fp; - - char a_rate[20], - ip[18]; - - t_clientinfo *p1, - *p2, - *p3; - - int ret; - - int line_num = 0; - char *line = NULL; - - - /** - * malloc memories for clients info list. - * */ - first_client_info = (t_clientinfo*)malloc(sizeof(t_clientinfo)); - if(NULL == first_client_info){ - debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - return -1; - } - first_client_info->next = NULL; - p1 = first_client_info; - p2 = p1; - - - /** - * get host name,ip and mac - * */ - fp = fopen(HOST_NAME_FILE,"r"); - if(NULL == fp){ - - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen error."); - return -1; - } - while(-1 != getline(&line,&line_num,fp)){ - if(NULL == p1){ - p1 = (t_clientinfo*)malloc(sizeof(t_clientinfo)); - if(NULL == p1){ - debug(LOG_ERR,"ERROR: at collect_client_info(), malloc error."); - fclose(fp); - return -1; - } - p2->next = p1; - p2 = p1; - p1->next = NULL; - - }//if(NULL == p1) - ret = sscanf(line,"%s %s %s",p1->client_mac,p1->client_ip,p1->host_name); - if(3 != ret){ - if(line != NULL) - free(line); - fclose(fp); - return -1; - } - p1 = p1->next; - - }//while - fclose(fp); - if(line != NULL){ - free(line); - line = NULL; - } - - - /* get up speed - * */ - fp = fopen(UP_SPEED_FILE,"r"); - if(NULL == fp){ - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); - return -1; - } - while(-1 != getline(&line,&line_num,fp)){ - ret = sscanf(line,"%s %s",ip,a_rate); - if(2 != ret){ - if(line != NULL) - free(line); - fclose(fp); - return -1; - } - p3 = get_client_info_by_ip(ip); - if(NULL != p3){ - p3->go_speed = atoi(a_rate); - } - - }//while - fclose(fp); - if(line != NULL){ - free(line); - line = NULL; - } - - - - /* get the down speed - * */ - fp = fopen(DOWN_SPEED_FILE,"r"); - if(NULL == fp){ - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); - return -1; - } - while(-1 != getline(&line,&line_num,fp)){ - - ret = sscanf(line,"%s %s",ip,a_rate); - if(2 != ret){ - if(line != NULL) - free(line); - fclose(fp); - return -1; - } - p3 = get_client_info_by_ip(ip); - if(NULL != p3){ - p3->come_speed = atoi(a_rate); - } - - }//while - fclose(fp); - if(line != NULL){ - free(line); - line = NULL; - } - - - return 0; -} - - - -/* @breif get unknown host name client's income speed and outgo speed,based on shell command. - * this functions take at least 1 second to run,because of execute the shell - * command have to sleep 1 second to collect client speed. - * @PARAMETER:[char *client_ip] the unknown host name client's ip - * [int *go_speed] the pointer for client's outgoing speed to store. - * [int *come_speed] the pointer for client's incoming speed to store. - * @RETURN_VALUE:zero is success,others is error. - * @Note: none - * GaomingPan lonely-test:yes - * */ -int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed) -{ - - FILE *fp; - - char a_rate[20], - ip[18]; - - int ret; - int line_num = 0; - char *line = NULL; - - - /* get up speed - * */ - fp = fopen(UP_SPEED_FILE,"r"); - if(NULL == fp){ - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); - return -1; - } - while(-1 != getline(&line,&line_num,fp)){ - ret = sscanf(line,"%s %s",ip,a_rate); - if(2 != ret){ - if(line != NULL) - free(line); - fclose(fp); - *go_speed = 0; - *come_speed = 0; - return -1; - } - - if(0 == strcmp(client_ip,ip)){ - *go_speed = atoi(a_rate); - } - - }//while - fclose(fp); - if(line != NULL){ - free(line); - line = NULL; - } - - - - /* get the down speed - * */ - fp = fopen(DOWN_SPEED_FILE,"r"); - if(NULL == fp){ - debug(LOG_ERR,"ERROR: at collect_client_info(),fopen for fp error."); - return -1; - } - while(-1 != getline(&line,&line_num,fp)){ - - ret = sscanf(line,"%s %s",ip,a_rate); - if(2 != ret){ - if(line != NULL) - free(line); - fclose(fp); - *go_speed = 0; - *come_speed = 0; - return -1; - } - if(0 == strcmp(client_ip,ip)){ - *come_speed = atoi(a_rate); - } - - }//while - fclose(fp); - if(line != NULL){ - free(line); - line = NULL; - } - - return 0; -} - -/* @breif After the function collect_client_info() called,should call this function to - * clean up. - * @PARAMETER:void - * @RETURN_VALUE:void - * @Note: function collect_client_info() and this function just like the fopen() and fclose(). - * GaomingPan lonely-test:yes - * */ -void clean_client_info() -{ - t_clientinfo *p; - - p = first_client_info; - - while(NULL != p){ - free(p); - p = p->next; - } - - first_client_info = NULL; -} - - - -/* @breif find the element from the client_info list by mac. - * @PARAMETER:[const char *mac],the pointer point to by mac. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, - * fail return the NULL. - * GaomingPan lonely-test:yes - * */ -t_clientinfo * get_client_info_by_mac(const char *mac) -{ - t_clientinfo *p; - p = first_client_info; - while(NULL != p){ - if(strcmp(mac,p->client_mac) == 0){ - return p; - } - p = p->next; - } - return NULL; -} - - - -/* @breif find the element from the client_info list by ip. - * @PARAMETER:[const char *ip],the pointer point to by ip. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, - * fail return the NULL. - * GaomingPan lonely-test:yes - * */ -t_clientinfo * get_client_info_by_ip(const char *ip) -{ - t_clientinfo *p; - p = first_client_info; - while(NULL != p){ - if(strcmp(ip,p->client_ip) == 0){ - return p; - } - p = p->next; - } - return NULL; -} - - -/* @breif find the element from the client_info list by ip. - * @ip,the pointer point to by client's ip. - * @@mac,the pointer point to by client's mac. - * GaomingPan lonely-test:yes - * */ -long get_online_time(const char *ip,const char *mac) -{ - t_client *ptr; - long online_time = 0; - - ptr = client_list_find(ip,mac); - - if(NULL!= ptr) - online_time = time(NULL) - ptr->record_time; - - return online_time; -} - - - -/*@breif get a flage string - * */ -char *get_client_auth_flag() -{ - return client_auth_flag; -} - - - -/*@breif set a flage string - * */ -void set_client_auth_flag() -{ - /* - * Rand a range number at [max,min]: - * rand()%(max - min + 1) + min - */ - int i; - for(i = 0;i<6;i++) - client_auth_flag[i] = rand()%(90 - 65 + 1) + 65; -} - - diff --git a/src/get_clientinfo.h b/src/get_clientinfo.h deleted file mode 100755 index 7d3d0c89..00000000 --- a/src/get_clientinfo.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * get_clientinfo.h - * - * Created on: Jul 13, 2015 - * Author: GaomingPan - */ - -#ifndef SRC_GET_CLIENTINFO_H_ -#define SRC_GET_CLIENTINFO_H_ - - -#define CLIENT_HOST_NAME_LEN 40 -#define CLIENT_MAC_ADDRESS_LEN 18 -#define CLIENT_IP_ADDRESS_LEN 16 - -#define UP_SPEED_FILE "/tmp/.client.up.speed" -#define DOWN_SPEED_FILE "/tmp/.client.down.speed" -#define HOST_NAME_FILE "/tmp/.hostname.txt" - - -/*@breif the sturct for client_info list - * */ -typedef struct _t_clientinfo{ - - char client_mac[CLIENT_MAC_ADDRESS_LEN]; - char client_ip[CLIENT_IP_ADDRESS_LEN]; - char host_name[CLIENT_HOST_NAME_LEN]; - int go_speed; - int come_speed; - struct _t_clientinfo *next; - -} t_clientinfo; - - -/* @breif get client host name,income speed and outgo speed,based on shell command. - * this functions take at least 1 second to run,because of execute the shell - * command have to sleep 1 second to collect client speed. - * @PARAMETER:void - * @RETURN_VALUE:zero is success,others is error. - * @Note: after this function be called and you get some clients information,you should - * call clean_client_info() function to clean up,just like the fopen() and fclose(). - * GaomingPan lonely-test:yes - * */ -int collect_client_info(); - - -/* @breif get unknown host name client's income speed and outgo speed,based on shell command. - * this functions take at least 1 second to run,because of execute the shell - * command have to sleep 1 second to collect client speed. - * @PARAMETER:[char *client_ip] the unknown host name client's ip - * [int *go_speed] the pointer for client's outgoing speed to store. - * [int *come_speed] the pointer for client's incoming speed to store. - * @RETURN_VALUE:zero is success,others is error. - * @Note: none - * GaomingPan lonely-test:yes - * */ -int get_unknown_client_speed(char *client_ip,int *go_speed,int *come_speed); - - - -/* @breif After the function collect_client_info() called,should call this function to - * clean up. - * @PARAMETER:void - * @RETURN_VALUE:void - * @Note: function collect_client_info() and this function just like the fopen() and fclose(). - * GaomingPan lonely-test:yes - * */ -void clean_client_info(); - - -/* @breif find the element from the client_info list by mac. - * @PARAMETER:[const char *mac],the pointer point to by mac. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, - * fail return the NULL. - * GaomingPan lonely-test:yes - * */ -t_clientinfo * get_client_info_by_mac(const char *mac); - - -/* @breif find the element from the client_info list by ip. - * @PARAMETER:[const char *ip],the pointer point to by ip. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, - * fail return the NULL. - * GaomingPan lonely-test:yes - * */ -t_clientinfo * get_client_info_by_ip(const char *ip); - - -/* @breif find the element from the client_info list by ip. - * @ip,the pointer point to by client's ip. - * @@mac,the pointer point to by client's mac. - * GaomingPan lonely-test:yes - * */ -long get_online_time(const char *ip,const char *mac); - - - -/*@breif get a flage string - * */ -char *get_client_auth_flag(); - - -/*@breif set a flage string - * */ -void set_client_auth_flag(); - - -#endif /* SRC_GET_CLIENTINFO_H_ */ - - - - diff --git a/src/get_devinfo.c b/src/get_devinfo.c deleted file mode 100755 index 87531f19..00000000 --- a/src/get_devinfo.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * get_devinfo.c - * - * Created on: Jul 9, 2015 - * Author: GaomingPan - */ -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include - - -#include "util.h" -#include "debug.h" -#include "conf.h" -#include "client_list.h" -#include "fw_iptables.h" -#include "../config.h" - - -#include "shell_command.h" -#include "get_devinfo.h" - -extern pthread_mutex_t client_list_mutex; - -static t_devinfo devinfo; -static t_cpuuse cpuuse; - -static char apmac[DEV_MAC_ADDR_LEN] = {0}; -static char apwanip[DEV_WAN_IP_LEN] = {0}; - -//extern char *dev_extern_iface; - -t_devinfo *get_devinfo(void) -{ - - memcpy(devinfo.gw_mac,apmac,DEV_MAC_ADDR_LEN); - -// if(get_apmac(devinfo.gw_mac)) -// { -// debug(LOG_ERR,"MyDEBUG:get get_apmac error!"); -// } - - if(get_devssid(devinfo.gw_ssid)) - { - debug(LOG_ERR,"ERR:get ssid error!"); - } - - if(get_dogversion(devinfo.dog_version)) - { - debug(LOG_ERR,"ERR: get_dogversion error!"); - } - - if(get_wanip(devinfo.wan_ip)) - { - debug(LOG_ERR,"ERR: get_wanip error!\n"); - } - - devinfo.cur_conn = get_curconn(); - devinfo.dev_conn = get_devconn(); - - devinfo.cpu_use = get_cpuuse(CPU_LOAD); - - if(get_wanbps(&devinfo.go_speed,&devinfo.come_speed)) - { - debug(LOG_ERR,"ERR: get_speed error!"); - } - - if(get_trafficCount(get_dev_extern_iface(),&devinfo.incoming,&devinfo.outgoing,NULL,NULL)) - { - debug(LOG_ERR,"ERR: get_traffic error!\n"); - } - - return &devinfo; -} - -/* @breif get wireless ssid,based on uci command. - * @PARAMETER: [char *ssid]:the char pointer for save the ssid. - * @RETURN_VALUE: zero is success,others is failed. - * GaomingPan lonely-test:yes - * */ -int get_devssid(char *ssid) -{ - FILE *fp; - memset(ssid,0,DEV_SSID_NAME_LEN); - fp = popen(CMD_GET_WIRELESS_SSID,"r"); - if(NULL == fp) - { - debug(LOG_ERR," get_devssid error!"); - sprintf(ssid,"%s","null"); - return -1; - } - fread(ssid,DEV_SSID_NAME_LEN,1,fp); - pclose(fp); - - int i = DEV_SSID_NAME_LEN - 1; - for(;i > 0;i--) - { - if(0x0a == ssid[i]) - { - ssid[i] = 0; - break; - } - } - return 0; -} - - -/* @breif get wifidog version - * @PARAMETER:[char *dogversion]:the char pointer for save the version - * @RETURN_VALUE:always return zero - * GaomingPan lonely-test:no - * */ -int get_dogversion(char *dogversion) -{ - memset(dogversion,0,DEV_DOG_VERSION_LEN); - sprintf(dogversion,"%s",VERSION); - return 0; -} - -/* @breif get wan interface ip,based on uci command. - * @PARAMETER:[char *wanip]:the char pointer for save the wan ip - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes - * */ -int get_wanip(char *wanip) -{ - FILE *fp; - - if(0 == strlen(apwanip)){ - fp = popen(CMD_GET_WAN_IP,"r"); - if(NULL == fp){ - debug(LOG_ERR,"get_wanip error!"); - if(NULL != wanip) - sprintf(wanip,"%s","0.0.0.0"); - return -1; - } - fread(apwanip,DEV_WAN_IP_LEN - 1,1,fp); - pclose(fp); - - int i = DEV_WAN_IP_LEN - 1; - for(;i >= 0;i--){ - if(0x0a == apwanip[i]){ - apwanip[i] = 0; - break; - } - } - - }else{ - if(NULL != wanip) - sprintf(wanip,"%s",apwanip); - } - - return 0; -} - -/** -int get_wanip(char *wanip) -{ - FILE *fp; - memset(wanip,0,DEV_WAN_IP_LEN); - fp = popen(CMD_GET_WAN_IP,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"get_wanip error!"); - sprintf(wanip,"%s","0.0.0.0"); - return -1; - } - fread(wanip,DEV_WAN_IP_LEN - 1,1,fp); - pclose(fp); - - int i = DEV_WAN_IP_LEN - 1; - for(;i > 0;i--) - { - if(0x0a == wanip[i]) - { - wanip[i] = 0; - break; - } - } - - return 0; -} -*****/ - - -/* @breif get ap mac address,based on uci command. - * @PARAMETER:[char *apmac]:the char pointer for save the mac - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes - * */ -int get_apmac(char *mac) -{ - FILE *fp; - int i; - memset(apmac,0,DEV_MAC_ADDR_LEN); - - fp = popen(CMD_GET_AP_MAC,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"get_apmac() popen error."); - sprintf(apmac,"%s","00-00-00-00-00-00"); - return -1; - } - fread(apmac,DEV_MAC_ADDR_LEN - 1,1,fp); - pclose(fp); - - for(i = 0; i< DEV_MAC_ADDR_LEN; i++) - { - if(':' == apmac[i]) - apmac[i] = '-'; - if(apmac[i] >= 'A' && apmac[i] <= 'F') - apmac[i] += apmac[i] + 0x20; - if(0x0a == apmac[i]) - apmac[i] = 0; - } - - if(NULL != mac) - mac = apmac; - - return 0; -} - - -/* @breif get number of client - * @PARAMETER:none - * @RETURN_VALUE:the number of current connected client - * GaomingPan lonely-test:no - * */ -int get_curconn(void) -{ - int count; - t_client *first; - - LOCK_CLIENT_LIST(); - - first = client_get_first_client(); - if (first == NULL) { - count = 0; - } else { - count = 1; - while (first->next != NULL) { - first = first->next; - count++; - } - } - - UNLOCK_CLIENT_LIST(); - - return count; -} - - -/* @breif get number of client who connect to the device - * @PARAMETER:none - * @RETURN_VALUE:the number of connected client - * GaomingPan lonely-test:no - * */ - -int get_devconn(void) -{ - FILE *fp; - char info_buf[512], - num_buf[10]; - char *ptr = NULL; - s_config *conf = config_get_config(); - - fp = fopen(IFACE_CONN_FILE,"r"); - if(NULL == fp){ - debug(LOG_ERR,"ERROR fopen error, at get_devconn()."); - return -1; - } - if(0 == fread(info_buf,1,512,fp)){ - fclose(fp); - return 0; - } - fclose(fp); - ptr = strstr(info_buf,conf->gw_interface); - if(NULL == ptr) - return 0; - sscanf(ptr,"%s* %d",num_buf); - return (atoi(num_buf)); -} - -/**** -int get_devconn(void) -{ - FILE *fp; - char shell_cmd[1024], - buf[10]; - s_config *conf = config_get_config(); - memset(buf,0,10); - - sprintf(shell_cmd,"cat /proc/net/arp|grep -e \"0x2\"|grep -e \"%s\" | awk \'!a[$4]++\'> /tmp/.devconn;awk \'END{print NR}\' /tmp/.devconn",conf->gw_interface); - //fp = popen("awk \'END{print NR}\' $(uci get dhcp.@dnsmasq[0].leasefile)","r"); - fp = popen(shell_cmd,"r"); - - if(NULL == fp) - { - debug(LOG_ERR,"ERROR popen error, at get_devconn()."); - return -1; - } - if(0 == fread(buf,1,10,fp)) - { - pclose(fp); - return 0; - } - pclose(fp); - return (atoi(buf)); -} -********/ - -/* @breif get cpu use infomation,based on shell command. - * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD - * @RETURN_VALUE:the number of current percent of CPU use. - * GaomingPan lonely-test:yes - * */ - -int get_cpuuse(int type) -{ - int use, - i; - FILE *fp; - - for(i = 0;i < 15;i++) - memset(cpuuse.use_info[i],0,8); - - fp = fopen(CPU_USE_INFO_FILE,"r"); - if(NULL == fp){ - debug(LOG_ERR,"fopen error,at get_cpuuse(...) !"); - return -1; - } - fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", - cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], - cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], - cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], - cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], - cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] - ); - fclose(fp); - -// for(;i<15;i++) -// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); - - switch(type){ - case CPU_USER: - cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; - use = atoi(cpuuse.use_info[CPU_USER]); - break; - case CPU_SYS: - cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; - use = atoi(cpuuse.use_info[CPU_SYS]); - break; - case CPU_NIC: - cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; - use = atoi(cpuuse.use_info[CPU_NIC]); - break; - case CPU_IDLE: - cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; - use = atoi(cpuuse.use_info[CPU_IDLE]); - break; - case CPU_LOAD: - cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; - use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); - break; - case CPU_IO: - cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; - use = atoi(cpuuse.use_info[CPU_IO]); - break; - case CPU_IRQ: - cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; - use = atoi(cpuuse.use_info[CPU_IRQ]); - break; - case CPU_SIRQ: - cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; - use = atoi(cpuuse.use_info[CPU_SIRQ]); - break; - default: - use = -1; - break; - } - - return use; -} - -/***** -int get_cpuuse(int type) -{ - char num[4]; - int use, - i; - FILE *fp; - - memset(num,0,4); - for(i = 0;i < 15;i++) - memset(cpuuse.use_info[i],0,8); - - fp = popen(CMD_GET_CPU_USE,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"get_cpuuse error!"); - return -1; - } - fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", - cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], - cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], - cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], - cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], - cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] - ); - pclose(fp); - -// for(;i<15;i++) -// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); - - switch(type){ - case CPU_USER: - cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; - use = atoi(cpuuse.use_info[CPU_USER]); - break; - case CPU_SYS: - cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; - use = atoi(cpuuse.use_info[CPU_SYS]); - break; - case CPU_NIC: - cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; - use = atoi(cpuuse.use_info[CPU_NIC]); - break; - case CPU_IDLE: - cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; - use = atoi(cpuuse.use_info[CPU_IDLE]); - break; - case CPU_LOAD: - cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; - use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); - break; - case CPU_IO: - cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; - use = atoi(cpuuse.use_info[CPU_IO]); - break; - case CPU_IRQ: - cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; - use = atoi(cpuuse.use_info[CPU_IRQ]); - break; - case CPU_SIRQ: - cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; - use = atoi(cpuuse.use_info[CPU_SIRQ]); - break; - default: - use = -1; - break; - } - - return use; -} -********************************************/ - -/* @breif get wan interface traffic. - * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. - * @RETURN_VALUE:zero is success,others is error. - * GaomingPan lonely-test:yes - * */ - -int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate) -{ - FILE *fp; - char *iface, - *ptr; - char data[4096]; - struct stat statbuf; - int data_size; - int ret; - - unsigned int rx,tx; - unsigned long long out,in; - - - iface = iface_name; - if(NULL == iface){ - out = 0L; - in = 0L; - debug(LOG_ERR,"at get_trafficCount(...),ifce_name is NULL."); - ret = -1; - goto ERR; - } - - stat(IFACE_DATA_FILE,&statbuf); - data_size = statbuf.st_size; - - fp = fopen(IFACE_DATA_FILE,"r"); - if(NULL == fp){ - out = 0L; - in = 0L; - debug(LOG_ERR,"at get_trafficCount(...), fopen the IFACE_DATA_FILE error."); - ret = -2; - goto ERR; - } - fread(data,1,data_size,fp); - fclose(fp); - - ptr = strstr(data,iface); - if(NULL == ptr){ - out = 0L; - in = 0L; - debug(LOG_ERR,"at get_trafficCount(...), strstr(..) get iface position error."); - ret = -3; - goto ERR; - } - ret = sscanf(ptr,"%*s %llu %llu %u %u",&in,&out,&rx,&tx); - if(ret != 4) - goto ERR; - - if(NULL != outgo) - *outgo = out; - if(NULL != income) - *income = in; - if(NULL != rx_rate) - *rx_rate = rx; - if(NULL != tx_rate) - *tx_rate = tx; - - return 0; - -ERR: - if(NULL != outgo) - *outgo = 0; - if(NULL != income) - *income = 0; - if(NULL != rx_rate) - *rx_rate = 0; - if(NULL != tx_rate) - *tx_rate = 0; - - return ret; -} - -/**************************************************** -int get_trafficCount(long *outgo,long *income) -{ - FILE *fp; - char ifname[DEV_IFNAME_LEN]; - memset(ifname,0,DEV_IFNAME_LEN); - - fp = popen(CMD_GET_WAN_IFNAME,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"get_trafficCount() popen error."); - *outgo = -1L; - *income = -1L; - return -1; - } - fread(ifname,DEV_IFNAME_LEN-1,1,fp); - pclose(fp); - - int j; - for(j = 0;j < DEV_IFNAME_LEN;j++) - { - if(0x0a == ifname[j]) - { - ifname[j] = 0; - break; - } - } - - int nDevLen = strlen(ifname); - if (nDevLen < 1 || nDevLen > DEV_IFNAME_LEN - 1) - { - debug(LOG_ERR,"get_trafficCount(),dev length too long."); - *outgo = -1L; - *income = -1L; - return -2; - } - int fd = open("/proc/net/dev", O_RDONLY | O_EXCL); - if (-1 == fd) - { - debug(LOG_ERR,"get_trafficCount(),open /proc/net/dev failed ,maybe file not exists!"); - *outgo = -1L; - *income = -1L; - return -3; - } - - char buf[1024*2]; - lseek(fd, 0L, SEEK_SET); - int nBytes = read(fd, buf, sizeof(buf)-1); - close(fd); - if (-1 == nBytes) - { - debug(LOG_ERR,"get_trafficCount(),read bytes error."); - *outgo = -1L; - *income = -1L; - return -4; - } - buf[nBytes] = '\0'; - - //è¿”å›ç¬¬ä¸€æ¬¡æŒ‡å‘ifnameä½ç½®ç„指针 - char* pDev = strstr(buf, ifname); - if (NULL == pDev) - { - debug(LOG_ERR,"get_trafficCount(),don't find dev %s", ifname); - *outgo = -1L; - *income = -1L; - return -5; - } - char *p; - char *ifconfig_value; - int i = 0; - long rx2_tx10[2]; - /*å»é™¤ç©ºæ ¼ï¼Œåˆ¶è¡¨ç¬¦ï¼Œæ¢è¡Œç¬¦ç­‰ä¸éœ€è¦ç„字段* - for (p = strtok(pDev, " \t\r\n"); p; p = strtok(NULL, " \t\r\n")) - { - i++; - ifconfig_value = (char*)malloc(30); - if(NULL == ifconfig_value) - { - debug(LOG_ERR,"get_trafficCount(),malloc error."); - *outgo = -1L; - *income = -1L; - return -6; - } - strcpy(ifconfig_value, p); - /*得到ç„字符串中ç„ç¬¬äºŒä¸ªå­—æ®µæ˜¯æ¥æ”¶æµé‡* - if(i == 2) - { - rx2_tx10[0] = atoll(ifconfig_value); - } - /*得到ç„字符串中ç„第å个字段是å‘逿µé‡* - if(i == 10) - { - rx2_tx10[1] = atoll(ifconfig_value); - break; - } - free(ifconfig_value); - } - free(ifconfig_value); - - *income = rx2_tx10[0]; - *outgo = rx2_tx10[1]; - - return 0; -} -******************************************/ - -/* @breif get wan interface speed,based on shell command. - * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. - * @RETURN_VALUE:zero is success,others is error. - * @NOTE: this function will take a one second to wait data update,so,it's just waste time. - * GaomingPan lonely-test:yes - * */ -int get_wanbps(unsigned int *go,unsigned int *come) -{ - unsigned int tx,rx; - int ret = 0; - char *iface; - - iface = get_dev_extern_iface();//config_get_config()->external_interface; - if(NULL == iface){ - debug(LOG_ERR,"at get_trafficCount(...), wifidog can't find the external_interface."); - } - - ret = get_trafficCount(iface,NULL,NULL,&rx,&tx); - if(ret != 0){ - debug(LOG_ERR,"at get_wanbps(), get_trafficCount() error return code = %d",ret); - if(NULL != go) - *go = 0; - if(NULL != come) - *come = 0; - return -1; - } - - if(NULL != go) - *go = tx; - if(NULL != come) - *come = rx; - - return 0; -} diff --git a/src/get_devinfo.h b/src/get_devinfo.h deleted file mode 100755 index 7fb09fae..00000000 --- a/src/get_devinfo.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * get_devinfo.h - * - * Created on: Jul 9, 2015 - * Author: GaomingPan - */ - -#ifndef SRC_GET_DEVINFO_H_ -#define SRC_GET_DEVINFO_H_ - -#define DEV_MAC_ADDR_LEN 18 -#define DEV_SSID_NAME_LEN 20 -#define DEV_DOG_VERSION_LEN 20 -#define DEV_WAN_IP_LEN 16 -#define DEV_IFNAME_LEN 11 - -#define IFACE_DATA_FILE "/tmp/.iface-data" -#define IFACE_CONN_FILE "/tmp/.iface_conn" -#define CPU_USE_INFO_FILE "/tmp/.cpu_use_info" - -#define CPU_USER 1 -#define CPU_SYS 3 -#define CPU_NIC 5 -#define CPU_IDLE 7 -#define CPU_IO 9 -#define CPU_IRQ 11 -#define CPU_SIRQ 13 -#define CPU_LOAD 16 - - - - -/*@ breif a struct hold information for ap*/ -typedef struct _t_devinfo{ - char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address - char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid - char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. - char wan_ip[DEV_WAN_IP_LEN]; // ap's wan interface ip - int cur_conn; // number of current connection client - int dev_conn; // number of connection in the device,maybe some has no authentication. - int cpu_use; // percent of use CPU - unsigned int go_speed; // wan interface go out speed - unsigned int come_speed; // wan interface come in speed - unsigned long long incoming; // wan interface incoming bytes - unsigned long long outgoing; // wan interface outgoing bytes -}t_devinfo; - - - -typedef struct _t_cpuuse{ - char use_info[15][8]; -}t_cpuuse; - - -t_devinfo *get_devinfo(void); - -/* @breif get wireless ssid,based on uci command. - * @PARAMETER: [char *ssid]:the char pointer for save the ssid. - * @RETURN_VALUE: zero is success,others is failed. - * GaomingPan lonely-test:yes - * */ -int get_devssid(char *ssid); - -/* @breif get wifidog version - * @PARAMETER:[char *dogversion]:the char pointer for save the version - * @RETURN_VALUE:always return zero - * GaomingPan lonely-test:no - * */ -int get_dogversion(char *dogversion); - - -/* @breif get wan interface ip,based on uci command. - * @PARAMETER:[char *wanip]:the char pointer for save the wan ip - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes - * */ -int get_wanip(char *wanip); - -/* @breif get ap mac address,based on uci command. - * @PARAMETER:[char *apmac]:the char pointer for save the mac - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes - * */ -int get_apmac(char *apmac); - -/* @breif get number of client - * @PARAMETER:none - * @RETURN_VALUE:the number of current connected client - * GaomingPan lonely-test:no - * */ -int get_curconn(void); - - -/* @breif get number of client who connect to the device - * @PARAMETER:none - * @RETURN_VALUE:the number of connected client - * GaomingPan lonely-test:no - * */ -int get_devconn(void); - -/* @breif get cpu use infomation,based on shell command - * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD - * @RETURN_VALUE:the number of current percent of CPU use. - * GaomingPan lonely-test:yes - * */ -int get_cpuuse(int type); - - -/* @breif get wan interface speed,based on shell command. - * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. - * @RETURN_VALUE:zero is success,others is error. - * GaomingPan lonely-test:yes - * */ -int get_wanbps(unsigned int *go,unsigned int *come); - - -/* @breif get wan interface traffic,based on shell command. - * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. - * @RETURN_VALUE:zero is success,others is error. - * GaomingPan lonely-test:yes - * */ -int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate); - - -#endif /* SRC_GET_DEVINFO_H_ */ diff --git a/src/get_remote_shell.c b/src/get_remote_shell.c deleted file mode 100755 index 5d67787a..00000000 --- a/src/get_remote_shell.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * get_remote_shell.c - * - * Created on: Jul 14, 2015 - * Author: GaomingPan - */ - - -#include -#include -#include -#include - -#include "debug.h" - -#include "get_remote_shell.h" - - - -static char remote_shell_cmd[ REMOTE_SHELL_COMMAND_LEN ]; - -static char info_http_url[128], - info_rmflag[20], - normal_http_url[128], - normal_rmflag[20]; - - -int init_post_http_url_config(void) -{ - memset(info_http_url,0,128); - memset(info_rmflag,0,20); - memset(normal_http_url,0,128); - memset(normal_rmflag,0,20); - - char buf[128]; - FILE *fp; - memset(buf,0,128); - - fp = popen("uci get dog_post_conf.url.info_url","r"); - if(NULL == fp) - { - return -1; - } - fread(buf,1,128,fp); - pclose(fp); - sprintf(info_http_url,"%s",buf); - memset(buf,0,128); - - fp = popen("uci get dog_post_conf.url.normal_url","r"); - if(NULL == fp) - { - return -2; - } - fread(buf,1,128,fp); - pclose(fp); - - sprintf(normal_http_url,"%s",buf); - memset(buf,0,128); - - fp = popen("uci get dog_post_conf.rmflag.info_rmflag","r"); - if(NULL == fp) - { - return -3; - } - fread(buf,1,128,fp); - pclose(fp); - - sprintf(info_rmflag,"%s",buf); - memset(buf,0,128); - - fp = popen("uci get dog_post_conf.rmflag.normal_rmflag","r"); - if(NULL == fp) - { - return -4; - } - fread(buf,1,128,fp); - pclose(fp); - sprintf(normal_rmflag,"%s",buf); - - debug(LOG_INFO,"init result :info_url:%s;info_rmflag:%s;normal_url:%s;normal_rmflag:%s", \ - info_http_url,info_rmflag, \ - normal_http_url,normal_rmflag - ); - - return 0; -} - - - - -int post_get_info_execut_output(char *cmd_output_path) -{ - char output[MAX_CMD_EXECUT_OUT_LEN]; - FILE *fp; - sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); - //printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); - fp = popen(output,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); - //printf("ERROR: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); - return -1; - } - pclose(fp); - return 0; -} - - - -int post_normal_execut_output(char *gw_id, char *cmd_id) -{ - char output[MAX_CMD_EXECUT_OUT_LEN]; - FILE *fp; - - sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"type\\\":\\\"default\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ - gw_id,cmd_id,BUILE_NORMAL_CMD_RESULT_SHELL,normal_http_url,normal_rmflag); - debug(LOG_INFO,"output_normal:--> %s",output); - fp = popen(output,"r"); - if(NULL == fp) - { - debug(LOG_ERR,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); - //printf("ERROR: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); - return -1; - } - pclose(fp); - return 0; -} - - - - - - -char *get_shell_command(char *cmdptr) -{ - - if(NULL == cmdptr) - { - debug(LOG_ERR,"REMOTE shell: remote shell command is null."); - return NULL; - } - memset(remote_shell_cmd,0,REMOTE_SHELL_COMMAND_LEN); - sprintf(remote_shell_cmd,"%s",cmdptr); - - return remote_shell_cmd; -} - - - - -int excute_shell_command(char *gw_id,char *shellcmd) -{ - char cmd_id[20], - get_info_cmd[30], - normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; - char *pos_id, - *pos_cmd; - int is_get_info = 0; - FILE *fp; - char cmdresult[1024]; - - memset(cmdresult,0,1024); - memset(cmd_id,0,20); - memset(get_info_cmd,0,30); - - pos_id = shellcmd; - pos_cmd = strstr(shellcmd,"|"); - - snprintf(cmd_id,++pos_cmd - pos_id - 1,"%s",++pos_id); - - pos_cmd = ++pos_cmd; - - snprintf(get_info_cmd,30,"%s",pos_cmd); - - is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); - - debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); - - if(0 == is_get_info) - { - sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id); - fp = popen(get_info_cmd,"r"); - } - else - { - sprintf(normal_cmd,"RESULT=\"$(%s)\";echo \"$RESULT\" > "NORMAL_CMD_RESULT_FILE,pos_cmd); - fp = popen(normal_cmd,"r"); - } - - debug(LOG_INFO,"pos_cmd:%s",pos_cmd); - - if(NULL == fp) - { - debug(LOG_ERR,"excute_shell_command popen error...."); - //printf("excute_shell_command popen error....\n"); - return -1; - } - //fread(cmdresult,1024,1,fp); - pclose(fp); - //printf("\n\ncmd result:\n %s\n\n",cmdresult); - - if(0 == is_get_info) - { - post_get_info_execut_output(SETTINGS_INFO_FILE); - - }else{ - - post_normal_execut_output(gw_id,cmd_id); - } - return 0; -} - - diff --git a/src/get_remote_shell.h b/src/get_remote_shell.h deleted file mode 100755 index 7c2f4dc9..00000000 --- a/src/get_remote_shell.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * get_remote_shell.h - * - * Created on: Jul 14, 2015 - * Author: GaomingPan - */ - -#ifndef SRC_GET_REMOTE_SHELL_H_ -#define SRC_GET_REMOTE_SHELL_H_ - -#define GET_SETTINGS_INFO_CMD "GET_settings" - -#define SETTINGS_INFO_FILE "/tmp/routersettings" - -#define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" - -#define BUILE_NORMAL_CMD_RESULT_SHELL "result=\"\";while read line;do result=\"\\\"$result$line\\\",\";done < "NORMAL_CMD_RESULT_FILE";result=${result%,};echo $result" - - -#define REMOTE_SHELL_COMMAND_LEN 1024 -#define MAX_CMD_EXECUT_OUT_LEN 4096 - -char *get_shell_command(char *cmdptr); - -int excute_shell_command(char *gw_id,char *shellcmd); - -int post_get_info_execut_output(char *cmd_output_path); - -int post_normal_execut_output(char *gw_id, char *cmd_id); - -int init_post_http_url_config(void); - -#endif /* SRC_GET_REMOTE_SHELL_H_ */ - - diff --git a/src/http.c b/src/http.c index 4b8e1080..ea2c7316 100644 --- a/src/http.c +++ b/src/http.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 ts=4 sts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -30,11 +27,7 @@ @author Copyright (C) 2007 David Bird */ -<<<<<<< HEAD /* Note that libcs other than GLIBC also use this macro to enable vasprintf */ -======= - ->>>>>>> FETCH_HEAD #define _GNU_SOURCE #include @@ -56,25 +49,15 @@ #include "auth.h" #include "firewall.h" #include "http.h" -<<<<<<< HEAD #include "client_list.h" #include "common.h" #include "centralserver.h" #include "util.h" #include "wd_util.h" -======= -#include "httpd.h" -#include "client_list.h" -#include "common.h" -#include "centralserver.h" - -#include "util.h" ->>>>>>> FETCH_HEAD #include "../config.h" -<<<<<<< HEAD /** The 404 handler is also responsible for redirecting to the auth server */ void http_callback_404(httpd * webserver, request * r, int error_code) @@ -217,128 +200,10 @@ http_callback_status(httpd * webserver, request * r) free(status); } -======= - -extern pthread_mutex_t client_list_mutex; - -/** The 404 handler is also responsible for redirecting to the auth server */ -void -http_callback_404(httpd *webserver, request *r) -{ - char tmp_url[MAX_BUF], - *url, - *mac; - s_config *config = config_get_config(); - t_auth_serv *auth_server = get_auth_server(); - - memset(tmp_url, 0, sizeof(tmp_url)); - /* - * XXX Note the code below assumes that the client's request is a plain - * http request to a standard port. At any rate, this handler is called only - * if the internet/auth server is down so it's not a huge loss, but still. - */ - snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s", - r->request.host, - r->request.path, - r->request.query[0] ? "?" : "", - r->request.query); - url = httpdUrlEncode(tmp_url); - - if (!is_online()) { - /* The internet connection is down at the moment - apologize and do not redirect anywhere */ - char * buf; - safe_asprintf(&buf, - "

We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.

" - "

If at all possible, please notify the owners of this hotspot that the internet connection is out of service.

" - "

The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.

" - "

In a while please click here to try your request again.

", tmp_url); - - send_http_page(r, "Uh oh! Internet access unavailable!", buf); - free(buf); - debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr); - } - else if (!is_auth_online()) { - /* The auth server is down at the moment - apologize and do not redirect anywhere */ - char * buf; - safe_asprintf(&buf, - "

We apologize, but it seems that we are currently unable to re-direct you to the login screen.

" - "

The maintainers of this network are aware of this disruption. We hope that this situation will be resolved soon.

" - "

In a couple of minutes please click here to try your request again.

", tmp_url); - - send_http_page(r, "Uh oh! Login screen unavailable!", buf); - free(buf); - debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr); - } - else { - /* Re-direct them to auth server */ - char *urlFragment; - - if (!(mac = arp_get(r->clientAddr))) { - /* We could not get their MAC address */ - debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request", r->clientAddr); - safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s", - auth_server->authserv_login_script_path_fragment, - config->gw_address, - config->gw_port, - config->gw_id, - url); - } else { - debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac); - safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s", - auth_server->authserv_login_script_path_fragment, - config->gw_address, - config->gw_port, - config->gw_id, - mac, - url); - } - - debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url); - http_send_redirect_to_auth(r, urlFragment, "Redirect to login page"); - free(urlFragment); - } - free(url); -} - -void -http_callback_wifidog(httpd *webserver, request *r) -{ - send_http_page(r, "WiFiDog", "Please use the menu to navigate the features of this WiFiDog installation."); -} - -void -http_callback_about(httpd *webserver, request *r) -{ - send_http_page(r, "About WiFiDog", "This is WiFiDog version " VERSION ""); -} - -void -http_callback_status(httpd *webserver, request *r) -{ - const s_config *config = config_get_config(); - char * status = NULL; - char *buf; - - if (config->httpdusername && - (strcmp(config->httpdusername, r->request.authUser) || - strcmp(config->httpdpassword, r->request.authPassword))) { - debug(LOG_INFO, "Status page requested, forcing authentication"); - httpdForceAuthenticate(r, config->httpdrealm); - return; - } - - status = get_status_text(); - safe_asprintf(&buf, "
%s
", status); - send_http_page(r, "WiFiDog Status", buf); - free(buf); - free(status); -} ->>>>>>> FETCH_HEAD /** @brief Convenience function to redirect the web browser to the auth server * @param r The request * @param urlFragment The end of the auth server URL to redirect to (the part after path) * @param text The text to include in the redirect header ant the mnual redirect title */ -<<<<<<< HEAD void http_send_redirect_to_auth(request * r, const char *urlFragment, const char *text) { @@ -359,39 +224,12 @@ http_send_redirect_to_auth(request * r, const char *urlFragment, const char *tex protocol, auth_server->authserv_hostname, port, auth_server->authserv_path, urlFragment); http_send_redirect(r, url, text); free(url); -======= -void http_send_redirect_to_auth(request *r, const char *urlFragment, const char *text) -{ - char *protocol = NULL; - int port = 80; - t_auth_serv *auth_server = get_auth_server(); - - if (auth_server->authserv_use_ssl) { - protocol = "https"; - port = auth_server->authserv_ssl_port; - } else { - protocol = "http"; - port = auth_server->authserv_http_port; - } - - char *url = NULL; - safe_asprintf(&url, "%s://%s:%d%s%s", - protocol, - auth_server->authserv_hostname, - port, - auth_server->authserv_path, - urlFragment - ); - http_send_redirect(r, url, text); - free(url); ->>>>>>> FETCH_HEAD } /** @brief Sends a redirect to the web browser * @param r The request * @param url The url to redirect to * @param text The text to include in the redirect header and the manual redirect link title. NULL is acceptable */ -<<<<<<< HEAD void http_send_redirect(request * r, const char *url, const char *text) { @@ -496,133 +334,26 @@ void send_http_page(request * r, const char *title, const char *message) { s_config *config = config_get_config(); -======= -void http_send_redirect(request *r, const char *url, const char *text) -{ - char *message = NULL; - char *header = NULL; - char *response = NULL; - /* Re-direct them to auth server */ - debug(LOG_DEBUG, "Redirecting client browser to %s", url); - safe_asprintf(&header, "Location: %s", url); - safe_asprintf(&response, "302 %s\n", text ? text : "Redirecting"); - httpdSetResponse(r, response); - httpdAddHeader(r, header); - free(response); - free(header); - safe_asprintf(&message, "Please click here.", url); - send_http_page(r, text ? text : "Redirection to message", message); - free(message); -} - -void -http_callback_auth(httpd *webserver, request *r) -{ - t_client *client; - httpVar * token; - char *mac; - httpVar *logout = httpdGetVariableByName(r, "logout"); - if ((token = httpdGetVariableByName(r, "token"))) { - /* They supplied variable "token" */ - if (!(mac = arp_get(r->clientAddr))) { - /* We could not get their MAC address */ - debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr); - send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address"); - } else { - /* We have their MAC address */ - - LOCK_CLIENT_LIST(); - - if ((client = client_list_find(r->clientAddr, mac)) == NULL) { - debug(LOG_DEBUG, "New client for %s", r->clientAddr); - client_list_append(r->clientAddr, mac, token->value); - } else if (logout) { - t_authresponse authresponse; - s_config *config = config_get_config(); - unsigned long long incoming = client->counters.incoming; - unsigned long long outgoing = client->counters.outgoing; - char *ip = safe_strdup(client->ip); - char *urlFragment = NULL; - t_auth_serv *auth_server = get_auth_server(); - - fw_deny(client->ip, client->mac, client->fw_connection_state); - client_list_delete(client); - debug(LOG_DEBUG, "Got logout from %s", client->ip); - - /* Advertise the logout if we have an auth server */ - if (config->auth_servers != NULL) { - UNLOCK_CLIENT_LIST(); - auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token->value, - incoming, outgoing); - LOCK_CLIENT_LIST(); - - /* Re-direct them to auth server */ - debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s" - "- redirecting them to logout message", client->ip, client->mac, client->token); - safe_asprintf(&urlFragment, "%smessage=%s", - auth_server->authserv_msg_script_path_fragment, - GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT - ); - http_send_redirect_to_auth(r, urlFragment, "Redirect to logout message"); - free(urlFragment); - } - free(ip); - } - else { - debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip); - } - UNLOCK_CLIENT_LIST(); - if (!logout) { - authenticate_client(r); - } - free(mac); - } - } else { - /* They did not supply variable "token" */ - send_http_page(r, "WiFiDog error", "Invalid token"); - } -} - -void send_http_page(request *r, const char *title, const char* message) -{ - s_config *config = config_get_config(); ->>>>>>> FETCH_HEAD char *buffer; struct stat stat_info; int fd; ssize_t written; -<<<<<<< HEAD fd = open(config->htmlmsgfile, O_RDONLY); if (fd == -1) { -======= - fd=open(config->htmlmsgfile, O_RDONLY); - if (fd==-1) { ->>>>>>> FETCH_HEAD debug(LOG_CRIT, "Failed to open HTML message file %s: %s", config->htmlmsgfile, strerror(errno)); return; } -<<<<<<< HEAD if (fstat(fd, &stat_info) == -1) { -======= - if (fstat(fd, &stat_info)==-1) { ->>>>>>> FETCH_HEAD debug(LOG_CRIT, "Failed to stat HTML message file: %s", strerror(errno)); close(fd); return; } -<<<<<<< HEAD // Cast from long to unsigned int buffer = (char *)safe_malloc((size_t) stat_info.st_size + 1); written = read(fd, buffer, (size_t) stat_info.st_size); if (written == -1) { -======= - - buffer=(char*)safe_malloc(stat_info.st_size+1); - written=read(fd, buffer, stat_info.st_size); - if (written==-1) { ->>>>>>> FETCH_HEAD debug(LOG_CRIT, "Failed to read HTML message file: %s", strerror(errno)); free(buffer); close(fd); @@ -630,18 +361,10 @@ void send_http_page(request *r, const char *title, const char* message) } close(fd); -<<<<<<< HEAD buffer[written] = 0; -======= - buffer[written]=0; ->>>>>>> FETCH_HEAD httpdAddVariable(r, "title", title); httpdAddVariable(r, "message", message); httpdAddVariable(r, "nodeID", config->gw_id); httpdOutput(r, buffer); free(buffer); } -<<<<<<< HEAD -======= - ->>>>>>> FETCH_HEAD diff --git a/src/http.h b/src/http.h index b7a0b35e..51cb04c1 100644 --- a/src/http.h +++ b/src/http.h @@ -30,7 +30,6 @@ #include "httpd.h" /**@brief Callback for libhttpd, main entry point for captive portal */ -<<<<<<< HEAD void http_callback_404(httpd *, request *, int); /**@brief Callback for libhttpd */ void http_callback_wifidog(httpd *, request *); @@ -50,23 +49,4 @@ void send_http_page(request *, const char *, const char* ); void http_send_redirect(request *, const char *, const char *); /** @brief Convenience function to redirect the web browser to the authe server */ void http_send_redirect_to_auth(request *, const char *, const char *); -======= -void http_callback_404(httpd *webserver, request *r); -/**@brief Callback for libhttpd */ -void http_callback_wifidog(httpd *webserver, request *r); -/**@brief Callback for libhttpd */ -void http_callback_about(httpd *webserver, request *r); -/**@brief Callback for libhttpd */ -void http_callback_status(httpd *webserver, request *r); -/**@brief Callback for libhttpd, main entry point post login for auth confirmation */ -void http_callback_auth(httpd *webserver, request *r); - -/** @brief Sends a HTML page to web browser */ -void send_http_page(request *r, const char *title, const char* message); - -/** @brief Sends a redirect to the web browser */ -void http_send_redirect(request *r, const char *url, const char *text); -/** @brief Convenience function to redirect the web browser to the authe server */ -void http_send_redirect_to_auth(request *r, const char *urlFragment, const char *text); ->>>>>>> FETCH_HEAD #endif /* _HTTP_H_ */ diff --git a/src/ping_thread.c b/src/ping_thread.c index 1c5bc2f6..3475379e 100644 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set sw=4 ts=4 sts=4 et : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -55,7 +52,6 @@ #include "ping_thread.h" #include "util.h" #include "centralserver.h" -<<<<<<< HEAD #include "firewall.h" #include "gateway.h" #include "simple_http.h" @@ -91,48 +87,6 @@ thread_ping(void *arg) /* No longer needs to be locked */ pthread_mutex_unlock(&cond_mutex); } -======= - -/*@breif get device info. - * GaomingPan*/ -#include "get_devinfo.h" -#include "get_remote_shell.h" -#include "device_key.h" - -static void ping(void); - -extern time_t started_time; - -/** Launches a thread that periodically checks in with the wifidog auth server to perform heartbeat function. -@param arg NULL -@todo This thread loops infinitely, need a watchdog to verify that it is still running? -*/ -void -thread_ping(void *arg) -{ - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; - struct timespec timeout; - - while (1) { - /* Make sure we check the servers at the very begining */ - debug(LOG_DEBUG, "Running ping()"); - ping(); - - /* Sleep for config.checkinterval seconds... */ - timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; - timeout.tv_nsec = 0; - - /* Mutex must be locked for pthread_cond_timedwait... */ - pthread_mutex_lock(&cond_mutex); - - /* Thread safe "sleep" */ - pthread_cond_timedwait(&cond, &cond_mutex, &timeout); - - /* No longer needs to be locked */ - pthread_mutex_unlock(&cond_mutex); - } ->>>>>>> FETCH_HEAD } /** @internal @@ -141,7 +95,6 @@ thread_ping(void *arg) static void ping(void) { -<<<<<<< HEAD char request[MAX_BUF]; FILE *fh; int sockfd; @@ -250,193 +203,4 @@ ping(void) free(res); } return; -======= - /*@breif device info struct - * GaomingPan - * */ - t_devinfo *infoptr; - char *cmdptr; - - ssize_t numbytes; - size_t totalbytes; - int sockfd, nfds, done; - char request[MAX_BUF]; - fd_set readfds; - struct timeval timeout; - FILE * fh; - unsigned long int sys_uptime = 0; - unsigned int sys_memfree = 0; - float sys_load = 0; - t_auth_serv *auth_server = NULL; - auth_server = get_auth_server(); - - debug(LOG_DEBUG, "Entering ping()"); - - /* - * The ping thread does not really try to see if the auth server is actually - * working. Merely that there is a web server listening at the port. And that - * is done by connect_auth_server() internally. - */ - sockfd = connect_auth_server(); - if (sockfd == -1) { - /* - * No auth servers for me to talk to - */ - return; - } - - /* - * Populate uptime, memfree and load - */ - if ((fh = fopen("/proc/uptime", "r"))) { - if(fscanf(fh, "%lu", &sys_uptime) != 1) - debug(LOG_CRIT, "Failed to read uptime"); - - fclose(fh); - } - if ((fh = fopen("/proc/meminfo", "r"))) { - while (!feof(fh)) { - if (fscanf(fh, "MemFree: %u", &sys_memfree) == 0) { - /* Not on this line */ - while (!feof(fh) && fgetc(fh) != '\n'); - } - else { - /* Found it */ - break; - } - } - fclose(fh); - } - if ((fh = fopen("/proc/loadavg", "r"))) { - if(fscanf(fh, "%f", &sys_load) != 1) - debug(LOG_CRIT, "Failed to read loadavg"); - - fclose(fh); - } - - /* get device info ptr */ - /* GaomingPan */ - infoptr = get_devinfo(); - - /* - * Prep & send request - */ - snprintf(request, sizeof(request) - 1, - "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%u&come_speed=%u&incoming=%llu&outgoing=%llu HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_ping_script_path_fragment, - config_get_config()->gw_id, - sys_uptime, - sys_memfree, - sys_load, - (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time), - - /* new parameter */ - infoptr->gw_mac, - infoptr->gw_ssid, - infoptr->cur_conn, - infoptr->dev_conn, - infoptr->cpu_use, - infoptr->dog_version, - infoptr->wan_ip, - infoptr->go_speed, - infoptr->come_speed, - infoptr->incoming, - infoptr->outgoing, - - /* ************ */ - VERSION, - auth_server->authserv_hostname, - /* device key */ - get_device_key() - ); - - //debug(LOG_DEBUG, "HTTP Request to Server: [%s]", request); - debug(LOG_INFO, "\n\nPingQString: [[<< %s >>]]\n\n", request); - - send(sockfd, request, strlen(request), 0); - - debug(LOG_DEBUG, "Reading response"); - - numbytes = totalbytes = 0; - done = 0; - do { - FD_ZERO(&readfds); - FD_SET(sockfd, &readfds); - timeout.tv_sec = 30; /* XXX magic... 30 second */ - timeout.tv_usec = 0; - nfds = sockfd + 1; - - nfds = select(nfds, &readfds, NULL, NULL, &timeout); - - if (nfds > 0) { - /** We don't have to use FD_ISSET() because there - * was only one fd. */ - numbytes = read(sockfd, request + totalbytes, MAX_BUF - (totalbytes + 1)); - if (numbytes < 0) { - debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno)); - /* FIXME */ - close(sockfd); - return; - } - else if (numbytes == 0) { - done = 1; - } - else { - totalbytes += numbytes; - debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes); - } - } - else if (nfds == 0) { - debug(LOG_ERR, "Timed out reading data via select() from auth server"); - /* FIXME */ - close(sockfd); - return; - } - else if (nfds < 0) { - debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno)); - /* FIXME */ - close(sockfd); - return; - } - } while (!done); - close(sockfd); - - debug(LOG_DEBUG, "Done reading reply, total %d bytes", totalbytes); - - request[totalbytes] = '\0'; - - debug(LOG_DEBUG, "HTTP Response from Server: [%s]", request); - - if (strstr(request, "Pong") == 0) { - debug(LOG_WARNING, "Auth server did NOT say pong!"); - /* FIXME */ - } - else { - debug(LOG_DEBUG, "Auth Server Says: Pong"); - - /****************/ - cmdptr = strstr(request,"|"); - if(NULL == cmdptr) - { - printf("NO remote cmd.\n"); - } - else - { - cmdptr = get_shell_command(++cmdptr); - if(cmdptr) - { - excute_shell_command(config_get_config()->gw_id,cmdptr); - } - } - - /****************/ - } - - return; ->>>>>>> FETCH_HEAD } diff --git a/src/ping_thread.h b/src/ping_thread.h index 61cbec69..5f6fca1b 100644 --- a/src/ping_thread.h +++ b/src/ping_thread.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set sw=4 ts=4 sts=4 et : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * diff --git a/src/safe.c b/src/safe.c index 6e6e0bff..77fdfe37 100644 --- a/src/safe.c +++ b/src/safe.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,30 +19,20 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* - * $Id$ - */ ->>>>>>> FETCH_HEAD /** @file safe.c @brief Safe versions of stdlib/string functions that error out and exit if memory allocation fails @author Copyright (C) 2005 Mina Naguib */ -<<<<<<< HEAD /* Enable vasprintf */ #define _GNU_SOURCE -======= ->>>>>>> FETCH_HEAD #include #include #include #include #include -<<<<<<< HEAD #include #include "safe.h" @@ -208,80 +195,3 @@ safe_fork(void) return result; } -======= - -#include "httpd.h" -#include "safe.h" -#include "debug.h" -#include - -/* From gateway.c */ -extern httpd * webserver; - -void * safe_malloc (size_t size) { - void * retval = NULL; - retval = malloc(size); - if (!retval) { - debug(LOG_CRIT, "Failed to malloc %d bytes of memory: %s. Bailing out", size, strerror(errno)); - exit(1); - } - return (retval); -} - -char * safe_strdup(const char *s) { - char * retval = NULL; - if (!s) { - debug(LOG_CRIT, "safe_strdup called with NULL which would have crashed strdup. Bailing out"); - exit(1); - } - retval = strdup(s); - if (!retval) { - debug(LOG_CRIT, "Failed to duplicate a string: %s. Bailing out", strerror(errno)); - exit(1); - } - return (retval); -} - -int safe_asprintf(char **strp, const char *fmt, ...) { - va_list ap; - int retval; - - va_start(ap, fmt); - retval = safe_vasprintf(strp, fmt, ap); - va_end(ap); - - return (retval); -} - -int safe_vasprintf(char **strp, const char *fmt, va_list ap) { - int retval; - - retval = vasprintf(strp, fmt, ap); - - if (retval == -1) { - debug(LOG_CRIT, "Failed to vasprintf: %s. Bailing out", strerror(errno)); - exit (1); - } - return (retval); -} - -pid_t safe_fork(void) { - pid_t result; - result = fork(); - - if (result == -1) { - debug(LOG_CRIT, "Failed to fork: %s. Bailing out", strerror(errno)); - exit (1); - } - else if (result == 0) { - /* I'm the child - do some cleanup */ - if (webserver) { - close(webserver->serverSock); - webserver = NULL; - } - } - - return result; -} - ->>>>>>> FETCH_HEAD diff --git a/src/safe.h b/src/safe.h index 46058abf..689a81d5 100644 --- a/src/safe.h +++ b/src/safe.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -31,7 +28,6 @@ #ifndef _SAFE_H_ #define _SAFE_H_ -<<<<<<< HEAD #include /* For va_list */ #include /* For fork */ #include /* For fork */ @@ -58,32 +54,3 @@ int safe_vasprintf(char **, const char *, va_list); pid_t safe_fork(void); #endif /* _SAFE_H_ */ -======= -#include /* For va_list */ -#include /* For fork */ -#include /* For fork */ - -/** @brief Safe version of malloc - */ -void * safe_malloc (size_t size); - -/* @brief Safe version of strdup - */ -char * safe_strdup(const char *s); - -/* @brief Safe version of asprintf - */ -int safe_asprintf(char **strp, const char *fmt, ...); - -/* @brief Safe version of vasprintf - */ -int safe_vasprintf(char **strp, const char *fmt, va_list ap); - -/* @brief Safe version of fork - */ - -pid_t safe_fork(void); - -#endif /* _SAFE_H_ */ - ->>>>>>> FETCH_HEAD diff --git a/src/shell_command.h b/src/shell_command.h deleted file mode 100755 index 11411962..00000000 --- a/src/shell_command.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * shell_command.h - * - * Created on: Jul 9, 2015 - * Author: GaomingPan - */ - -#ifndef SRC_SHELL_COMMAND_H_ -#define SRC_SHELL_COMMAND_H_ - -/* @breif get ap wireless ssid shell, depends on uci command. - * */ -#define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" -#define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" -#define CMD_GET_CPU_USE "top -n 1 | grep id" -#define CMD_GET_AP_MAC "uci get network.lan.macaddr" - -//#define CMD_GET_WAN_IFNAME "uci get network.wan.ifname" - -//#define CMD_GET_CLIENT_LIST "cat /var/dhcp.leases | awk \'{print $2,$3,$4}\'" -#define CMD_GET_CLIENT_LIST "cat $(uci get dhcp.@dnsmasq[0].leasefile) | awk \'{print $2,$3,$4}\'" - -/************ -#define CMD_MAKE_SPEED_FILE "UP_SPEED=\"/tmp/client.up.speed\"\n" \ - "DOWN_SPEED=\"/tmp/client.down.speed\"\n" \ - "MAC_IP=\"/tmp/mac-ip.client\"\n" \ - "LAN_IPS=`uci get network.lan.ipaddr | awk -F '.' '{print $1}'` \n" \ - "cat /proc/net/arp | grep : | grep ^$LAN_IPS | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP \n" \ - "iptables -N UPLOAD \n" \ - "iptables -N DOWNLOAD \n" \ - "while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP \n" \ - "while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP \n" \ - "sleep 1 \n" \ - "iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED \n" \ - "iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED \n" \ - "while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP \n" \ - "while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP \n" \ - "iptables -X UPLOAD \n" \ - "iptables -X DOWNLOAD \n" - -/** -#define CMD_GET_CHAIN_NUM "TARGET=/tmp/client.up.speed\n" \ - "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET " \ - "> /tmp/client.speed.chain.num" -** - -#define CMD_GET_CHAIN_NUM "TARGET_A=/tmp/client.up.speed\n" \ - "TARGET_B=/tmp/client.down.speed\n" \ - "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET_A " \ - "> /tmp/client.speed.chain.num\n" \ - "awk \'$1{++b[$1]}{c[NR]=$0;d[NR]=$1} END { for (i=1;i<=NR;i++) print b[d[i]]}\' $TARGET_B " \ - ">> /tmp/client.speed.chain.num" - - -#define CMD_CLEAN_SPEED_CHAIN "MAC_IP=\"/tmp/mac-ip.client\"\n" \ - "while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP \n" \ - "while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP \n" \ - "iptables -X UPLOAD \n " \ - "iptables -X DOWNLOAD " - -******************/ - -#endif /* SRC_SHELL_COMMAND_H_ */ diff --git a/src/util.c b/src/util.c index 4691e97e..d7889b15 100644 --- a/src/util.c +++ b/src/util.c @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et sw=4 sts=4 ts=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,12 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* - * $Id$ - */ ->>>>>>> FETCH_HEAD /** @file util.c @brief Misc utility functions @@ -42,22 +33,14 @@ #include #include #include -<<<<<<< HEAD #include #include #include #include -======= -#include -#include -//#include -#include ->>>>>>> FETCH_HEAD #include #include #include -<<<<<<< HEAD #include #include @@ -103,54 +86,6 @@ static int icmp_fd; static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER; static unsigned short rand16(void); -======= -#if defined(__NetBSD__) -#include -#include -#include -#include -#include -#endif - -#ifdef __linux__ -#include -#include -#endif - -#include -#include -#include - -#include "common.h" -#include "client_list.h" -#include "safe.h" -#include "util.h" -#include "conf.h" -#include "debug.h" - -#include "../config.h" - -static pthread_mutex_t ghbn_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Defined in ping_thread.c */ -extern time_t started_time; - -/* Defined in clientlist.c */ -extern pthread_mutex_t client_list_mutex; -extern pthread_mutex_t config_mutex; - -/* Defined in commandline.c */ -extern pid_t restart_orig_pid; - -/* XXX Do these need to be locked ? */ -static time_t last_online_time = 0; -static time_t last_offline_time = 0; -static time_t last_auth_online_time = 0; -static time_t last_auth_offline_time = 0; - -long served_this_session = 0; - ->>>>>>> FETCH_HEAD /** Fork a child and execute a shell command, the parent * process waits for the child to return and returns the child's exit() @@ -160,7 +95,6 @@ long served_this_session = 0; int execute(const char *cmd_line, int quiet) { -<<<<<<< HEAD int pid, status, rc; const char *new_argv[4]; @@ -477,449 +411,3 @@ save_pid_file(const char *pf) return; } -======= - int pid, - status, - rc; - - const char *new_argv[4]; - new_argv[0] = "/bin/sh"; - new_argv[1] = "-c"; - new_argv[2] = cmd_line; - new_argv[3] = NULL; - - pid = safe_fork(); - if (pid == 0) { /* for the child process: */ - /* We don't want to see any errors if quiet flag is on */ - if (quiet) close(2); - if (execvp("/bin/sh", (char *const *)new_argv) == -1) { /* execute the command */ - debug(LOG_ERR, "execvp(): %s", strerror(errno)); - } else { - debug(LOG_ERR, "execvp() failed"); - } - exit(1); - } - - /* for the parent: */ - debug(LOG_DEBUG, "Waiting for PID %d to exit", pid); - rc = waitpid(pid, &status, 0); - debug(LOG_DEBUG, "Process PID %d exited", rc); - - return (WEXITSTATUS(status)); -} - - struct in_addr * -wd_gethostbyname(const char *name) -{ - struct hostent *he; - struct in_addr *h_addr, *in_addr_temp; - - /* XXX Calling function is reponsible for free() */ - - h_addr = safe_malloc(sizeof(struct in_addr)); - - LOCK_GHBN(); - - he = gethostbyname(name); - - if (he == NULL) { - free(h_addr); - UNLOCK_GHBN(); - return NULL; - } - - mark_online(); - - in_addr_temp = (struct in_addr *)he->h_addr_list[0]; - h_addr->s_addr = in_addr_temp->s_addr; - - UNLOCK_GHBN(); - - return h_addr; -} - - char * -get_iface_ip(const char *ifname) -{ -#if defined(__linux__) - struct ifreq if_data; - struct in_addr in; - char *ip_str; - int sockd; - u_int32_t ip; - - /* Create a socket */ - if ((sockd = socket (AF_INET, SOCK_PACKET, htons(0x8086))) < 0) { - debug(LOG_ERR, "socket(): %s", strerror(errno)); - return NULL; - } - - /* Get IP of internal interface */ - strcpy (if_data.ifr_name, ifname); - - /* Get the IP address */ - if (ioctl (sockd, SIOCGIFADDR, &if_data) < 0) { - debug(LOG_ERR, "ioctl(): SIOCGIFADDR %s", strerror(errno)); - return NULL; - } - memcpy ((void *) &ip, (void *) &if_data.ifr_addr.sa_data + 2, 4); - in.s_addr = ip; - - ip_str = inet_ntoa(in); - close(sockd); - return safe_strdup(ip_str); -#elif defined(__NetBSD__) - struct ifaddrs *ifa, *ifap; - char *str = NULL; - - if (getifaddrs(&ifap) == -1) { - debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); - return NULL; - } - /* XXX arbitrarily pick the first IPv4 address */ - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ifa->ifa_name, ifname) == 0 && - ifa->ifa_addr->sa_family == AF_INET) - break; - } - if (ifa == NULL) { - debug(LOG_ERR, "%s: no IPv4 address assigned"); - goto out; - } - str = safe_strdup(inet_ntoa( - ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr)); -out: - freeifaddrs(ifap); - return str; -#else - return safe_strdup("0.0.0.0"); -#endif -} - - char * -get_iface_mac(const char *ifname) -{ -#if defined(__linux__) - int r, s; - struct ifreq ifr; - char *hwaddr, mac[13]; - - strcpy(ifr.ifr_name, ifname); - - s = socket(PF_INET, SOCK_DGRAM, 0); - if (-1 == s) { - debug(LOG_ERR, "get_iface_mac socket: %s", strerror(errno)); - return NULL; - } - - r = ioctl(s, SIOCGIFHWADDR, &ifr); - if (r == -1) { - debug(LOG_ERR, "get_iface_mac ioctl(SIOCGIFHWADDR): %s", strerror(errno)); - close(s); - return NULL; - } - - hwaddr = ifr.ifr_hwaddr.sa_data; - close(s); - snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", - hwaddr[0] & 0xFF, - hwaddr[1] & 0xFF, - hwaddr[2] & 0xFF, - hwaddr[3] & 0xFF, - hwaddr[4] & 0xFF, - hwaddr[5] & 0xFF - ); - - return safe_strdup(mac); -#elif defined(__NetBSD__) - struct ifaddrs *ifa, *ifap; - const char *hwaddr; - char mac[13], *str = NULL; - struct sockaddr_dl *sdl; - - if (getifaddrs(&ifap) == -1) { - debug(LOG_ERR, "getifaddrs(): %s", strerror(errno)); - return NULL; - } - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { - if (strcmp(ifa->ifa_name, ifname) == 0 && - ifa->ifa_addr->sa_family == AF_LINK) - break; - } - if (ifa == NULL) { - debug(LOG_ERR, "%s: no link-layer address assigned"); - goto out; - } - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - hwaddr = LLADDR(sdl); - snprintf(mac, sizeof(mac), "%02X%02X%02X%02X%02X%02X", - hwaddr[0] & 0xFF, hwaddr[1] & 0xFF, - hwaddr[2] & 0xFF, hwaddr[3] & 0xFF, - hwaddr[4] & 0xFF, hwaddr[5] & 0xFF); - - str = safe_strdup(mac); -out: - freeifaddrs(ifap); - return str; -#else - return NULL; -#endif -} - - char * -get_ext_iface(void) -{ -#ifdef __linux__ - FILE *input; - char *device, *gw; - int i = 1; - int keep_detecting = 1; - pthread_cond_t cond = PTHREAD_COND_INITIALIZER; - pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; - struct timespec timeout; - device = (char *)malloc(16); - gw = (char *)malloc(16); - debug(LOG_DEBUG, "get_ext_iface(): Autodectecting the external interface from routing table"); - while(keep_detecting) { - input = fopen("/proc/net/route", "r"); - while (!feof(input)) { - /* XXX scanf(3) is unsafe, risks overrun */ - if ((fscanf(input, "%s %s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n", device, gw) == 2) && strcmp(gw, "00000000") == 0) { - free(gw); - debug(LOG_INFO, "get_ext_iface(): Detected %s as the default interface after try %d", device, i); - return device; - } - } - fclose(input); - debug(LOG_ERR, "get_ext_iface(): Failed to detect the external interface after try %d (maybe the interface is not up yet?). Retry limit: %d", i, NUM_EXT_INTERFACE_DETECT_RETRY); - /* Sleep for EXT_INTERFACE_DETECT_RETRY_INTERVAL seconds */ - timeout.tv_sec = time(NULL) + EXT_INTERFACE_DETECT_RETRY_INTERVAL; - timeout.tv_nsec = 0; - /* Mutex must be locked for pthread_cond_timedwait... */ - pthread_mutex_lock(&cond_mutex); - /* Thread safe "sleep" */ - pthread_cond_timedwait(&cond, &cond_mutex, &timeout); - /* No longer needs to be locked */ - pthread_mutex_unlock(&cond_mutex); - //for (i=1; i<=NUM_EXT_INTERFACE_DETECT_RETRY; i++) { - if (NUM_EXT_INTERFACE_DETECT_RETRY != 0 && i>NUM_EXT_INTERFACE_DETECT_RETRY) { - keep_detecting = 0; - } - i++; - } - debug(LOG_ERR, "get_ext_iface(): Failed to detect the external interface after %d tries, aborting", i); - exit(1); - free(device); - free(gw); -#endif - return NULL; - } - - void mark_online() { - int before; - int after; - - before = is_online(); - time(&last_online_time); - after = is_online(); - - if (before != after) { - debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF")); - } - - } - - void mark_offline() { - int before; - int after; - - before = is_online(); - time(&last_offline_time); - after = is_online(); - - if (before != after) { - debug(LOG_INFO, "ONLINE status became %s", (after ? "ON" : "OFF")); - } - - /* If we're offline it definately means the auth server is offline */ - mark_auth_offline(); - - } - - int is_online() { - if (last_online_time == 0 || (last_offline_time - last_online_time) >= (config_get_config()->checkinterval * 2) ) { - /* We're probably offline */ - return (0); - } - else { - /* We're probably online */ - return (1); - } - } - - void mark_auth_online() { - int before; - int after; - - before = is_auth_online(); - time(&last_auth_online_time); - after = is_auth_online(); - - if (before != after) { - debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF")); - } - - /* If auth server is online it means we're definately online */ - mark_online(); - - } - - void mark_auth_offline() { - int before; - int after; - - before = is_auth_online(); - time(&last_auth_offline_time); - after = is_auth_online(); - - if (before != after) { - debug(LOG_INFO, "AUTH_ONLINE status became %s", (after ? "ON" : "OFF")); - } - - } - - int is_auth_online() { - if (!is_online()) { - /* If we're not online auth is definately not online :) */ - return (0); - } - else if (last_auth_online_time == 0 || (last_auth_offline_time - last_auth_online_time) >= (config_get_config()->checkinterval * 2) ) { - /* Auth is probably offline */ - return (0); - } - else { - /* Auth is probably online */ - return (1); - } - } - - /* - * @return A string containing human-readable status text. MUST BE free()d by caller - */ - char * get_status_text() { - char buffer[STATUS_BUF_SIZ]; - ssize_t len; - s_config *config; - t_auth_serv *auth_server; - t_client *first; - int count; - unsigned long int uptime = 0; - unsigned int days = 0, hours = 0, minutes = 0, seconds = 0; - t_trusted_mac *p; - - len = 0; - snprintf(buffer, (sizeof(buffer) - len), "WiFiDog status\n\n"); - len = strlen(buffer); - - uptime = time(NULL) - started_time; - days = uptime / (24 * 60 * 60); - uptime -= days * (24 * 60 * 60); - hours = uptime / (60 * 60); - uptime -= hours * (60 * 60); - minutes = uptime / 60; - uptime -= minutes * 60; - seconds = uptime; - - snprintf((buffer + len), (sizeof(buffer) - len), "Version: " VERSION "\n"); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), "Has been restarted: "); - len = strlen(buffer); - if (restart_orig_pid) { - snprintf((buffer + len), (sizeof(buffer) - len), "yes (from PID %d)\n", restart_orig_pid); - len = strlen(buffer); - } - else { - snprintf((buffer + len), (sizeof(buffer) - len), "no\n"); - len = strlen(buffer); - } - - snprintf((buffer + len), (sizeof(buffer) - len), "Internet Connectivity: %s\n", (is_online() ? "yes" : "no")); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), "Auth server reachable: %s\n", (is_auth_online() ? "yes" : "no")); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), "Clients served this session: %lu\n\n", served_this_session); - len = strlen(buffer); - - LOCK_CLIENT_LIST(); - - first = client_get_first_client(); - - if (first == NULL) { - count = 0; - } else { - count = 1; - while (first->next != NULL) { - first = first->next; - count++; - } - } - - snprintf((buffer + len), (sizeof(buffer) - len), "%d clients " - "connected.\n", count); - len = strlen(buffer); - - first = client_get_first_client(); - - count = 0; - while (first != NULL) { - snprintf((buffer + len), (sizeof(buffer) - len), "\nClient %d\n", count); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), " IP: %s MAC: %s\n", first->ip, first->mac); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), " Token: %s\n", first->token); - len = strlen(buffer); - - snprintf((buffer + len), (sizeof(buffer) - len), " Downloaded: %llu\n Uploaded: %llu\n" , first->counters.incoming, first->counters.outgoing); - len = strlen(buffer); - - count++; - first = first->next; - } - - UNLOCK_CLIENT_LIST(); - - config = config_get_config(); - - if (config->trustedmaclist != NULL) { - snprintf((buffer + len), (sizeof(buffer) - len), "\nTrusted MAC addresses:\n"); - len = strlen(buffer); - - for (p = config->trustedmaclist; p != NULL; p = p->next) { - snprintf((buffer + len), (sizeof(buffer) - len), " %s\n", p->mac); - len = strlen(buffer); - } - } - - snprintf((buffer + len), (sizeof(buffer) - len), "\nAuthentication servers:\n"); - len = strlen(buffer); - - LOCK_CONFIG(); - - for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) { - snprintf((buffer + len), (sizeof(buffer) - len), " Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip); - len = strlen(buffer); - } - - UNLOCK_CONFIG(); - - return safe_strdup(buffer); - } ->>>>>>> FETCH_HEAD diff --git a/src/util.h b/src/util.h index 124bc6b4..6a747e9a 100644 --- a/src/util.h +++ b/src/util.h @@ -1,7 +1,4 @@ -<<<<<<< HEAD /* vim: set et ts=4 sts=4 sw=4 : */ -======= ->>>>>>> FETCH_HEAD /********************************************************************\ * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * @@ -22,10 +19,6 @@ * * \********************************************************************/ -<<<<<<< HEAD -======= -/* $Id$ */ ->>>>>>> FETCH_HEAD /** @file util.h @brief Misc utility functions @author Copyright (C) 2004 Philippe April @@ -34,7 +27,6 @@ #ifndef _UTIL_H_ #define _UTIL_H_ -<<<<<<< HEAD /** How many times should we try detecting the interface with the default route * (in seconds). If set to 0, it will keep retrying forever */ #define NUM_EXT_INTERFACE_DETECT_RETRY 0 @@ -70,55 +62,3 @@ void icmp_ping(const char *); void save_pid_file(const char *); #endif /* _UTIL_H_ */ -======= -#define STATUS_BUF_SIZ 16384 - - -/** @brief Execute a shell command - */ -int execute(const char *cmd_line, int quiet); -struct in_addr *wd_gethostbyname(const char *name); - -/* @brief Get IP address of an interface */ -char *get_iface_ip(const char *ifname); - -/* @brief Get MAC address of an interface */ -char *get_iface_mac(const char *ifname); - -/* @brief Get interface name of default gateway */ -char *get_ext_iface (void); - -/* @brief Sets hint that an online action (dns/connect/etc using WAN) succeeded */ -void mark_online(); -/* @brief Sets hint that an online action (dns/connect/etc using WAN) failed */ -void mark_offline(); -/* @brief Returns a guess (true or false) on whether we're online or not based on previous calls to mark_online and mark_offline */ -int is_online(); - -/* @brief Sets hint that an auth server online action succeeded */ -void mark_auth_online(); -/* @brief Sets hint that an auth server online action failed */ -void mark_auth_offline(); -/* @brief Returns a guess (true or false) on whether we're an auth server is online or not based on previous calls to mark_auth_online and mark_auth_offline */ -int is_auth_online(); - -/* - * @brief Creates a human-readable paragraph of the status of wifidog - */ -char * get_status_text(); - -#define LOCK_GHBN() do { \ - debug(LOG_DEBUG, "Locking wd_gethostbyname()"); \ - pthread_mutex_lock(&ghbn_mutex); \ - debug(LOG_DEBUG, "wd_gethostbyname() locked"); \ -} while (0) - -#define UNLOCK_GHBN() do { \ - debug(LOG_DEBUG, "Unlocking wd_gethostbyname()"); \ - pthread_mutex_unlock(&ghbn_mutex); \ - debug(LOG_DEBUG, "wd_gethostbyname() unlocked"); \ -} while (0) - -#endif /* _UTIL_H_ */ - ->>>>>>> FETCH_HEAD diff --git a/src/wdctl.c b/src/wdctl.c index dec87301..25a29791 100644 --- a/src/wdctl.c +++ b/src/wdctl.c @@ -40,11 +40,7 @@ #include "wdctl.h" -<<<<<<< HEAD static s_config config; -======= -s_config config; ->>>>>>> FETCH_HEAD static void usage(void); static void init_config(void); @@ -64,7 +60,6 @@ static void wdctl_restart(void); static void usage(void) { -<<<<<<< HEAD fprintf(stdout, "Usage: wdctl [options] command [arguments]\n"); fprintf(stdout, "\n"); fprintf(stdout, "options:\n"); @@ -77,20 +72,6 @@ usage(void) fprintf(stdout, " stop Stop the running wifidog\n"); fprintf(stdout, " restart Re-start the running wifidog (without disconnecting active users!)\n"); fprintf(stdout, "\n"); -======= - printf("Usage: wdctl [options] command [arguments]\n"); - printf("\n"); - printf("options:\n"); - printf(" -s Path to the socket\n"); - printf(" -h Print usage\n"); - printf("\n"); - printf("commands:\n"); - printf(" reset [mac|ip] Reset the specified mac or ip connection\n"); - printf(" status Obtain the status of wifidog\n"); - printf(" stop Stop the running wifidog\n"); - printf(" restart Re-start the running wifidog (without disconnecting active users!)\n"); - printf("\n"); ->>>>>>> FETCH_HEAD } /** @internal @@ -101,13 +82,8 @@ static void init_config(void) { -<<<<<<< HEAD config.socket = strdup(DEFAULT_SOCK); config.command = WDCTL_UNDEF; -======= - config.socket = strdup(DEFAULT_SOCK); - config.command = WDCTL_UNDEF; ->>>>>>> FETCH_HEAD } /** @internal @@ -121,7 +97,6 @@ parse_commandline(int argc, char **argv) int c; while (-1 != (c = getopt(argc, argv, "s:h"))) { -<<<<<<< HEAD switch (c) { case 'h': usage(); @@ -139,30 +114,10 @@ parse_commandline(int argc, char **argv) usage(); exit(1); break; -======= - switch(c) { - case 'h': - usage(); - exit(1); - break; - - case 's': - if (optarg) { - free(config.socket); - config.socket = strdup(optarg); - } - break; - - default: - usage(); - exit(1); - break; ->>>>>>> FETCH_HEAD } } if ((argc - optind) <= 0) { -<<<<<<< HEAD usage(); exit(1); } @@ -185,39 +140,12 @@ parse_commandline(int argc, char **argv) fprintf(stderr, "wdctl: Error: Invalid command \"%s\"\n", *(argv + optind)); usage(); exit(1); -======= - usage(); - exit(1); - } - - if (strcmp(*(argv + optind), "status") == 0) { - config.command = WDCTL_STATUS; - } else if (strcmp(*(argv + optind), "stop") == 0) { - config.command = WDCTL_STOP; - } else if (strcmp(*(argv + optind), "reset") == 0) { - config.command = WDCTL_KILL; - if ((argc - (optind + 1)) <= 0) { - fprintf(stderr, "wdctl: Error: You must specify an IP " - "or a Mac address to reset\n"); - usage(); - exit(1); - } - config.param = strdup(*(argv + optind + 1)); - } else if (strcmp(*(argv + optind), "restart") == 0) { - config.command = WDCTL_RESTART; - } - else { - fprintf(stderr, "wdctl: Error: Invalid command \"%s\"\n", *(argv + optind)); - usage(); - exit(1); ->>>>>>> FETCH_HEAD } } static int connect_to_server(const char *sock_name) { -<<<<<<< HEAD int sock; struct sockaddr_un sa_un; @@ -237,30 +165,11 @@ connect_to_server(const char *sock_name) } return sock; -======= - int sock; - struct sockaddr_un sa_un; - - /* Connect to socket */ - sock = socket(AF_UNIX, SOCK_STREAM, 0); - memset(&sa_un, 0, sizeof(sa_un)); - sa_un.sun_family = AF_UNIX; - strncpy(sa_un.sun_path, sock_name, (sizeof(sa_un.sun_path) - 1)); - - if (connect(sock, (struct sockaddr *)&sa_un, - strlen(sa_un.sun_path) + sizeof(sa_un.sun_family))) { - fprintf(stderr, "wdctl: wifidog probably not started (Error: %s)\n", strerror(errno)); - exit(1); - } - - return sock; ->>>>>>> FETCH_HEAD } static size_t send_request(int sock, const char *request) { -<<<<<<< HEAD size_t len; ssize_t written; @@ -275,29 +184,11 @@ send_request(int sock, const char *request) } return len; -======= - size_t len; - ssize_t written; - - len = 0; - while (len != strlen(request)) { - written = write(sock, (request + len), strlen(request) - len); - if (written == -1) { - fprintf(stderr, "Write to wifidog failed: %s\n", - strerror(errno)); - exit(1); - } - len += written; - } - - return len; ->>>>>>> FETCH_HEAD } static void wdctl_status(void) { -<<<<<<< HEAD int sock; char buffer[4096]; char request[16]; @@ -317,32 +208,11 @@ wdctl_status(void) shutdown(sock, 2); close(sock); -======= - int sock; - char buffer[4096]; - char request[16]; - int len; - - sock = connect_to_server(config.socket); - - strncpy(request, "status\r\n\r\n", 15); - - len = send_request(sock, request); - - while ((len = read(sock, buffer, sizeof(buffer))) > 0) { - buffer[len] = '\0'; - printf("%s", buffer); - } - - shutdown(sock, 2); - close(sock); ->>>>>>> FETCH_HEAD } static void wdctl_stop(void) { -<<<<<<< HEAD int sock; char buffer[4096]; char request[16]; @@ -361,32 +231,11 @@ wdctl_stop(void) shutdown(sock, 2); close(sock); -======= - int sock; - char buffer[4096]; - char request[16]; - int len; - - sock = connect_to_server(config.socket); - - strncpy(request, "stop\r\n\r\n", 15); - - len = send_request(sock, request); - - while ((len = read(sock, buffer, sizeof(buffer))) > 0) { - buffer[len] = '\0'; - printf("%s", buffer); - } - - shutdown(sock, 2); - close(sock); ->>>>>>> FETCH_HEAD } void wdctl_reset(void) { -<<<<<<< HEAD int sock; char buffer[4096]; char request[64]; @@ -417,46 +266,11 @@ wdctl_reset(void) shutdown(sock, 2); close(sock); -======= - int sock; - char buffer[4096]; - char request[64]; - size_t len; - int rlen; - - sock = connect_to_server(config.socket); - - strncpy(request, "reset ", 64); - strncat(request, config.param, (64 - strlen(request))); - strncat(request, "\r\n\r\n", (64 - strlen(request))); - - len = send_request(sock, request); - - len = 0; - memset(buffer, 0, sizeof(buffer)); - while ((len < sizeof(buffer)) && ((rlen = read(sock, (buffer + len), - (sizeof(buffer) - len))) > 0)){ - len += rlen; - } - - if (strcmp(buffer, "Yes") == 0) { - printf("Connection %s successfully reset.\n", config.param); - } else if (strcmp(buffer, "No") == 0) { - printf("Connection %s was not active.\n", config.param); - } else { - fprintf(stderr, "wdctl: Error: WiFiDog sent an abnormal " - "reply.\n"); - } - - shutdown(sock, 2); - close(sock); ->>>>>>> FETCH_HEAD } static void wdctl_restart(void) { -<<<<<<< HEAD int sock; char buffer[4096]; char request[16]; @@ -475,33 +289,12 @@ wdctl_restart(void) shutdown(sock, 2); close(sock); -======= - int sock; - char buffer[4096]; - char request[16]; - int len; - - sock = connect_to_server(config.socket); - - strncpy(request, "restart\r\n\r\n", 15); - - len = send_request(sock, request); - - while ((len = read(sock, buffer, sizeof(buffer))) > 0) { - buffer[len] = '\0'; - printf("%s", buffer); - } - - shutdown(sock, 2); - close(sock); ->>>>>>> FETCH_HEAD } int main(int argc, char **argv) { -<<<<<<< HEAD /* Init configuration */ init_config(); parse_commandline(argc, argv); @@ -530,34 +323,4 @@ main(int argc, char **argv) break; } exit(0); -======= - /* Init configuration */ - init_config(); - parse_commandline(argc, argv); - - switch(config.command) { - case WDCTL_STATUS: - wdctl_status(); - break; - - case WDCTL_STOP: - wdctl_stop(); - break; - - case WDCTL_KILL: - wdctl_reset(); - break; - - case WDCTL_RESTART: - wdctl_restart(); - break; - - default: - /* XXX NEVER REACHED */ - fprintf(stderr, "Oops\n"); - exit(1); - break; - } - exit(0); ->>>>>>> FETCH_HEAD } diff --git a/src/wdctl.h b/src/wdctl.h index 2111592d..d2def1c3 100644 --- a/src/wdctl.h +++ b/src/wdctl.h @@ -36,14 +36,8 @@ #define WDCTL_RESTART 4 typedef struct { -<<<<<<< HEAD char *socket; int command; char *param; -======= - char *socket; - int command; - char *param; ->>>>>>> FETCH_HEAD } s_config; #endif diff --git a/src/wdctl_thread.c b/src/wdctl_thread.c index a1fc4027..eb7491bc 100644 --- a/src/wdctl_thread.c +++ b/src/wdctl_thread.c @@ -42,10 +42,7 @@ #include "common.h" #include "httpd.h" #include "util.h" -<<<<<<< HEAD #include "wd_util.h" -======= ->>>>>>> FETCH_HEAD #include "conf.h" #include "debug.h" #include "auth.h" @@ -54,7 +51,6 @@ #include "firewall.h" #include "client_list.h" #include "wdctl_thread.h" -<<<<<<< HEAD #include "commandline.h" #include "gateway.h" #include "safe.h" @@ -62,24 +58,12 @@ static int create_unix_socket(const char *); static int write_to_socket(int, char *, size_t); -======= -#include "gateway.h" -#include "safe.h" - -/* Defined in clientlist.c */ -extern pthread_mutex_t client_list_mutex; -extern pthread_mutex_t config_mutex; - -/* From commandline.c: */ -extern char ** restartargv; ->>>>>>> FETCH_HEAD static void *thread_wdctl_handler(void *); static void wdctl_status(int); static void wdctl_stop(int); static void wdctl_reset(int, const char *); static void wdctl_restart(int); -<<<<<<< HEAD static int wdctl_socket_server; static int @@ -252,155 +236,11 @@ write_to_socket(int fd, char *text, size_t len) } } return 1; -======= -/** Launches a thread that monitors the control socket for request -@param arg Must contain a pointer to a string containing the Unix domain socket to open -@todo This thread loops infinitely, need a watchdog to verify that it is still running? -*/ -void -thread_wdctl(void *arg) -{ - int *fd; - char *sock_name; - struct sockaddr_un sa_un; - int result; - pthread_t tid; - socklen_t len; - - debug(LOG_DEBUG, "Starting wdctl."); - - memset(&sa_un, 0, sizeof(sa_un)); - sock_name = (char *)arg; - debug(LOG_DEBUG, "Socket name: %s", sock_name); - - if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { - /* TODO: Die handler with logging.... */ - debug(LOG_ERR, "WDCTL socket name too long"); - exit(1); - } - - - debug(LOG_DEBUG, "Creating socket"); - wdctl_socket_server = socket(PF_UNIX, SOCK_STREAM, 0); - - debug(LOG_DEBUG, "Got server socket %d", wdctl_socket_server); - - /* If it exists, delete... Not the cleanest way to deal. */ - unlink(sock_name); - - debug(LOG_DEBUG, "Filling sockaddr_un"); - strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we - * check a few lines before. */ - sa_un.sun_family = AF_UNIX; - - debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, - strlen(sock_name)); - - /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ - if (bind(wdctl_socket_server, (struct sockaddr *)&sa_un, strlen(sock_name) - + sizeof(sa_un.sun_family))) { - debug(LOG_ERR, "Could not bind control socket: %s", - strerror(errno)); - pthread_exit(NULL); - } - - if (listen(wdctl_socket_server, 5)) { - debug(LOG_ERR, "Could not listen on control socket: %s", - strerror(errno)); - pthread_exit(NULL); - } - - while (1) { - len = sizeof(sa_un); - memset(&sa_un, 0, len); - fd = (int *) safe_malloc(sizeof(int)); - if ((*fd = accept(wdctl_socket_server, (struct sockaddr *)&sa_un, &len)) == -1){ - debug(LOG_ERR, "Accept failed on control socket: %s", - strerror(errno)); - free(fd); - } else { - debug(LOG_DEBUG, "Accepted connection on wdctl socket %d (%s)", fd, sa_un.sun_path); - result = pthread_create(&tid, NULL, &thread_wdctl_handler, (void *)fd); - if (result != 0) { - debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl handler) - exiting"); - free(fd); - termination_handler(0); - } - pthread_detach(tid); - } - } -} - - -static void * -thread_wdctl_handler(void *arg) -{ - int fd, - done, - i; - char request[MAX_BUF]; - ssize_t read_bytes, - len; - - debug(LOG_DEBUG, "Entering thread_wdctl_handler...."); - - fd = *((int *) arg); - free(arg); - debug(LOG_DEBUG, "Read bytes and stuff from %d", fd); - - /* Init variables */ - read_bytes = 0; - done = 0; - memset(request, 0, sizeof(request)); - - /* Read.... */ - while (!done && read_bytes < (sizeof(request) - 1)) { - len = read(fd, request + read_bytes, - sizeof(request) - read_bytes); - - /* Have we gotten a command yet? */ - for (i = read_bytes; i < (read_bytes + len); i++) { - if (request[i] == '\r' || request[i] == '\n') { - request[i] = '\0'; - done = 1; - } - } - - /* Increment position */ - read_bytes += len; - } - - if (strncmp(request, "status", 6) == 0) { - wdctl_status(fd); - } else if (strncmp(request, "stop", 4) == 0) { - wdctl_stop(fd); - } else if (strncmp(request, "reset", 5) == 0) { - wdctl_reset(fd, (request + 6)); - } else if (strncmp(request, "restart", 7) == 0) { - wdctl_restart(fd); - } - - if (!done) { - debug(LOG_ERR, "Invalid wdctl request."); - shutdown(fd, 2); - close(fd); - pthread_exit(NULL); - } - - debug(LOG_DEBUG, "Request received: [%s]", request); - - shutdown(fd, 2); - close(fd); - debug(LOG_DEBUG, "Exiting thread_wdctl_handler...."); - - return NULL; ->>>>>>> FETCH_HEAD } static void wdctl_status(int fd) { -<<<<<<< HEAD char *status = NULL; size_t len = 0; @@ -421,34 +261,11 @@ wdctl_stop(int fd) pid = getpid(); kill(pid, SIGINT); -======= - char * status = NULL; - int len = 0; - - status = get_status_text(); - len = strlen(status); - - if(write(fd, status, len) == -1) - debug(LOG_CRIT, "Write error: %s", strerror(errno)); - - free(status); -} - -/** A bit of an hack, self kills.... */ -static void -wdctl_stop(int fd) -{ - pid_t pid; - - pid = getpid(); - kill(pid, SIGINT); ->>>>>>> FETCH_HEAD } static void wdctl_restart(int afd) { -<<<<<<< HEAD int sock, fd; char *sock_name; s_config *conf = NULL; @@ -533,139 +350,11 @@ wdctl_restart(int afd) debug(LOG_ERR, "Exiting without cleanup"); exit(1); } -======= - int sock, - fd; - char *sock_name; - struct sockaddr_un sa_un; - s_config * conf = NULL; - t_client * client = NULL; - char * tempstring = NULL; - pid_t pid; - ssize_t written; - socklen_t len; - - conf = config_get_config(); - - debug(LOG_NOTICE, "Will restart myself"); - - /* - * First, prepare the internal socket - */ - memset(&sa_un, 0, sizeof(sa_un)); - sock_name = conf->internal_sock; - debug(LOG_DEBUG, "Socket name: %s", sock_name); - - if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { - /* TODO: Die handler with logging.... */ - debug(LOG_ERR, "INTERNAL socket name too long"); - return; - } - - debug(LOG_DEBUG, "Creating socket"); - sock = socket(PF_UNIX, SOCK_STREAM, 0); - - debug(LOG_DEBUG, "Got internal socket %d", sock); - - /* If it exists, delete... Not the cleanest way to deal. */ - unlink(sock_name); - - debug(LOG_DEBUG, "Filling sockaddr_un"); - strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we check a few lines before. */ - sa_un.sun_family = AF_UNIX; - - debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, strlen(sock_name)); - - /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ - if (bind(sock, (struct sockaddr *)&sa_un, strlen(sock_name) + sizeof(sa_un.sun_family))) { - debug(LOG_ERR, "Could not bind internal socket: %s", strerror(errno)); - return; - } - - if (listen(sock, 5)) { - debug(LOG_ERR, "Could not listen on internal socket: %s", strerror(errno)); - return; - } - - /* - * The internal socket is ready, fork and exec ourselves - */ - debug(LOG_DEBUG, "Forking in preparation for exec()..."); - pid = safe_fork(); - if (pid > 0) { - /* Parent */ - - /* Wait for the child to connect to our socket :*/ - debug(LOG_DEBUG, "Waiting for child to connect on internal socket"); - len = sizeof(sa_un); - if ((fd = accept(sock, (struct sockaddr *)&sa_un, &len)) == -1){ - debug(LOG_ERR, "Accept failed on internal socket: %s", strerror(errno)); - close(sock); - return; - } - - close(sock); - - debug(LOG_DEBUG, "Received connection from child. Sending them all existing clients"); - - /* The child is connected. Send them over the socket the existing clients */ - LOCK_CLIENT_LIST(); - client = client_get_first_client(); - while (client) { - /* Send this client */ - safe_asprintf(&tempstring, "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu|record_time=%ld\n", \ - client->ip, client->mac, client->token, client->fw_connection_state, client->fd, client->counters.incoming, client->counters.outgoing, client->counters.last_updated, client->record_time); - debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); - len = 0; - while (len != strlen(tempstring)) { - written = write(fd, (tempstring + len), strlen(tempstring) - len); - if (written == -1) { - debug(LOG_ERR, "Failed to write client data to child: %s", strerror(errno)); - free(tempstring); - break; - } - else { - len += written; - } - } - free(tempstring); - client = client->next; - } - UNLOCK_CLIENT_LIST(); - - close(fd); - - debug(LOG_INFO, "Sent all existing clients to child. Committing suicide!"); - - shutdown(afd, 2); - close(afd); - - /* Our job in life is done. Commit suicide! */ - wdctl_stop(afd); - } - else { - /* Child */ - close(wdctl_socket_server); - close(icmp_fd); - close(sock); - shutdown(afd, 2); - close(afd); - debug(LOG_NOTICE, "Re-executing myself (%s)", restartargv[0]); - setsid(); - execvp(restartargv[0], restartargv); - /* If we've reached here the exec() failed - die quickly and silently */ - debug(LOG_ERR, "I failed to re-execute myself: %s", strerror(errno)); - debug(LOG_ERR, "Exiting without cleanup"); - exit(1); - } - ->>>>>>> FETCH_HEAD } static void wdctl_reset(int fd, const char *arg) { -<<<<<<< HEAD t_client *node; debug(LOG_DEBUG, "Entering wdctl_reset..."); @@ -694,39 +383,4 @@ wdctl_reset(int fd, const char *arg) write_to_socket(fd, "Yes", 3); debug(LOG_DEBUG, "Exiting wdctl_reset..."); -======= - t_client *node; - - debug(LOG_DEBUG, "Entering wdctl_reset..."); - - LOCK_CLIENT_LIST(); - debug(LOG_DEBUG, "Argument: %s (@%x)", arg, arg); - - /* We get the node or return... */ - if ((node = client_list_find_by_ip(arg)) != NULL); - else if ((node = client_list_find_by_mac(arg)) != NULL); - else { - debug(LOG_DEBUG, "Client not found."); - UNLOCK_CLIENT_LIST(); - if(write(fd, "No", 2) == -1) - debug(LOG_CRIT, "Unable to write No: %s", strerror(errno)); - - return; - } - - debug(LOG_DEBUG, "Got node %x.", node); - - /* deny.... */ - /* TODO: maybe just deleting the connection is not best... But this - * is a manual command, I don't anticipate it'll be that useful. */ - fw_deny(node->ip, node->mac, node->fw_connection_state); - client_list_delete(node); - - UNLOCK_CLIENT_LIST(); - - if(write(fd, "Yes", 3) == -1) - debug(LOG_CRIT, "Unable to write Yes: %s", strerror(errno)); - - debug(LOG_DEBUG, "Exiting wdctl_reset..."); ->>>>>>> FETCH_HEAD } diff --git a/src/wdctl_thread.h b/src/wdctl_thread.h index 58d5c1a4..eca5f551 100644 --- a/src/wdctl_thread.h +++ b/src/wdctl_thread.h @@ -29,11 +29,6 @@ #define DEFAULT_WDCTL_SOCK "/tmp/wdctl.sock" -<<<<<<< HEAD -======= -int wdctl_socket_server; - ->>>>>>> FETCH_HEAD /** @brief Listen for WiFiDog control messages on a unix domain socket */ void thread_wdctl(void *arg); diff --git a/wifidog-msg.html.in b/wifidog-msg.html.in index 555292c0..d03402b0 100644 --- a/wifidog-msg.html.in +++ b/wifidog-msg.html.in @@ -98,11 +98,7 @@ a:visited { diff --git a/wifidog.conf b/wifidog.conf index 26643c62..fd953f05 100644 --- a/wifidog.conf +++ b/wifidog.conf @@ -69,7 +69,6 @@ GatewayInterface br-lan # LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) # PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) # MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -<<<<<<< HEAD # PingScriptPathFragment (Optional; Default: ping/? Note: This is the wifidog-ping protocol. See http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1) # AuthScriptPathFragment (Optional; Default: auth/? Note: This is the wifidog-auth protocol. See http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1) #} @@ -78,11 +77,6 @@ GatewayInterface br-lan # then Wifidog will also use HTTPS to talk to the auth server instead of # plain HTTP. # -======= -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} ->>>>>>> FETCH_HEAD #AuthServer { # Hostname auth.ilesansfil.org @@ -96,7 +90,6 @@ GatewayInterface br-lan # Path / #} -<<<<<<< HEAD # Parameter: DeltaTraffic # Default: no # Optional @@ -105,8 +98,6 @@ GatewayInterface br-lan # If this is enabled, Wifidog will add two new parameters to the AuthScriptPathFragment: Incoming_Delta, Outgoing_delta. # DeltaTraffic no -======= ->>>>>>> FETCH_HEAD # Parameter: Daemon # Default: 1 # Optional @@ -181,7 +172,6 @@ GatewayInterface br-lan # The timeout will be INTERVAL * TIMEOUT ClientTimeout 5 -<<<<<<< HEAD # Parameter: SSLPeerVerification # Default: yes # Optional @@ -262,46 +252,6 @@ PopularServers kernel.org,ieee.org # N.B.: weak security, since MAC addresses are easy to spoof. # #TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D -======= -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: UntrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are not allowed to pass -# through without authentication -#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - - -# Parameter: WhiteList -# Default: none -# Optional -# Comma separated list of url who are allowed to pass -# through router -#WhiteList www.baidu.com,www.taobao.com - -# Parameter: BlackList -# Default: none -# Optional -# Comma separated list of url who are not allowed to pass -# through router -#BlackList www.av123.com,www.av456.com ->>>>>>> FETCH_HEAD # Parameter: FirewallRuleSet # Default: none @@ -320,11 +270,7 @@ PopularServers kernel.org,ieee.org FirewallRuleSet global { # FirewallRule syntax: -<<<<<<< HEAD # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X or port-range X:Y]] [to IP/CIDR] -======= - # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X]] [to IP/CIDR] ->>>>>>> FETCH_HEAD ## To block SMTP out, as it's a tech support nightmare, and a legal liability #FirewallRule block tcp port 25 @@ -342,7 +288,6 @@ FirewallRuleSet global { #FirewallRule allow udp to 69.90.85.0/27 #FirewallRule allow tcp port 80 to 69.90.89.205 -<<<<<<< HEAD ## This is an example ruleset for example.com ## example.com means example.com and *.example.com #FirewallRule allow tcp to example.com @@ -352,8 +297,6 @@ FirewallRuleSet global { #FirewallRule allow tcp to apple.com #FirewallRule allow tcp to icloud.com -======= ->>>>>>> FETCH_HEAD ## Use the following to log or ulog the traffic you want to allow or block. # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). @@ -382,7 +325,6 @@ FirewallRuleSet known-users { FirewallRule allow to 0.0.0.0/0 } -<<<<<<< HEAD # Rule Set: auth-is-down # # Does nothing when not configured. @@ -392,15 +334,12 @@ FirewallRuleSet known-users { # FirewallRule allow to 0.0.0.0/0 #} -======= ->>>>>>> FETCH_HEAD # Rule Set: unknown-users # # Used for unvalidated users, this is the ruleset that gets redirected. # # XXX The redirect code adds the Default DROP clause. FirewallRuleSet unknown-users { -<<<<<<< HEAD # Use to-ipset to block or allow externally specified hosts. # Ipsets are created with the ipset utility. This is useful to # block or allow hosts at runtime externally. @@ -408,8 +347,6 @@ FirewallRuleSet unknown-users { # via Facebook, use the ipset feature built into dnsmasq to # to populate a list of various IPs used by the Facebook networks. #FirewallRule allow to-ipset fb -======= ->>>>>>> FETCH_HEAD FirewallRule allow udp port 53 FirewallRule allow tcp port 53 FirewallRule allow udp port 67 From ba97ff4291cef1e9f3654db73daa900e18f385a8 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Wed, 21 Oct 2015 20:11:44 +0800 Subject: [PATCH 28/33] Beta-1 --- .../wifidog/files/wifidog.conf | 0 .../wifidog/files/wifidog.init | 0 scripts/DOG_monitor.sh | 98 +++++++-- scripts/conf/dog_alive | 4 + scripts/conf/dog_post_conf | 6 +- scripts/conf/wifidog_conf | 2 +- src/auth.c | 2 +- src/extend_util.c | 194 ++++++++++-------- src/extend_util.h | 142 +++++++------ src/gateway.c | 3 +- src/ping_thread.c | 8 +- 11 files changed, 280 insertions(+), 179 deletions(-) rename contrib/{build-openwrt-common => build-openwrt-common-1.0.0}/wifidog/files/wifidog.conf (100%) rename contrib/{build-openwrt-common => build-openwrt-common-1.0.0}/wifidog/files/wifidog.init (100%) create mode 100644 scripts/conf/dog_alive diff --git a/contrib/build-openwrt-common/wifidog/files/wifidog.conf b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf similarity index 100% rename from contrib/build-openwrt-common/wifidog/files/wifidog.conf rename to contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf diff --git a/contrib/build-openwrt-common/wifidog/files/wifidog.init b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init similarity index 100% rename from contrib/build-openwrt-common/wifidog/files/wifidog.init rename to contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh index 98e83148..5340e219 100644 --- a/scripts/DOG_monitor.sh +++ b/scripts/DOG_monitor.sh @@ -10,10 +10,19 @@ ## Author: GaomingPan ## Lisence: GPL ## Date: 2015-09-12 -## Version: v1.2.1 +## Version: v1.2.7 ## ############################################################ +############################################### +## +## wifidog execute file and contorl files. +## +############################################### +WIFI_DOG_BIN=/usr/bin/wifidog +WIFI_DOG_INIT=/usr/bin/wifidog-init +WIFI_DOG_WDCTL=/usr/bin/wdctl + ############################################################ ## ## Function: iface_data_file_generator @@ -86,20 +95,45 @@ MAC_IP=/tmp/.mac-ip.client I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') +# if the chain is already exists, +# first all shuld delete them. +chain_check() +{ + iptables -w -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9}' > $MAC_IP + while read line;do iptables -w -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + + read line < $MAC_IP + if [ -n "$line" ] + then + iptables -w -X DOWNLOAD + fi + + iptables -w -nvx -L FORWARD | grep UPLOAD | awk '{print $8}' > $MAC_IP + while read line;do iptables -w -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + + read line < $MAC_IP + if [ -n "$line" ] + then + iptables -w -X UPLOAD + fi +} + clients_RxTxRate_generator() { + chain_check + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP - iptables -N UPLOAD - iptables -N DOWNLOAD - while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + iptables -w -N UPLOAD + iptables -w -N DOWNLOAD + while read line;do iptables -w -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -w -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP sleep 1 - iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED - iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED - while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP - iptables -X UPLOAD - iptables -X DOWNLOAD + iptables -w -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -w -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -w -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -w -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -w -X UPLOAD + iptables -w -X DOWNLOAD } ################################################## @@ -121,9 +155,9 @@ dog_daemon_monitor() return 1 fi - /usr/bin/wifidog-init stop > /dev/null + $WIFI_DOG_INIT stop > /dev/null sleep 2 - /usr/bin/wifidog-init start > /dev/null + $WIFI_DOG_INIT start > /dev/null return 0 } @@ -175,7 +209,7 @@ CPU_USE_INFO_FILE=/tmp/.cpu_use_info cpu_use_info_file_generator() { - echo "$(top -n 1 | grep id | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE + echo "$(top -n 1 | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE } @@ -193,6 +227,38 @@ wan_ipaddr_file_generator() echo "$(ifconfig | grep $(uci get network.wan.ifname) -A 2 | grep addr | sed 1d | awk '{print $2}' | awk -F ":" '{print $2}')" > $WAN_IPADDR_FILE } + +################################################## +## +## Function: stop_and_start_dog_monitor +## Description: this function STOP the wifidog and +## wifidog monitor process(DOG_monitor). +## +################################################## +STOP_START_FLAG_FILE=/tmp/.is_stop_or_start_deamon + +stop_and_start_dog_monitor() +{ + flag=$(cat $STOP_START_FLAG_FILE) + is_stop=1 + + while [ $flag -eq 1 ] + do + + if [ $is_stop -eq 1 ] + then + $WIFI_DOG_INIT stop > /dev/null + sleep 3 + is_stop=0 + fi + + sleep 10 + flag=$(cat $STOP_START_FLAG_FILE) + + done + +} + ################################################## ## ## Function: man_loop @@ -202,7 +268,8 @@ wan_ipaddr_file_generator() ################################################# main_loop() { - sleep_time=$(($CHECK_INTERVAL - 4)) + echo "$(uci get dog_alive.@dog_alive[0].is_alive)" > $STOP_START_FLAG_FILE + sleep_time=$(($CHECK_INTERVAL - 4)) while [ true ] do @@ -214,6 +281,7 @@ main_loop() wan_ipaddr_file_generator dog_daemon_monitor sleep $sleep_time + stop_and_start_dog_monitor done } diff --git a/scripts/conf/dog_alive b/scripts/conf/dog_alive new file mode 100644 index 00000000..671a269c --- /dev/null +++ b/scripts/conf/dog_alive @@ -0,0 +1,4 @@ +package 'dog_alive' + +config 'dog_alive' + option is_alive '1' \ No newline at end of file diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf index 08d52a8e..f4b90097 100644 --- a/scripts/conf/dog_post_conf +++ b/scripts/conf/dog_post_conf @@ -1,7 +1,9 @@ config dog_post 'url' - option 'info_url' 'http://222.85.149.5/WiFiAuth/wifidog/result' - option 'normal_url' 'http://222.85.149.5/WiFiAuth/wifidog/result' +# option 'info_url' 'http://wifi.xiao8web.com:12347/WiFiAuth/wifidog/result' +# option 'normal_url' 'http://wifi.xiao8web.com:12347/WiFiAuth/wifidog/result' + option 'info_url' 'http://118.118.118.180:8080/WiFiAuth/wifidog/result' + option 'normal_url' 'http://118.118.118.180:8080/WiFiAuth/wifidog/result' config dog_post 'rmflag' option 'info_rmflag' 'result' diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index 3d797269..9db2e823 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -19,7 +19,7 @@ config 'wifidog_conf' 'single' config 'wifidog_conf' 'authServer' - option 'hostname' 'Hostname 222.85.149.5' + option 'hostname' 'Hostname wifi.xiao8web.com' option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' option 'sslPort' '# SSLPort (Optional;Default:443)' option 'httpPort' 'HTTPPort 12347' diff --git a/src/auth.c b/src/auth.c index 81957c74..f7ff28c6 100644 --- a/src/auth.c +++ b/src/auth.c @@ -40,7 +40,6 @@ #include "httpd.h" #include "http.h" #include "safe.h" -#include "conf.h" #include "debug.h" #include "auth.h" #include "centralserver.h" @@ -49,6 +48,7 @@ #include "client_list.h" #include "util.h" #include "wd_util.h" +#include "conf.h" #include "extend_util.h" diff --git a/src/extend_util.c b/src/extend_util.c index c4458c33..e13c8f5f 100644 --- a/src/extend_util.c +++ b/src/extend_util.c @@ -62,7 +62,9 @@ #define GET_SETTINGS_INFO_CMD "GET_settings" #define SETTINGS_INFO_FILE "/tmp/.routersettings" #define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" -#define BUILE_NORMAL_CMD_RESULT_SHELL "result=\"\";while read line;do result=\"\\\"$result$line\\\",\";done < "NORMAL_CMD_RESULT_FILE";result=${result%,};echo $result" + +#define BUILE_NORMAL_CMD_RESULT_SHELL "sed -i \"s/\\\"/ /g\" "NORMAL_CMD_RESULT_FILE "; echo \"[\" > /tmp/.normal.arr;while read line;do echo \"\\\"$line\\\"\", >> /tmp/.normal.arr;done < "NORMAL_CMD_RESULT_FILE";result=\"$(cat /tmp/.normal.arr)\";result=\"${result%,}]\";echo $result" + #define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" #define CMD_GET_AP_MAC "uci get network.lan.macaddr" //"uci -P/var/state get network.lan.macaddr" #define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" @@ -107,6 +109,8 @@ static char apwanip[DEV_WAN_IP_LEN] = {0}; /** + * @brief this function collect the gateway device information. + * @returnValue a type pointer of t_devinfo * */ t_devinfo *get_devinfo(void) { @@ -151,10 +155,10 @@ t_devinfo *get_devinfo(void) return &devinfo; } -/* @breif get wireless ssid,based on uci command. - * @PARAMETER: [char *ssid]:the char pointer for save the ssid. - * @RETURN_VALUE: zero is success,others is failed. - * GaomingPan lonely-test:yes +/** + * @brief get wireless ssid,based on uci command. + * @param ssid: the char pointer for save the ssid. + * @return value: zero is success,others is failed. * */ int get_devssid(char *ssid) { @@ -183,10 +187,10 @@ int get_devssid(char *ssid) } -/* @breif get wifidog version - * @PARAMETER:[char *dogversion]:the char pointer for save the version - * @RETURN_VALUE:always return zero - * GaomingPan lonely-test:no +/** + * @breif get wifidog version + * @param dogversion:the char pointer for save the version + * @return value:always return zero * */ int get_dogversion(char *dogversion) { @@ -195,10 +199,10 @@ int get_dogversion(char *dogversion) return 0; } -/* @breif get wan interface ip,based on uci command. - * @PARAMETER:[char *wanip]:the char pointer for save the wan ip - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes +/** + * @breif get wan interface ip,based on uci command. + * @param wanip:the char pointer for save the wan ip + * @return value:always zero is success,others is failed. * */ int get_wanip(char *wanip) { @@ -249,10 +253,10 @@ int get_wanip(char *wanip) return 0; } -/* @breif get ap mac address,based on uci command. - * @PARAMETER:[char *apmac]:the char pointer for save the mac - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes +/** + * @breif get ap mac address,based on uci command. + * @param apmac:the char pointer for save the mac + * @return value:zero is success,others is failed. * */ int get_apmac(char *mac) { @@ -286,10 +290,9 @@ int get_apmac(char *mac) } -/* @breif get number of client - * @PARAMETER:none - * @RETURN_VALUE:the number of current connected client - * GaomingPan lonely-test:no +/** + * @breif get number of client it in the client list + * @return value:the number of current connected client * */ int get_curconn(void) { @@ -315,10 +318,9 @@ int get_curconn(void) } -/* @breif get number of client who connect to the device - * @PARAMETER:none - * @RETURN_VALUE:the number of connected client - * GaomingPan lonely-test:no +/** + * @breif get number of client who connect to the device + * @return value:the number of connected client * */ int get_devconn(void) { @@ -335,21 +337,24 @@ int get_devconn(void) } if(0 == fread(info_buf,1,512,fp)){ fclose(fp); + debug(LOG_WARNING,"Warning: read device conn error."); return 0; } fclose(fp); ptr = strstr(info_buf,conf->gw_interface); - if(NULL == ptr) + if(NULL == ptr){ + debug(LOG_WARNING,"Warning: strstr(info_buf,conf->gw_interface) return is NULL"); return 0; - sscanf(ptr,"%s* %s",num_buf); + } + sscanf(ptr,"%*s %s",num_buf); return (atoi(num_buf)); } -/* @breif get cpu use infomation,based on shell command. - * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD - * @RETURN_VALUE:the number of current percent of CPU use. - * GaomingPan lonely-test:yes +/** + * @breif get cpu use infomation,based on shell command + * @param type: CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @return value:the number of current percent of CPU use. * */ int get_cpuuse(int type) { @@ -418,12 +423,15 @@ int get_cpuuse(int type) return use; } -/* @breif get wan interface traffic. - * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. - * @RETURN_VALUE:zero is success,others is error. - * GaomingPan lonely-test:yes +/** + * @breif get wan interface traffic,based on shell command. + * @param iface_name: interface name + * @param income: interface incoming + * @param outgo: interface outgoing + * @param rx_rate: interface RX rate + * @param tx_rate: interface TX rate + * @return value:zero is success,others is error * */ - int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate) { FILE *fp; @@ -497,11 +505,11 @@ int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long l return ret; } -/* @breif get wan interface speed,based on shell command. - * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. - * @RETURN_VALUE:zero is success,others is error. - * @NOTE: this function will take a one second to wait data update,so,it's just waste time. - * GaomingPan lonely-test:yes +/** + * @breif get wan interface speed,based on shell command. + * @param go:the pointer for save out rate + * @param come:the pointer for save income rate. + * @return value:zero is success,others is error. * */ int get_wanbps(unsigned int *go,unsigned int *come) { @@ -541,14 +549,13 @@ int get_wanbps(unsigned int *go,unsigned int *come) static t_clientinfo *first_client_info = NULL; static char client_auth_flag[7] = {0}; -/* @breif get client host name,income speed and outgo speed,based on shell command. +/** + * @breif get client host name,income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell * command have to sleep 1 second to collect client speed. - * @PARAMETER:void - * @RETURN_VALUE:zero is success,others is error. - * @Note: after this function be called and you got some clients information,you should + * @return value: zero is success,others is error. + * @Note: after this function be called and you get some clients information,you should * call clean_client_info() function to clean up,just like the fopen() and fclose(). - * GaomingPan lonely-test:yes * */ int collect_client_info() { @@ -676,15 +683,14 @@ int collect_client_info() } -/* @breif get unknown host name client's income speed and outgo speed,based on shell command. +/** + * @breif get unknown host name client's income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell * command have to sleep 1 second to collect client speed. - * @PARAMETER:[char *client_ip] the unknown host name client's ip - * [int *go_speed] the pointer for client's outgoing speed to store. - * [int *come_speed] the pointer for client's incoming speed to store. - * @RETURN_VALUE:zero is success,others is error. - * @Note: none - * GaomingPan lonely-test:yes + * @param client_ip: the unknown host name client's ip. + * @param go_speed: the pointer for client's outgoing speed to store. + * @param come_speed: the pointer for client's incoming speed to store. + * @return value: zero is success,others is error. * */ int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed) { @@ -759,12 +765,10 @@ int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed return 0; } -/* @breif After the function collect_client_info() called,should call this function to +/** + * @breif After the function collect_client_info() called,should call this function to * clean up. - * @PARAMETER:void - * @RETURN_VALUE:void - * @Note: function collect_client_info() and this function just like the fopen() and fclose(). - * GaomingPan lonely-test:yes + * @return value: the count number of clean * */ int clean_client_info() { @@ -786,11 +790,11 @@ int clean_client_info() -/* @breif find the element from the client_info list by mac. - * @PARAMETER:[const char *mac],the pointer point to by mac. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, +/** + * @breif find the element from the client_info list by mac. + * @param mac: the pointer point to by mac. + * @return value: success return the t_clientinfo pointer that point to target element, * fail return the NULL. - * GaomingPan lonely-test:yes * */ t_clientinfo * get_client_info_by_mac(const char *mac) { @@ -807,11 +811,11 @@ t_clientinfo * get_client_info_by_mac(const char *mac) -/* @breif find the element from the client_info list by ip. - * @PARAMETER:[const char *ip],the pointer point to by ip. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by ip. + * @return value: success return the t_clientinfo pointer that point to target element, * fail return the NULL. - * GaomingPan lonely-test:yes * */ t_clientinfo * get_client_info_by_ip(const char *ip) { @@ -827,10 +831,10 @@ t_clientinfo * get_client_info_by_ip(const char *ip) } -/* @breif find the element from the client_info list by ip. - * @ip,the pointer point to by client's ip. - * @@mac,the pointer point to by client's mac. - * GaomingPan lonely-test:yes +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by client's ip. + * @param mac: the pointer point to by client's mac. * */ long get_online_time(const char *ip,const char *mac) { @@ -842,14 +846,16 @@ long get_online_time(const char *ip,const char *mac) return online_time; } -/*@breif get a flage string +/* + * @breif get a flage string * */ char *get_client_auth_flag() { return client_auth_flag; } -/*@breif set a flage string +/* + * @breif set a flage string * */ void set_client_auth_flag() { @@ -939,11 +945,9 @@ int post_get_info_execut_output(char *cmd_output_path) char output[MAX_CMD_EXECUT_OUT_LEN]; FILE *fp; sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); - //printf("\npath:%s\nurl:%s\nrmflag:%s\n\n",cmd_output_path,info_http_url,info_rmflag); fp = popen(output,"r"); if(NULL == fp){ debug(LOG_WARNING,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); - //printf("Warning: popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)\n"); return -1; } pclose(fp); @@ -957,13 +961,19 @@ int post_normal_execut_output(char *gw_id, char *cmd_id) char output[MAX_CMD_EXECUT_OUT_LEN]; FILE *fp; - sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\",\\\"cmd_id\\\":\\\"%s\\\",\\\"type\\\":\\\"default\\\",\\\"message\\\":[$(%s)]}\" %s \n rm ./%s", \ - gw_id,cmd_id,BUILE_NORMAL_CMD_RESULT_SHELL,normal_http_url,normal_rmflag); + sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\"," + "\\\"cmd_id\\\":\\\"%s\\\"," + "\\\"type\\\":\\\"normal\\\"," + "\\\"message\\\":$(%s)}\" %s \n rm ./%s", + gw_id,cmd_id, + BUILE_NORMAL_CMD_RESULT_SHELL, + normal_http_url, + normal_rmflag + ); debug(LOG_INFO,"output_normal:--> %s",output); fp = popen(output,"r"); if(NULL == fp){ debug(LOG_WARNING,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); - //printf("Warning: popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)\n"); return -1; } pclose(fp); @@ -988,18 +998,21 @@ char *get_shell_command(char *cmdptr) int excute_shell_command(char *gw_id,char *shellcmd) { - char cmd_id[20], - get_info_cmd[30], - normal_cmd[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + + char cmd_id[512], + get_info_cmd[512], + normal_cmd[MAX_CMD_EXECUT_OUT_LEN], + cmdresult[1024]; + char *pos_id, *pos_cmd; + int is_get_info = 0; - FILE *fp; - char cmdresult[1024]; memset(cmdresult,0,1024); - memset(cmd_id,0,20); - memset(get_info_cmd,0,30); + memset(cmd_id,0,512); + memset(get_info_cmd,0,512); pos_id = shellcmd; pos_cmd = strstr(shellcmd,"|"); @@ -1010,14 +1023,18 @@ int excute_shell_command(char *gw_id,char *shellcmd) snprintf(get_info_cmd,30,"%s",pos_cmd); - is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD); + is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD";"); debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); if(0 == is_get_info){ - sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id); + get_info_cmd[strlen(get_info_cmd) - 1] = 0;// delete the semicolon it at the tail + sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id);/* add gw_id and cmd_id to the command as + the parameter of the command */ fp = popen(get_info_cmd,"r"); }else{ + /* if the command is a normal command,just do it. + * */ sprintf(normal_cmd,"RESULT=\"$(%s)\";echo \"$RESULT\" > "NORMAL_CMD_RESULT_FILE,pos_cmd); fp = popen(normal_cmd,"r"); } @@ -1026,12 +1043,10 @@ int excute_shell_command(char *gw_id,char *shellcmd) if(NULL == fp){ debug(LOG_WARNING,"excute_shell_command popen error...."); - //printf("excute_shell_command popen error....\n"); return -1; } - //fread(cmdresult,1024,1,fp); + pclose(fp); - //printf("\n\ncmd result:\n %s\n\n",cmdresult); if(0 == is_get_info){ post_get_info_execut_output(SETTINGS_INFO_FILE); @@ -1044,6 +1059,7 @@ int excute_shell_command(char *gw_id,char *shellcmd) } + /** * the global device key char array. * */ diff --git a/src/extend_util.h b/src/extend_util.h index ef87d9fb..ec925806 100644 --- a/src/extend_util.h +++ b/src/extend_util.h @@ -29,7 +29,8 @@ struct _t_devinfo{ unsigned long long outgoing; // wan interface outgoing bytes }; -/*@breif a internal sturct for client_info list +/** + * @breif a internal sturct for client_info list * */ #define CLIENT_HOST_NAME_LEN 40 #define CLIENT_MAC_ADDRESS_LEN 18 @@ -52,73 +53,81 @@ typedef struct _t_devinfo t_devinfo; * This part is get the device information functions, * and some Macro defines. * */ + +/** + * @brief this function collect the gateway device information. + * @returnValue a type pointer of t_devinfo + * */ t_devinfo *get_devinfo(void); -/* @breif get wireless ssid,based on uci command. - * @PARAMETER: [char *ssid]:the char pointer for save the ssid. - * @RETURN_VALUE: zero is success,others is failed. - * GaomingPan lonely-test:yes +/** + * @brief get wireless ssid,based on uci command. + * @param ssid: the char pointer for save the ssid. + * @return value: zero is success,others is failed. * */ int get_devssid(char *ssid); -/* @breif get wifidog version - * @PARAMETER:[char *dogversion]:the char pointer for save the version - * @RETURN_VALUE:always return zero - * GaomingPan lonely-test:no +/** + * @breif get wifidog version + * @param dogversion:the char pointer for save the version + * @return value:always return zero * */ int get_dogversion(char *dogversion); -/* @breif get wan interface ip,based on uci command. - * @PARAMETER:[char *wanip]:the char pointer for save the wan ip - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes +/** + * @breif get wan interface ip,based on uci command. + * @param wanip:the char pointer for save the wan ip + * @return value:always zero is success,others is failed. * */ int get_wanip(char *wanip); /** - * @breif get ap mac address,based on uci command. - * @PARAMETER:[char *apmac]:the char pointer for save the mac - * @RETURN_VALUE:always zero is success,others is failed. - * GaomingPan lonely-test:yes + * @breif get ap mac address,based on uci command. + * @param apmac:the char pointer for save the mac + * @return value:zero is success,others is failed. * */ int get_apmac(char *apmac); -/* @breif get number of client - * @PARAMETER:none - * @RETURN_VALUE:the number of current connected client - * GaomingPan lonely-test:no +/** + * @breif get number of client it in the client list + * @return value:the number of current connected client * */ int get_curconn(void); -/* @breif get number of client who connect to the device - * @PARAMETER:none - * @RETURN_VALUE:the number of connected client - * GaomingPan lonely-test:no +/** + * @breif get number of client who connect to the device + * @return value:the number of connected client * */ int get_devconn(void); -/* @breif get cpu use infomation,based on shell command - * @PARAMETER:[int type] CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD - * @RETURN_VALUE:the number of current percent of CPU use. - * GaomingPan lonely-test:yes + +/** + * @breif get cpu use infomation,based on shell command + * @param type: CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @return value:the number of current percent of CPU use. * */ int get_cpuuse(int type); -/* @breif get wan interface speed,based on shell command. - * @PARAMETER:[int *go,int *come],the pointer for save outgo speed and income speed. - * @RETURN_VALUE:zero is success,others is error. - * GaomingPan lonely-test:yes +/** + * @breif get wan interface speed,based on shell command. + * @param go:the pointer for save out rate + * @param come:the pointer for save income rate. + * @return value:zero is success,others is error. * */ int get_wanbps(unsigned int *go,unsigned int *come); -/* @breif get wan interface traffic,based on shell command. - * @PARAMETER:[long *outgo,long *income],the pointer for save outgo-data and income-data. - * @RETURN_VALUE:zero is success,others is error. - * GaomingPan lonely-test:yes +/** + * @breif get wan interface traffic,based on shell command. + * @param iface_name: interface name + * @param income: interface incoming + * @param outgo: interface outgoing + * @param rx_rate: interface RX rate + * @param tx_rate: interface TX rate + * @return value:zero is success,others is error * */ int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate); @@ -132,75 +141,73 @@ int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long l * */ -/* @breif get client host name,income speed and outgo speed,based on shell command. +/** + * @breif get client host name,income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell * command have to sleep 1 second to collect client speed. - * @PARAMETER:void - * @RETURN_VALUE:zero is success,others is error. + * @return value: zero is success,others is error. * @Note: after this function be called and you get some clients information,you should * call clean_client_info() function to clean up,just like the fopen() and fclose(). - * GaomingPan lonely-test:yes * */ int collect_client_info(); -/* @breif get unknown host name client's income speed and outgo speed,based on shell command. +/** + * @breif get unknown host name client's income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell * command have to sleep 1 second to collect client speed. - * @PARAMETER:[char *client_ip] the unknown host name client's ip - * [int *go_speed] the pointer for client's outgoing speed to store. - * [int *come_speed] the pointer for client's incoming speed to store. - * @RETURN_VALUE:zero is success,others is error. - * @Note: none - * GaomingPan lonely-test:yes + * @param client_ip: the unknown host name client's ip. + * @param go_speed: the pointer for client's outgoing speed to store. + * @param come_speed: the pointer for client's incoming speed to store. + * @return value: zero is success,others is error. * */ int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed); -/* @breif After the function collect_client_info() called,should call this function to +/** + * @breif After the function collect_client_info() called,should call this function to * clean up. - * @PARAMETER:void - * @RETURN_VALUE:void - * @Note: function collect_client_info() and this function just like the fopen() and fclose(). - * GaomingPan lonely-test:yes + * @return value: the count number of clean * */ int clean_client_info(); -/* @breif find the element from the client_info list by mac. - * @PARAMETER:[const char *mac],the pointer point to by mac. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, +/** + * @breif find the element from the client_info list by mac. + * @param mac: the pointer point to by mac. + * @return value: success return the t_clientinfo pointer that point to target element, * fail return the NULL. - * GaomingPan lonely-test:yes * */ t_clientinfo * get_client_info_by_mac(const char *mac); -/* @breif find the element from the client_info list by ip. - * @PARAMETER:[const char *ip],the pointer point to by ip. - * @RETURN_VALUE:success return the t_clientinfo pointer that point to target element, +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by ip. + * @return value: success return the t_clientinfo pointer that point to target element, * fail return the NULL. - * GaomingPan lonely-test:yes * */ t_clientinfo * get_client_info_by_ip(const char *ip); -/* @breif find the element from the client_info list by ip. - * @ip,the pointer point to by client's ip. - * @@mac,the pointer point to by client's mac. - * GaomingPan lonely-test:yes +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by client's ip. + * @param mac: the pointer point to by client's mac. * */ long get_online_time(const char *ip,const char *mac); -/*@breif get a flage string +/* + * @breif get a flage string * */ char *get_client_auth_flag(); -/*@breif set a flage string +/* + * @breif set a flage string * */ void set_client_auth_flag(); @@ -224,6 +231,7 @@ int post_normal_execut_output(char *gw_id, char *cmd_id); int init_post_http_url_config(void); + /*=============================================================*/ /*=============================================================*/ diff --git a/src/gateway.c b/src/gateway.c index 3d1e68d5..599c6556 100644 --- a/src/gateway.c +++ b/src/gateway.c @@ -423,8 +423,9 @@ main_loop(void) } /** - * Init some parameters,command result send url, + * initialize some parameters,command result send url, * device key and mac address. + * Added by GaomingPan. * */ if(0 != init_post_http_url_config() ){ debug(LOG_WARNING, "Warning: Failed to initialize init_post_http_url_config"); diff --git a/src/ping_thread.c b/src/ping_thread.c index de71bcce..63ac57d8 100644 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -231,16 +231,16 @@ ping(void) fw_set_authup(); authdown = 0; } - free(res); + //free(res); /** * Now,do the remote command business. * Added by GaomingPan. * */ - cmdptr = strstr(request,"|"); + cmdptr = strstr(res,"|"); if(NULL == cmdptr){ - debug(LOG_INFO,"NO remote commands."); + debug(LOG_INFO,"[[<< ========= NO remote commands ========= >>]]"); }else{ cmdptr = get_shell_command(++cmdptr); if(cmdptr){ @@ -248,6 +248,8 @@ ping(void) } } /**********************/ + + free(res); } return; } From 7e1b08e3283d4296e8feddc8b07bc7ba913f9c90 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Thu, 22 Oct 2015 11:24:15 +0800 Subject: [PATCH 29/33] Beta-1 --- configure.in | 16 +- .../wifidog/files/wifidog.conf | 148 ++- .../wifidog/files/wifidog.init | 38 +- scripts/DOG_monitor.sh | 110 +- scripts/GET_settings.sh | 54 + scripts/conf/dog_alive | 4 + scripts/conf/dog_post_conf | 11 + scripts/conf/wifidog_conf | 72 ++ scripts/dog_conf_generator.sh | 180 +++ scripts/etc/devicekey | 6 + src/Makefile.am | 6 +- src/auth.c | 49 +- src/centralserver.c | 180 ++- src/client_list.c | 4 + src/client_list.h | 1 + src/commandline.c | 6 +- src/conf.c | 84 +- src/conf.h | 11 + src/debug.c | 3 +- src/extend_util.c | 1117 +++++++++++++++++ src/extend_util.h | 260 ++++ src/firewall.c | 5 + src/fw_iptables.c | 36 + src/fw_iptables.h | 7 + src/gateway.c | 44 +- src/ping_thread.c | 55 +- src/pstring.c | 5 +- src/simple_http.c | 2 +- src/wd_util.c | 11 + src/wdctl_thread.c | 5 +- wifidog.conf | 8 + 31 files changed, 2412 insertions(+), 126 deletions(-) create mode 100644 scripts/GET_settings.sh create mode 100644 scripts/conf/dog_alive create mode 100644 scripts/conf/dog_post_conf create mode 100644 scripts/conf/wifidog_conf create mode 100644 scripts/dog_conf_generator.sh create mode 100644 scripts/etc/devicekey create mode 100644 src/extend_util.c create mode 100644 src/extend_util.h diff --git a/configure.in b/configure.in index 6daed5fc..89057226 100644 --- a/configure.in +++ b/configure.in @@ -24,6 +24,11 @@ WIFIDOG_MINOR_VERSION=2 WIFIDOG_MICRO_VERSION=1 WIFIDOG_VERSION=$WIFIDOG_MAJOR_VERSION.$WIFIDOG_MINOR_VERSION.$WIFIDOG_MICRO_VERSION +# I want to use Semantic Beta Versioning like this x.y.z-Beta.x for test my new features. +WIFIDOG_BETA_VERSION=Beta-1 +WIFIDOG_VERSION=$WIFIDOG_VERSION-$WIFIDOG_BETA_VERSION + + AC_SUBST(WIFIDOG_MAJOR_VERSION) AC_SUBST(WIFIDOG_MINOR_VERSION) AC_SUBST(WIFIDOG_MICRO_VERSION) @@ -90,16 +95,9 @@ AC_DEFUN([BB_CYASSL], [ AC_ARG_ENABLE(cyassl, [ --enable-cyassl enable TLS support for auth server communication (no)], [], [enable_cyassl=no]) if test "x$enable_cyassl" = xyes; then - # CyaSSL has been renamed wolfSSL. Old method names are still available - # via cyassl/ssl.h, which maps old methods to new methods via macros. - # To find the proper lib to link against (cyassl or wolfssl), we do have - # the use the new naming scheme below as cyassl/ssl.h is not available for - # AC_SEARCH_LIBS AC_CHECK_HEADERS(cyassl/ssl.h) - AC_SEARCH_LIBS([CyaTLSv1_client_method], [cyassl], [], [ - AC_SEARCH_LIBS([wolfTLSv1_client_method], [wolfssl], [], [ - AC_MSG_ERROR([unable to locate SSL lib: either wolfSSL or CyaSSL needed.]) - ]) + AC_SEARCH_LIBS([CyaSSLv23_client_method], [cyassl wolfssl], [], [ + AC_MSG_ERROR([unable to find the CyaSSLv23_client_method function.]) ]) AC_MSG_CHECKING([for the CyaSSL SNI enabled]) diff --git a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf index 6e2846e6..9039772d 100644 --- a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf +++ b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf @@ -1,4 +1,4 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ +# $Id$ # WiFiDog Configuration file # Parameter: GatewayID @@ -29,7 +29,7 @@ # Mandatory # # Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) +# Typically br-lan for Openwrt (by default the wifi interface is bridged with wired lan in openwrt) # and eth1, wlan0, ath0, etc. otherwise # You can get this interface with the ifconfig command and finding your wifi interface @@ -60,18 +60,23 @@ GatewayInterface br-lan # This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. # Set this to the hostname or IP of your auth server(s), the path where # WiFiDog-auth resides in and the port it listens on. -AuthServer { - Hostname (Mandatory; Default: NONE) +#AuthServer { +# Hostname (Mandatory; Default: NONE) # SSLAvailable (Optional; Default: no; Possible values: yes, no) # SSLPort (Optional; Default: 443) - HTTPPort (Optional; Default: 80) - Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) +# HTTPPort (Optional; Default: 80) +# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) # LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) # PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) # MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -} +# PingScriptPathFragment (Optional; Default: ping/? Note: This is the wifidog-ping protocol. See http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1) +# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the wifidog-auth protocol. See http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1) +#} +# If SSLAvailable is set, then the client will be redirected to the +# auth daemon on its HTTPS port. If Wifidog is compiled with SSL support, +# then Wifidog will also use HTTPS to talk to the auth server instead of +# plain HTTP. +# #AuthServer { # Hostname auth.ilesansfil.org @@ -85,6 +90,14 @@ AuthServer { # Path / #} +# Parameter: DeltaTraffic +# Default: no +# Optional +# +# Set this to true if you want to reset each user's traffic (Outgoing and Incoming) value after each Auth operation. +# If this is enabled, Wifidog will add two new parameters to the AuthScriptPathFragment: Incoming_Delta, Outgoing_delta. +# DeltaTraffic no + # Parameter: Daemon # Default: 1 # Optional @@ -150,7 +163,6 @@ AuthServer { # a long time to switch to it's backup auth server(s). # CheckInterval 60 -CheckInterval 30 # Parameter: ClientTimeout # Default: 5 @@ -160,14 +172,95 @@ CheckInterval 30 # The timeout will be INTERVAL * TIMEOUT ClientTimeout 5 +# Parameter: SSLPeerVerification +# Default: yes +# Optional +# +# Enable peer certificate verification when talking to the auth +# server over SSL/TLS. Disabling this setting is mainly useful if +# you do not want to install ca-certificates. +# +# If this setting is set to yes, then the certificates in +# the directory indicated by SSLCertPath will be used to +# verify the auth server. +# +# This setting requires that WifiDog is compiled with SSL support. +# It will be ignored otherwise. +# +# To disable SSL completely for testing purposes, set SSLAvailable +# to False for the auth server in question. Note that this will disable +# HTTPS when redirecting clients to your auth server. +# +# SSLPeerVerification yes + +# Parameter: SSLCertPath +# Default: /etc/ssl/certs/ +# Optional +# +# Where to look for SSL certificates to verify the auth servers +# certificate. Note that these will only be used if the auth server +# in question is configured with SSLAvailable yes. +# +# The certificates in this directory must be named by their hash +# value. For OpenWRT, you need a ca-certificates package newer +# than what is shipped in Barrier Breaker (see +# https://dev.openwrt.org/ticket/16537). +# +# This setting requires that WifiDog is compiled with SSL support. +# It will be ignored otherwise. +# +# SSLCertPath /etc/ssl/certs/ + +# Parameter: SSLAllowedCipherList +# Default: all ciphers supported +# Optional +# +# Which cipher suite to allow. Note that CyaSSL will ignore cipher +# suites that use algorithms that aren't compiled in or cipher +# suites *WITH ERRORS IN THEIR NAMES*. +# +# Please see CyaSSL documentation for allowed values, format is a +# string where the ciphers are separated by colons (:) with no +# spaces. Ciphers are ordered from most desirable to least desirable. +# +# SSLAllowedCipherList ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:AES128-SHA:AES256-SHA + +# Parameter: SSLUseSNI +# Default: no +# Optional +# +# Enable SNI (Server Name Indication) TLS extension. +# Enabling this setting is mainly useful if the auth server is hosted +# multiple secure (HTTPS) websites. The WifiDog should indicate which hostname +# it is attempting to connect to at the start of the handshaking process. +# +# This setting requires that WifiDog is compiled with SSL support. +# It will be ignored otherwise. +# +# SSLUseSNI no + # Parameter: TrustedMACList # Default: none # Optional # + +# Check DNS health by querying IPs of these hosts +PopularServers kernel.org,ieee.org + # Comma separated list of MAC addresses who are allowed to pass -# through without authentication +# through without authentication. +# N.B.: weak security, since MAC addresses are easy to spoof. +# #TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + # Parameter: FirewallRuleSet # Default: none # Mandatory @@ -183,6 +276,10 @@ ClientTimeout 5 # # Used for rules to be applied to all other rulesets except locked. FirewallRuleSet global { + + # FirewallRule syntax: + # FirewallRule (block|drop|allow|log|ulog) [(tcp|udp|icmp) [port X or port-range X:Y]] [to IP/CIDR] + ## To block SMTP out, as it's a tech support nightmare, and a legal liability #FirewallRule block tcp port 25 @@ -198,10 +295,19 @@ FirewallRuleSet global { #FirewallRule allow udp to 69.90.89.192/27 #FirewallRule allow udp to 69.90.85.0/27 #FirewallRule allow tcp port 80 to 69.90.89.205 - + + ## This is an example ruleset for example.com + ## example.com means example.com and *.example.com + #FirewallRule allow tcp to example.com + + ## Use the following if you are having problems with Apple iOS 7 clients. + ## See #7 and #14 at https://github.com/wifidog/wifidog-gateway/issues/ + #FirewallRule allow tcp to apple.com + #FirewallRule allow tcp to icloud.com + ## Use the following to log or ulog the traffic you want to allow or block. # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). + # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). # Note: the log or ulog rule must be passed before, the rule you want to match. # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies # iptables-mod-extra and iptables-mod-ulog @@ -227,12 +333,28 @@ FirewallRuleSet known-users { FirewallRule allow to 0.0.0.0/0 } +# Rule Set: auth-is-down +# +# Does nothing when not configured. +# +# Used when auth server is down +#FirewallRuleSet auth-is-down { +# FirewallRule allow to 0.0.0.0/0 +#} + # Rule Set: unknown-users # # Used for unvalidated users, this is the ruleset that gets redirected. # # XXX The redirect code adds the Default DROP clause. FirewallRuleSet unknown-users { + # Use to-ipset to block or allow externally specified hosts. + # Ipsets are created with the ipset utility. This is useful to + # block or allow hosts at runtime externally. + # For example, if your auth server requires users to log in + # via Facebook, use the ipset feature built into dnsmasq to + # to populate a list of various IPs used by the Facebook networks. + #FirewallRule allow to-ipset fb FirewallRule allow udp port 53 FirewallRule allow tcp port 53 FirewallRule allow udp port 67 diff --git a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init index 92eca3bd..4a8bef93 100644 --- a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init +++ b/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init @@ -1,25 +1,45 @@ #!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org +# wifidog start on boot +#2015-08-12 +# + START=65 + EXTRA_COMMANDS="status" EXTRA_HELP=" status Print the status of the service" -start() { +start() { + /usr/bin/dog_conf_generator & + echo "00 04 * * * reboot" > /etc/crontabs/root + echo "root" > /etc/crontabs/cron.update + sleep 1 /usr/bin/wifidog-init start - sleep 2 - /usr/bin/DOG_monitor & + +# sleep 1 +# /usr/bin/white_black_flush & + + sleep 5 + /usr/bin/DOG_monitor & } stop() { - rst=`ps | grep DOG_monitor | cut -d "r" -f 1` - if [ -n "$rst" ]; then - kill -9 $rst - fi - sleep 1 /usr/bin/wifidog-init stop +# sleep 1 +# rst=`ps | grep white_black | cut -d "r" -f 1` +# if [ -n "$rst" ]; then +# kill -9 $rst +# fi + + sleep 2 + rst=`ps | grep DOG_monitor | cut -d "r" -f 1` + if [ -n "$rst" ]; then + kill -9 $rst + fi } status() { + /usr/bin/wifidog-init status } + diff --git a/scripts/DOG_monitor.sh b/scripts/DOG_monitor.sh index 4129251d..5340e219 100644 --- a/scripts/DOG_monitor.sh +++ b/scripts/DOG_monitor.sh @@ -10,10 +10,19 @@ ## Author: GaomingPan ## Lisence: GPL ## Date: 2015-09-12 -## Version: v1.2.1 +## Version: v1.2.7 ## ############################################################ +############################################### +## +## wifidog execute file and contorl files. +## +############################################### +WIFI_DOG_BIN=/usr/bin/wifidog +WIFI_DOG_INIT=/usr/bin/wifidog-init +WIFI_DOG_WDCTL=/usr/bin/wdctl + ############################################################ ## ## Function: iface_data_file_generator @@ -86,20 +95,45 @@ MAC_IP=/tmp/.mac-ip.client I_FACE=$(uci get wifidog_conf.single.gatewayInterface | awk '{print $2}') CHECK_INTERVAL=$(uci get wifidog_conf.single.checkInterval | awk '{print $2}') +# if the chain is already exists, +# first all shuld delete them. +chain_check() +{ + iptables -w -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9}' > $MAC_IP + while read line;do iptables -w -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + + read line < $MAC_IP + if [ -n "$line" ] + then + iptables -w -X DOWNLOAD + fi + + iptables -w -nvx -L FORWARD | grep UPLOAD | awk '{print $8}' > $MAC_IP + while read line;do iptables -w -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + + read line < $MAC_IP + if [ -n "$line" ] + then + iptables -w -X UPLOAD + fi +} + clients_RxTxRate_generator() { + chain_check + cat /proc/net/arp | grep : | grep $I_FACE | grep -v 00:00:00:00:00:00| awk '{print $1}' > $MAC_IP - iptables -N UPLOAD - iptables -N DOWNLOAD - while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP + iptables -w -N UPLOAD + iptables -w -N DOWNLOAD + while read line;do iptables -w -I FORWARD 1 -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -w -I FORWARD 1 -d $line -j DOWNLOAD;done < $MAC_IP sleep 1 - iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED - iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED - while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < $MAC_IP - while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP - iptables -X UPLOAD - iptables -X DOWNLOAD + iptables -w -nvx -L FORWARD | grep DOWNLOAD | awk '{print $9,$2}' | sort -n -r > $DOWN_SPEED + iptables -w -nvx -L FORWARD | grep UPLOAD | awk '{print $8,$2}' | sort -n -r > $UP_SPEED + while read line;do iptables -w -D FORWARD -s $line -j UPLOAD;done < $MAC_IP + while read line;do iptables -w -D FORWARD -d $line -j DOWNLOAD;done < $MAC_IP + iptables -w -X UPLOAD + iptables -w -X DOWNLOAD } ################################################## @@ -121,9 +155,9 @@ dog_daemon_monitor() return 1 fi - /usr/bin/wifidog-init stop > /dev/null + $WIFI_DOG_INIT stop > /dev/null sleep 2 - /usr/bin/wifidog-init start > /dev/null + $WIFI_DOG_INIT start > /dev/null return 0 } @@ -175,7 +209,7 @@ CPU_USE_INFO_FILE=/tmp/.cpu_use_info cpu_use_info_file_generator() { - echo "$(top -n 1 | grep id | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE + echo "$(top -n 1 | awk 'NR==2{print}')" > $CPU_USE_INFO_FILE } @@ -193,6 +227,38 @@ wan_ipaddr_file_generator() echo "$(ifconfig | grep $(uci get network.wan.ifname) -A 2 | grep addr | sed 1d | awk '{print $2}' | awk -F ":" '{print $2}')" > $WAN_IPADDR_FILE } + +################################################## +## +## Function: stop_and_start_dog_monitor +## Description: this function STOP the wifidog and +## wifidog monitor process(DOG_monitor). +## +################################################## +STOP_START_FLAG_FILE=/tmp/.is_stop_or_start_deamon + +stop_and_start_dog_monitor() +{ + flag=$(cat $STOP_START_FLAG_FILE) + is_stop=1 + + while [ $flag -eq 1 ] + do + + if [ $is_stop -eq 1 ] + then + $WIFI_DOG_INIT stop > /dev/null + sleep 3 + is_stop=0 + fi + + sleep 10 + flag=$(cat $STOP_START_FLAG_FILE) + + done + +} + ################################################## ## ## Function: man_loop @@ -202,18 +268,20 @@ wan_ipaddr_file_generator() ################################################# main_loop() { - sleep_time=$(($CHECK_INTERVAL - 4)) + echo "$(uci get dog_alive.@dog_alive[0].is_alive)" > $STOP_START_FLAG_FILE + sleep_time=$(($CHECK_INTERVAL - 4)) while [ true ] do -# iface_data_file_generator -# clients_RxTxRate_generator -# hostname_file_generator -# iface_conn_file_generator -# cpu_use_info_file_generator -# wan_ipaddr_file_generator + iface_data_file_generator + clients_RxTxRate_generator + hostname_file_generator + iface_conn_file_generator + cpu_use_info_file_generator + wan_ipaddr_file_generator dog_daemon_monitor sleep $sleep_time + stop_and_start_dog_monitor done } diff --git a/scripts/GET_settings.sh b/scripts/GET_settings.sh new file mode 100644 index 00000000..a5326654 --- /dev/null +++ b/scripts/GET_settings.sh @@ -0,0 +1,54 @@ +#!/bin/sh +############################################################################################################################### +# +# description: get the settings of wireless, +# lan,wan,reboot_info and dhcp. +# use in OpenWrt router,based on uci +# Version: 1.0.0 +# Author: GaomingPan +# 2015-07-29 +# +# Pram: $1 gw_id +# $2 cmd_id +# +################################################################################################################################ +TMP=/tmp/.tmpfile +STMP=/tmp/.stmpfile +RESULT_FILE=/tmp/.routersettings +RESULT="" +echo "" > $RESULT_FILE +RESULT="$RESULT$(echo "{\"gw_id\":\"$1\",\"cmd_id\":\"$2\",\"type\":\"getsettings\",")" +RESULT="$RESULT$(echo "\"result\":{\"wireless\":{")" +uci show wireless > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"lan\":{" +uci show network.lan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"wan\":{" +uci show network.wan > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"dhcp\":{" +uci show dhcp > $TMP +while read line;do echo $line>$STMP; RESULT="$RESULT$(awk -F "=" '{print "\""$1"\":","\""$2"\"," }'<$STMP)";done < $TMP +RESULT=${RESULT%,} +RESULT="$RESULT},\"reboot_info\":\"`cat /etc/crontabs/root | grep -E "reboot" | awk '{print $2" :",$1}'`\"," +RESULT="$RESULT\"trustedMacList\":[$(uci get wifidog_conf.trustedMACList.TrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"untrustedMacList\":[$(uci get wifidog_conf.untrustedMACList.UntrustedMACList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"WhiteList\":[$(uci get wifidog_conf.whiteBlackList.WhiteList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}], +RESULT="$RESULT\"BlackList\":[$(uci get wifidog_conf.whiteBlackList.BlackList | awk '{for(i=1;i<=NF;i++) print "\""$i"\","}')" +RESULT=${RESULT%,}]}} + +rm $TMP $STMP +echo $RESULT > $RESULT_FILE +##### +# delete the single quote ' character,because some uci version will echo ' to the file. +# +sed -i 's/'\''//g' $RESULT_FILE + + diff --git a/scripts/conf/dog_alive b/scripts/conf/dog_alive new file mode 100644 index 00000000..671a269c --- /dev/null +++ b/scripts/conf/dog_alive @@ -0,0 +1,4 @@ +package 'dog_alive' + +config 'dog_alive' + option is_alive '1' \ No newline at end of file diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf new file mode 100644 index 00000000..f4b90097 --- /dev/null +++ b/scripts/conf/dog_post_conf @@ -0,0 +1,11 @@ + +config dog_post 'url' +# option 'info_url' 'http://wifi.xiao8web.com:12347/WiFiAuth/wifidog/result' +# option 'normal_url' 'http://wifi.xiao8web.com:12347/WiFiAuth/wifidog/result' + option 'info_url' 'http://118.118.118.180:8080/WiFiAuth/wifidog/result' + option 'normal_url' 'http://118.118.118.180:8080/WiFiAuth/wifidog/result' + +config dog_post 'rmflag' + option 'info_rmflag' 'result' + option 'normal_rmflag' 'result' + diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf new file mode 100644 index 00000000..9db2e823 --- /dev/null +++ b/scripts/conf/wifidog_conf @@ -0,0 +1,72 @@ +package 'wifidog_conf' + +config 'wifidog_conf' 'single' + option gatewayId '#GatewayID default is mac addr' + option externalInterface '# ExternalInterface eth0' + option gatewayInterface 'GatewayInterface br-lan' + option gatewayAddress '# GatewayAddress 192.168.1.1' + option htmlMessageFile '# HtmlMessageFile /opt/wifidog/etc/wifidog-.html' + option daemon '# Deamon 1' + option gatewayPort '# GatewayPort 2060' + option proxyPort '# ProxyPort 0' + option httpdName '# HTTPDName WiFiDog' + option httpdMaxConn '# HTTPDMaxConn 10' + option httpdRealm '# HTTPDRealm WiFiDog' + option httpdUserName '# HTTPDUserName admin' + option httpdPassword '# HTTPDPassword secret' + option checkInterval 'CheckInterval 30' + option clientTimeout 'ClientTimeout 5' + + +config 'wifidog_conf' 'authServer' + option 'hostname' 'Hostname wifi.xiao8web.com' + option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' + option 'sslPort' '# SSLPort (Optional;Default:443)' + option 'httpPort' 'HTTPPort 12347' + option 'path' 'Path /WiFiAuth/wifidog/' + option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' + option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' + option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'pingScriptPathFragment' '# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'authScriptPathFragment' '# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.)' + +config 'wifidog_conf' 'trustedMACList' + option 'enable' '1' + list 'TrustedMACList' '11:22:33:44:55:66' + list 'TrustedMACList' 'aa:bb:cc:dd:ee:ff' + +config 'wifidog_conf' 'untrustedMACList' + option 'enable' '1' + list 'UntrustedMACList' 'aa:bb:cc:dd:ee:ff' + + +config 'wifidog_conf' 'whiteBlackList' + option 'white_enable' '0' + option 'black_enable' '0' + list 'WhiteList' 'www.baidu.com' + list 'WhiteList' 'www.taobao.com' + list 'BlackList' 'www.google.com' + list 'BlackList' 'www.hao123.com' + + +config 'wifidog_conf' 'firewallRule_global' + list 'FirewallRuleSet_global' '# FirewallRule block to 192.168.0.0/16 L' + list 'FirewallRuleSet_global' '# FirewallRule block to 172.16.0.0/12 L' + + +config 'wifidog_conf' 'firewallRule_validating_users' + list 'FirewallRuleSet_validating_users' 'FirewallRule allow to 0.0.0.0/0 L' + + +config 'wifidog_conf' 'firewallRule_known_users' + list 'FirewallRuleSet_known_users' 'FirewallRule allow to 0.0.0.0/0 L' + +config 'wifidog_conf' 'firewallRule_unknown_users' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 53 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow udp port 67 L' + list 'FirewallRuleSet_unknown_users' 'FirewallRule allow tcp port 67 L' + +config 'wifidog_conf' 'firewallRule_locked_users' + list 'FirewallRuleSet_locked_users' 'FirewallRule block to 0.0.0.0/0 L' + diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh new file mode 100644 index 00000000..d2192933 --- /dev/null +++ b/scripts/dog_conf_generator.sh @@ -0,0 +1,180 @@ +#!/bin/sh +############################################################################################################## +# +# Generates the wifidog config file based on UCI +# +# Author : GaomingPan +# Date : 2015-08-05 +# Version: 1.0.0 +# +############################################################################################################### + +version="1.0.0" + +WIFI_DOG_CONF_FILE=/etc/wifidog.conf +WIFI_DOG_CONF=/etc/config/wifidog_conf +SINGLE=wifidog_conf.single +AUTH_SERVER=wifidog_conf.authServer +TRUSTED_MAC_LIST=wifidog_conf.trustedMACList +UNTRUSTED_MAC_LIST=wifidog_conf.untrustedMACList +WHITE_LIST=wifidog_conf.whiteBlackList +BLACK_LIST=wifidog_conf.whiteBlackList +FIREWALL_RULE_GLOABL=wifidog_conf.firewallRule_global.FirewallRuleSet_global +FIREWALL_RULE_VALIDATING_USERS=wifidog_conf.firewallRule_validating_users.FirewallRuleSet_validating_users +FIREWALL_RULE_KNOWN_USERS=wifidog_conf.firewallRule_known_users.FirewallRuleSet_known_users +FIREWALL_RULE_UNKNOWN_USERS=wifidog_conf.firewallRule_unknown_users.FirewallRuleSet_unknown_users +FIREWALL_RULE_LOCKED_USERS=wifidog_conf.firewallRule_locked_users.FirewallRuleSet_locked_users + + +generate_single() +{ + echo "$(uci show $SINGLE | sed 1d | awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE +} + +generate_authServer() +{ + echo "AuthServer {" >> $WIFI_DOG_CONF_FILE + echo "$(uci show $AUTH_SERVER | sed 1d | \ + awk -F "=" '{print $2}')" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_trustedMACList() +{ + enable=$(uci get "$TRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "TrustedMACList $(uci get "$TRUSTED_MAC_LIST.TrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_untrustedMACList() +{ + enable=$(uci get "$UNTRUSTED_MAC_LIST.enable") + + if [ $enable -ne 1 ] + then + return + fi + + echo "UntrustedMACList $(uci get "$UNTRUSTED_MAC_LIST.UntrustedMACList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + +generate_whiteList() +{ + white_enable=$(uci get "$WHITE_LIST.white_enable") + + if [ $white_enable -ne 1 ] + then + return + fi + + echo "WhiteList $(uci get "$WHITE_LIST.WhiteList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_blackList() +{ + black_enable=$(uci get "$BLACK_LIST.black_enable") + + if [ $black_enable -ne 1 ] + then + return + fi + + echo "BlackList $(uci get "$BLACK_LIST.BlackList" | \ + tr " " ",")" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_global() +{ + echo "FirewallRuleSet global {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_GLOABL | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + + +generate_firewallRule_validating_users() +{ + echo "FirewallRuleSet validating-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_VALIDATING_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_known_users() +{ + echo "FirewallRuleSet known-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_KNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + + +generate_firewallRule_unknown_users() +{ + echo "FirewallRuleSet unknown-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_UNKNOWN_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +generate_firewallRule_locked_users() +{ + echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE + echo "$(uci get $FIREWALL_RULE_LOCKED_USERS | tr "L" "\n")" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + +conf_character_check() +{ + +##### +# delete the single quote ' character,because some uci version will echo ' to the +# config file. + sed -i 's/'\''//g' $WIFI_DOG_CONF_FILE +#### +# delete the blank character at the line header + sed -i 's/^[[:space:]]*//' $WIFI_DOG_CONF_FILE + +#### +# delete the blank character at the line tail + sed -i 's/[[:space:]]*$//' $WIFI_DOG_CONF_FILE + +} + +generate_wifidog_conf_file() +{ + echo "###########################################################" > $WIFI_DOG_CONF_FILE + echo "## this is wifidog config file" >> $WIFI_DOG_CONF_FILE + echo "## auto generate by dog_conf_generator.sh" >> $WIFI_DOG_CONF_FILE + echo "## Version: $version Based on UCI" >> $WIFI_DOG_CONF_FILE + echo "############################################################" >> $WIFI_DOG_CONF_FILE + + generate_single + generate_authServer + generate_trustedMACList + generate_untrustedMACList + generate_whiteList + generate_blackList + generate_firewallRule_global + generate_firewallRule_validating_users + generate_firewallRule_known_users + generate_firewallRule_unknown_users + generate_firewallRule_locked_users + + conf_character_check +} + + +#echo "------ starting generate wifidog config file --------" + +generate_wifidog_conf_file + +#echo "------ wifidog config file generate complete --------" + diff --git a/scripts/etc/devicekey b/scripts/etc/devicekey new file mode 100644 index 00000000..12a3d538 --- /dev/null +++ b/scripts/etc/devicekey @@ -0,0 +1,6 @@ +######################################################## +## ### +## this file is the device key, do NOT modify it. ### +## ### +######################################################## +ae89-0633-cd4f-895d-780f-3342 \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index fba84cf0..d93f598c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,7 +34,8 @@ libgateway_a_SOURCES = commandline.c \ httpd_thread.c \ simple_http.c \ pstring.c \ - wd_util.c + wd_util.c \ + extend_util.c noinst_HEADERS = commandline.h \ common.h \ @@ -55,7 +56,8 @@ noinst_HEADERS = commandline.h \ httpd_thread.h \ simple_http.h \ pstring.h \ - wd_util.h + wd_util.h \ + extend_util.h wdctl_LDADD = libgateway.a diff --git a/src/auth.c b/src/auth.c index 77b7d908..f7ff28c6 100644 --- a/src/auth.c +++ b/src/auth.c @@ -40,7 +40,6 @@ #include "httpd.h" #include "http.h" #include "safe.h" -#include "conf.h" #include "debug.h" #include "auth.h" #include "centralserver.h" @@ -49,6 +48,9 @@ #include "client_list.h" #include "util.h" #include "wd_util.h" +#include "conf.h" + +#include "extend_util.h" /** Launches a thread that periodically checks if any of the connections has timed out @param arg Must contain a pointer to a string containing the IP adress of the client to check to check @@ -61,8 +63,18 @@ thread_client_timeout_check(const void *arg) pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; struct timespec timeout; + int ret = 0; while (1) { + /** + * Now,cllecting client's info,will create a + * client's info list. + * Added by GaomingPan + * */ + ret = collect_client_info(); + if(ret) + debug(LOG_WARNING,"cllecting client's info ERROR."); + /* Sleep for config.checkinterval seconds... */ timeout.tv_sec = time(NULL) + config_get_config()->checkinterval; timeout.tv_nsec = 0; @@ -79,6 +91,14 @@ thread_client_timeout_check(const void *arg) debug(LOG_DEBUG, "Running fw_counter()"); fw_sync_with_authserver(); + + /** + * Now,clearing client's info list, + * free the memories. + * Added by GaomingPan + * */ + ret = clean_client_info(); + debug(LOG_DEBUG,"free [%d] entry client's info.",ret); } } @@ -223,20 +243,19 @@ authenticate_client(request * r) fw_allow(client, FW_MARK_KNOWN); served_this_session++; -/** add parameter: - * *gw_address,mac (client's MAC address). - * * Added by GaomingPan. - * * */ -//safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); -safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", - auth_server->authserv_portal_script_path_fragment, - config->gw_id, - config->gw_address, - client->mac - ); - debug(LOG_INFO,"PortalQString: [[<< ============== \n\n %s ============== >>]]\n\n",urlFragment); - /************************************/ - + /** add parameter: + * gw_address,mac (client's MAC address). + * Added by GaomingPan. + * */ + //safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id); + safe_asprintf(&urlFragment, "%sgw_id=%s&gw_address=%s&mac=%s", + auth_server->authserv_portal_script_path_fragment, + config->gw_id, + config->gw_address, + client->mac + ); + /************************************/ + debug(LOG_INFO,"PortalQString: [[<< ============== \n\n %s ============== >>]]\n\n",urlFragment); http_send_redirect_to_auth(r, urlFragment, "Redirect to portal"); free(urlFragment); diff --git a/src/centralserver.c b/src/centralserver.c index 22c87099..7a478ef2 100644 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -25,6 +25,8 @@ @author Copyright (C) 2004 Philippe April */ + + #include #include #include @@ -39,19 +41,21 @@ #include #include "httpd.h" - -#include "common.h" -#include "safe.h" -#include "util.h" -#include "wd_util.h" #include "auth.h" +#include "common.h" #include "conf.h" #include "debug.h" -#include "centralserver.h" #include "firewall.h" +#include "safe.h" +#include "simple_http.h" +#include "util.h" +#include "wd_util.h" #include "../config.h" -#include "simple_http.h" +#include "centralserver.h" + +#include "extend_util.h" + /** Initiates a transaction with the auth server, either to authenticate or to * update the traffic counters at the server @@ -75,6 +79,19 @@ auth_server_request(t_authresponse * authresponse, const char *request_type, con t_auth_serv *auth_server = NULL; auth_server = get_auth_server(); + + /** + * get client's info, + * get client's online time, + * outgo rate and comin rate. + * Added by GaomingPan + * */ + t_clientinfo *client_info = NULL; + client_info = get_client_info_by_ip(ip); + time_t online_time = get_online_time(ip,mac); + int go_speed, + come_speed; + /* Blanket default is error. */ authresponse->authcode = AUTH_ERROR; @@ -86,35 +103,130 @@ auth_server_request(t_authresponse * authresponse, const char *request_type, con */ memset(buf, 0, sizeof(buf)); safe_token = httpdUrlEncode(token); - if(config -> deltatraffic) { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, mac, safe_token, - incoming, - outgoing, - incoming_delta, - outgoing_delta, - config->gw_id, VERSION, auth_server->authserv_hostname); - } else { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, safe_token, incoming, outgoing, config->gw_id, VERSION, auth_server->authserv_hostname); - } + + if(client_info){ + if(config -> deltatraffic) { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, mac, safe_token, + incoming, + outgoing, + incoming_delta, + outgoing_delta, + config->gw_id, + + /* new parameters,added by GaomingPan */ + client_info->host_name, + client_info->go_speed, + client_info->come_speed, + online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } else { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, safe_token, incoming, outgoing, config->gw_id, + + /* new parameters,added by GaomingPan */ + client_info->host_name, + client_info->go_speed, + client_info->come_speed, + online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } + }else{//if(client_info) + get_unknown_client_speed(ip,&go_speed,&come_speed); + if(config -> deltatraffic) { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, mac, safe_token, + incoming, + outgoing, + incoming_delta, + outgoing_delta, + config->gw_id, + + /* new parameters,added by GaomingPan */ + "unknown",//client_info->host_name, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } else { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", + auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, + ip, + mac, safe_token, incoming, outgoing, config->gw_id, + + /* new parameters,added by GaomingPan */ + "unknown",//client_info->host_name, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + } + }//if(client_info) + free(safe_token); + debug(LOG_INFO, "\n\nSendingQString: [[<<================\n %s ==================>>]]\n\n", buf); + char *res; #ifdef USE_CYASSL if (auth_server->authserv_use_ssl) { diff --git a/src/client_list.c b/src/client_list.c index df7bd610..21ba2101 100644 --- a/src/client_list.c +++ b/src/client_list.c @@ -126,6 +126,10 @@ client_list_add(const char *ip, const char *mac, const char *token) curclient->counters.incoming = curclient->counters.incoming_history = curclient->counters.outgoing = curclient->counters.outgoing_history = 0; curclient->counters.last_updated = time(NULL); + /** + * record the time when client add to the list. + * */ + curclient->record_time = time(NULL); client_list_insert_client(curclient); diff --git a/src/client_list.h b/src/client_list.h index ebc1c192..9ad36552 100644 --- a/src/client_list.h +++ b/src/client_list.h @@ -59,6 +59,7 @@ typedef struct _t_client { _http_* function is called */ t_counters counters; /**< @brief Counters for input/output of the client. */ + time_t record_time; /**< @breif the time point of the client add to list.*/ } t_client; /** @brief Get a new client struct, not added to the list yet */ diff --git a/src/commandline.c b/src/commandline.c index fdcfe501..a75522fa 100644 --- a/src/commandline.c +++ b/src/commandline.c @@ -29,12 +29,12 @@ #include #include #include +#include +#include "commandline.h" +#include "conf.h" #include "debug.h" #include "safe.h" -#include "conf.h" -#include "commandline.h" - #include "../config.h" /* diff --git a/src/conf.c b/src/conf.c index 89998cd1..d5720a61 100644 --- a/src/conf.c +++ b/src/conf.c @@ -44,7 +44,7 @@ #include "http.h" #include "auth.h" #include "firewall.h" -#include "config.h" +#include "../config.h" #include "util.h" @@ -97,6 +97,7 @@ typedef enum { oFirewallRule, oFirewallRuleSet, oTrustedMACList, + oUntrustedMACList,/*Untrusted mac list option,added by GaomingPan*/ oPopularServers, oHtmlMessageFile, oProxyPort, @@ -144,6 +145,7 @@ static const struct { "firewallruleset", oFirewallRuleSet}, { "firewallrule", oFirewallRule}, { "trustedmaclist", oTrustedMACList}, { + "untrustedmaclist", oUntrustedMACList},{ /*key word for untrusted mac, added by GaomingPan*/ "popularservers", oPopularServers}, { "htmlmessagefile", oHtmlMessageFile}, { "proxyport", oProxyPort}, { @@ -159,6 +161,7 @@ static void parse_auth_server(FILE *, const char *, int *); static int _parse_firewall_rule(const char *, char *); static void parse_firewall_ruleset(const char *, FILE *, const char *, int *); static void parse_trusted_mac_list(const char *); +static void parse_untrusted_mac_list(const char *);/*parse untrusted mac list, added by GaomingPan*/ static void parse_popular_servers(const char *); static void validate_popular_servers(void); static void add_popular_server(const char *); @@ -735,6 +738,9 @@ config_read(const char *filename) case oTrustedMACList: parse_trusted_mac_list(p1); break; + case oUntrustedMACList: /*parse untrustd mac list,added by GaomingPan*/ + parse_untrusted_mac_list(p1); + break; case oPopularServers: parse_popular_servers(rawarg); break; @@ -943,6 +949,82 @@ parse_trusted_mac_list(const char *ptr) } +/** @internal + * Parse the untrusted mac list. + * Added by GaomingPan,Sun Oct 11,2015 + */ +static void +parse_untrusted_mac_list(const char *ptr) +{ + char *ptrcopy = NULL; + char *possiblemac = NULL; + char *mac = NULL; + t_untrusted_mac *p = NULL; + + debug(LOG_DEBUG, "Parsing string [%s] for untrusted MAC addresses", ptr); + + mac = safe_malloc(18); + + /* strsep modifies original, so let's make a copy */ + ptrcopy = safe_strdup(ptr); + + while ((possiblemac = strsep(&ptrcopy, ","))) { + /* check for valid format */ + if (!check_mac_format(possiblemac)) { + debug(LOG_ERR, + "[%s] not a valid MAC address to not trust. See option UntrustedMACList in wifidog.conf for correct this mistake.", + possiblemac); + free(ptrcopy); + free(mac); + return; + } else { + if (sscanf(possiblemac, " %17[A-Fa-f0-9:]", mac) == 1) { + /* Copy mac to the list */ + + debug(LOG_DEBUG, "Adding MAC address [%s] to untrusted list", mac); + + if (config.untrustedmaclist == NULL) { + config.untrustedmaclist = safe_malloc(sizeof(t_untrusted_mac)); + config.untrustedmaclist->mac = safe_strdup(mac); + config.untrustedmaclist->next = NULL; + } else { + int skipmac; + /* Advance to the last entry */ + p = config.untrustedmaclist; + skipmac = 0; + /* Check before loop to handle case were mac is a duplicate + * of the first and only item in the list so far. + */ + if (0 == strcmp(p->mac, mac)) { + skipmac = 1; + } + while (p->next != NULL) { + if (0 == strcmp(p->mac, mac)) { + skipmac = 1; + } + p = p->next; + } + if (!skipmac) { + p->next = safe_malloc(sizeof(t_untrusted_mac)); + p = p->next; + p->mac = safe_strdup(mac); + p->next = NULL; + } else { + debug(LOG_ERR, + "MAC address [%s] already on untrusted list. See option UntrustedMACList in wifidog.conf file ", + mac); + } + } + } + } + } + + free(ptrcopy); + + free(mac); + +} + /** @internal * Add a popular server to the list. It prepends for simplicity. * @param server The hostname to add. diff --git a/src/conf.h b/src/conf.h index f9ce3404..0e56d4bb 100644 --- a/src/conf.h +++ b/src/conf.h @@ -145,6 +145,15 @@ typedef struct _trusted_mac_t { struct _trusted_mac_t *next; } t_trusted_mac; +/** + * Untrusted MAC Addresses. + * Added by GaomingPan,Sun Oct 11, 2015. + * */ +typedef struct _untrusted_mac_t { + char *mac; + struct _untrusted_mac_t *next; +} t_untrusted_mac; + /** * Popular Servers */ @@ -195,6 +204,8 @@ typedef struct { auth server for server name indication, the TLS extension */ t_firewall_ruleset *rulesets; /**< @brief firewall rules */ t_trusted_mac *trustedmaclist; /**< @brief list of trusted macs */ + t_untrusted_mac *untrustedmaclist; /**< @brief list of untrusted macs, + added by GaomingPan */ char *arp_table_path; /**< @brief Path to custom ARP table, formatted like /proc/net/arp */ t_popular_server *popular_servers; /**< @brief list of popular servers */ diff --git a/src/debug.c b/src/debug.c index 83c87cd9..58fff29c 100644 --- a/src/debug.c +++ b/src/debug.c @@ -24,6 +24,8 @@ @author Copyright (C) 2004 Philippe April */ +#include "debug.h" + #include #include #include @@ -32,7 +34,6 @@ #include #include -#include "debug.h" debugconf_t debugconf = { .debuglevel = LOG_INFO, diff --git a/src/extend_util.c b/src/extend_util.c new file mode 100644 index 00000000..e13c8f5f --- /dev/null +++ b/src/extend_util.c @@ -0,0 +1,1117 @@ +/* + * extend_util.c + * + * Created on: Oct 10, 2015 + * Author: GaomingPan + */ +#include "extend_util.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "client_list.h" +#include "conf.h" +#include "debug.h" +#include "fw_iptables.h" +#include "util.h" +#include "../config.h" + + + + +/*================= SOME INTERNAL DEFINDS AND STRUCTURES ======================*/ +/** + * This part is get the device information functions, + * and some Macro defines. + * */ +#define DEV_IFNAME_LEN 11 +#define IFACE_DATA_FILE "/tmp/.iface-data" +#define IFACE_CONN_FILE "/tmp/.iface_conn" +#define CPU_USE_INFO_FILE "/tmp/.cpu_use_info" +#define CPU_USER 1 +#define CPU_SYS 3 +#define CPU_NIC 5 +#define CPU_IDLE 7 +#define CPU_IO 9 +#define CPU_IRQ 11 +#define CPU_SIRQ 13 +#define CPU_LOAD 16 + + +/** + * This part is get the client's information functions, + * and some Macro defines. + * */ +#define UP_SPEED_FILE "/tmp/.client.up.speed" +#define DOWN_SPEED_FILE "/tmp/.client.down.speed" +#define HOST_NAME_FILE "/tmp/.hostname.txt" + +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ +#define GET_SETTINGS_INFO_CMD "GET_settings" +#define SETTINGS_INFO_FILE "/tmp/.routersettings" +#define NORMAL_CMD_RESULT_FILE "/tmp/.normal_cmd_result" + +#define BUILE_NORMAL_CMD_RESULT_SHELL "sed -i \"s/\\\"/ /g\" "NORMAL_CMD_RESULT_FILE "; echo \"[\" > /tmp/.normal.arr;while read line;do echo \"\\\"$line\\\"\", >> /tmp/.normal.arr;done < "NORMAL_CMD_RESULT_FILE";result=\"$(cat /tmp/.normal.arr)\";result=\"${result%,}]\";echo $result" + +#define CMD_GET_WAN_IP "uci -P/var/state get network.wan.ipaddr" +#define CMD_GET_AP_MAC "uci get network.lan.macaddr" //"uci -P/var/state get network.lan.macaddr" +#define CMD_GET_WIRELESS_SSID "uci get wireless.@wifi-iface[0].ssid" +#define WAN_IP_ADDR_FILE "/tmp/.wan_ipaddr.txt" +#define REMOTE_SHELL_COMMAND_LEN 1024 +#define MAX_CMD_EXECUT_OUT_LEN 4096 + +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ +#define DEVICE_KEY_FILE "/etc/.devicekey" + + +/*=============================================================*/ +/** + * This part is get the device information functions, + * and some Macro defines. + * */ + + +/** + * @ breif a internal struct hold cpu load information for ap + * */ +struct _t_cpuuse{ + char use_info[15][8]; +}; + + +typedef struct _t_cpuuse t_cpuuse; + + +/*======================== END DEFINDS ========================*/ + + +extern pthread_mutex_t client_list_mutex; +static t_devinfo devinfo; +static t_cpuuse cpuuse; +static char apmac[DEV_MAC_ADDR_LEN] = {0}; +static char apwanip[DEV_WAN_IP_LEN] = {0}; +//extern char *dev_extern_iface; + + +/** + * @brief this function collect the gateway device information. + * @returnValue a type pointer of t_devinfo + * */ +t_devinfo *get_devinfo(void) +{ + + memcpy(devinfo.gw_mac,apmac,DEV_MAC_ADDR_LEN); + +// if(get_apmac(devinfo.gw_mac)) +// { +// debug(LOG_WARNING,"MyDEBUG:get get_apmac error!"); +// } + + if(get_devssid(devinfo.gw_ssid)) + { + debug(LOG_WARNING,"ERR:get ssid error!"); + } + + if(get_dogversion(devinfo.dog_version)) + { + debug(LOG_WARNING,"ERR: get_dogversion error!"); + } + + if(get_wanip(devinfo.wan_ip)) + { + debug(LOG_WARNING,"ERR: get_wanip error!\n"); + } + + devinfo.cur_conn = get_curconn(); + devinfo.dev_conn = get_devconn(); + + devinfo.cpu_use = get_cpuuse(CPU_LOAD); + + if(get_wanbps(&devinfo.go_speed,&devinfo.come_speed)) + { + debug(LOG_WARNING,"ERR: get_speed error!"); + } + + if(get_trafficCount(get_dev_extern_iface(),&devinfo.incoming,&devinfo.outgoing,NULL,NULL)) + { + debug(LOG_WARNING,"ERR: get_traffic error!\n"); + } + + return &devinfo; +} + +/** + * @brief get wireless ssid,based on uci command. + * @param ssid: the char pointer for save the ssid. + * @return value: zero is success,others is failed. + * */ +int get_devssid(char *ssid) +{ + FILE *fp; + memset(ssid,0,DEV_SSID_NAME_LEN); + fp = popen(CMD_GET_WIRELESS_SSID,"r"); + if(NULL == fp) + { + debug(LOG_WARNING," get_devssid error!"); + sprintf(ssid,"%s","null"); + return -1; + } + fread(ssid,DEV_SSID_NAME_LEN,1,fp); + pclose(fp); + + int i = DEV_SSID_NAME_LEN - 1; + for(;i > 0;i--) + { + if(0x0a == ssid[i]) + { + ssid[i] = 0; + break; + } + } + return 0; +} + + +/** + * @breif get wifidog version + * @param dogversion:the char pointer for save the version + * @return value:always return zero + * */ +int get_dogversion(char *dogversion) +{ + memset(dogversion,0,DEV_DOG_VERSION_LEN); + sprintf(dogversion,"%s",VERSION); + return 0; +} + +/** + * @breif get wan interface ip,based on uci command. + * @param wanip:the char pointer for save the wan ip + * @return value:always zero is success,others is failed. + * */ +int get_wanip(char *wanip) +{ + FILE *fp; + + if(0 == strlen(apwanip)){ + /* + fp = popen(CMD_GET_WAN_IP,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"get_wanip error!"); + if(NULL != wanip) + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(apwanip,DEV_WAN_IP_LEN - 1,1,fp); + pclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i >= 0;i--){ + if(0x0a == apwanip[i]){ + apwanip[i] = 0; + break; + } + } + */ + fp = fopen(WAN_IP_ADDR_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"get_wanip error!"); + if(NULL != wanip) + sprintf(wanip,"%s","0.0.0.0"); + return -1; + } + fread(apwanip,DEV_WAN_IP_LEN - 1,1,fp); + fclose(fp); + + int i = DEV_WAN_IP_LEN - 1; + for(;i >= 0;i--){ + if(0x0a == apwanip[i]){ + apwanip[i] = 0; + break; + } + } + + } + if(NULL != wanip) + sprintf(wanip,"%s",apwanip); + + return 0; +} + +/** + * @breif get ap mac address,based on uci command. + * @param apmac:the char pointer for save the mac + * @return value:zero is success,others is failed. + * */ +int get_apmac(char *mac) +{ + FILE *fp; + int i; + + if(0 == strlen(apmac)){ + fp = popen(CMD_GET_AP_MAC,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"get_apmac() popen error."); + sprintf(apmac,"%s","00-00-00-00-00-00"); + return -1; + } + fread(apmac,DEV_MAC_ADDR_LEN - 1,1,fp); + pclose(fp); + + for(i = 0; i< DEV_MAC_ADDR_LEN; i++){ + if(':' == apmac[i]) + apmac[i] = '-'; + if(apmac[i] >= 'A' && apmac[i] <= 'F') + apmac[i] += apmac[i] + 0x20; + if(0x0a == apmac[i]) + apmac[i] = 0; + } + } + + if(NULL != mac) + mac = apmac; + + return 0; +} + + +/** + * @breif get number of client it in the client list + * @return value:the number of current connected client + * */ +int get_curconn(void) +{ + int count; + t_client *first; + + LOCK_CLIENT_LIST(); + + first = client_get_first_client(); + if (first == NULL) { + count = 0; + } else { + count = 1; + while (first->next != NULL) { + first = first->next; + count++; + } + } + + UNLOCK_CLIENT_LIST(); + + return count; +} + + +/** + * @breif get number of client who connect to the device + * @return value:the number of connected client + * */ +int get_devconn(void) +{ + FILE *fp; + char info_buf[512], + num_buf[10]; + char *ptr = NULL; + s_config *conf = config_get_config(); + + fp = fopen(IFACE_CONN_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: fopen error, at get_devconn()."); + return -1; + } + if(0 == fread(info_buf,1,512,fp)){ + fclose(fp); + debug(LOG_WARNING,"Warning: read device conn error."); + return 0; + } + fclose(fp); + ptr = strstr(info_buf,conf->gw_interface); + if(NULL == ptr){ + debug(LOG_WARNING,"Warning: strstr(info_buf,conf->gw_interface) return is NULL"); + return 0; + } + sscanf(ptr,"%*s %s",num_buf); + return (atoi(num_buf)); +} + + +/** + * @breif get cpu use infomation,based on shell command + * @param type: CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @return value:the number of current percent of CPU use. + * */ +int get_cpuuse(int type) +{ + int use, + i; + FILE *fp; + + for(i = 0;i < 15;i++) + memset(cpuuse.use_info[i],0,8); + + fp = fopen(CPU_USE_INFO_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"fopen error,at get_cpuuse(...) !"); + return -1; + } + fscanf(fp,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + cpuuse.use_info[0],cpuuse.use_info[1],cpuuse.use_info[2], + cpuuse.use_info[3],cpuuse.use_info[4],cpuuse.use_info[5], + cpuuse.use_info[6],cpuuse.use_info[7],cpuuse.use_info[8], + cpuuse.use_info[9],cpuuse.use_info[10],cpuuse.use_info[11], + cpuuse.use_info[12],cpuuse.use_info[13],cpuuse.use_info[14] + ); + fclose(fp); + +// for(;i<15;i++) +// printf("cpuuse.use_info[%d]:%s\n",i,cpuuse.use_info[i]); + + switch(type){ + case CPU_USER: + cpuuse.use_info[CPU_USER][strlen(cpuuse.use_info[CPU_USER])-1] = 0; + use = atoi(cpuuse.use_info[CPU_USER]); + break; + case CPU_SYS: + cpuuse.use_info[CPU_SYS][strlen(cpuuse.use_info[CPU_SYS])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SYS]); + break; + case CPU_NIC: + cpuuse.use_info[CPU_NIC][strlen(cpuuse.use_info[CPU_NIC])-1] = 0; + use = atoi(cpuuse.use_info[CPU_NIC]); + break; + case CPU_IDLE: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_LOAD: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IDLE])-1] = 0; + use = 100 - atoi(cpuuse.use_info[CPU_IDLE]); + break; + case CPU_IO: + cpuuse.use_info[CPU_IDLE][strlen(cpuuse.use_info[CPU_IO])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IO]); + break; + case CPU_IRQ: + cpuuse.use_info[CPU_IRQ][strlen(cpuuse.use_info[CPU_IRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_IRQ]); + break; + case CPU_SIRQ: + cpuuse.use_info[CPU_SIRQ][strlen(cpuuse.use_info[CPU_SIRQ])-1] = 0; + use = atoi(cpuuse.use_info[CPU_SIRQ]); + break; + default: + use = -1; + break; + } + + return use; +} + +/** + * @breif get wan interface traffic,based on shell command. + * @param iface_name: interface name + * @param income: interface incoming + * @param outgo: interface outgoing + * @param rx_rate: interface RX rate + * @param tx_rate: interface TX rate + * @return value:zero is success,others is error + * */ +int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate) +{ + FILE *fp; + char *iface, + *ptr; + char data[4096]; + struct stat statbuf; + int data_size; + int ret; + + unsigned int rx,tx; + unsigned long long out,in; + + + iface = iface_name; + if(NULL == iface){ + out = 0L; + in = 0L; + debug(LOG_WARNING,"at get_trafficCount(...),ifce_name is NULL."); + ret = -1; + goto ERR; + } + + stat(IFACE_DATA_FILE,&statbuf); + data_size = statbuf.st_size; + + fp = fopen(IFACE_DATA_FILE,"r"); + if(NULL == fp){ + out = 0L; + in = 0L; + debug(LOG_WARNING,"at get_trafficCount(...), fopen the IFACE_DATA_FILE error."); + ret = -2; + goto ERR; + } + fread(data,1,data_size,fp); + fclose(fp); + + ptr = strstr(data,iface); + if(NULL == ptr){ + out = 0L; + in = 0L; + debug(LOG_WARNING,"at get_trafficCount(...), strstr(..) get iface position error."); + ret = -3; + goto ERR; + } + ret = sscanf(ptr,"%*s %llu %llu %u %u",&in,&out,&rx,&tx); + if(ret != 4) + goto ERR; + + if(NULL != outgo) + *outgo = out; + if(NULL != income) + *income = in; + if(NULL != rx_rate) + *rx_rate = rx; + if(NULL != tx_rate) + *tx_rate = tx; + + return 0; + +ERR: + if(NULL != outgo) + *outgo = 0; + if(NULL != income) + *income = 0; + if(NULL != rx_rate) + *rx_rate = 0; + if(NULL != tx_rate) + *tx_rate = 0; + + return ret; +} + +/** + * @breif get wan interface speed,based on shell command. + * @param go:the pointer for save out rate + * @param come:the pointer for save income rate. + * @return value:zero is success,others is error. + * */ +int get_wanbps(unsigned int *go,unsigned int *come) +{ + unsigned int tx,rx; + int ret = 0; + char *iface; + + iface = get_dev_extern_iface();//config_get_config()->external_interface; + if(NULL == iface){ + debug(LOG_WARNING,"at get_trafficCount(...), wifidog can't find the external_interface."); + } + + ret = get_trafficCount(iface,NULL,NULL,&rx,&tx); + if(ret != 0){ + debug(LOG_WARNING,"at get_wanbps(), get_trafficCount() error return code = %d",ret); + if(NULL != go) + *go = 0; + if(NULL != come) + *come = 0; + return -1; + } + + if(NULL != go) + *go = tx; + if(NULL != come) + *come = rx; + + return 0; +} +/*=============================================================*/ + +/*=============================================================*/ +/** + * This part is get the client's information functions, + * and some Macro defines. + * */ +static t_clientinfo *first_client_info = NULL; +static char client_auth_flag[7] = {0}; + +/** + * @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @return value: zero is success,others is error. + * @Note: after this function be called and you get some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * */ +int collect_client_info() +{ + FILE *fp; + char a_rate[20], + ip[18]; + t_clientinfo *p1, + *p2, + *p3; + int ret; + int line_num = 0; + char *line = NULL; + + if(first_client_info){ + debug(LOG_WARNING,"client's info list not NULL,can't cllecting info,will clearing the list."); + clean_client_info(); + return -1; + } + /** + * malloc memories for clients info list. + * */ + first_client_info = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == first_client_info){ + debug(LOG_WARNING,"Warning: at collect_client_info(), malloc error."); + return -1; + } + first_client_info->next = NULL; + p1 = first_client_info; + p2 = p1; + + /** + * get host name,ip and mac + * */ + fp = fopen(HOST_NAME_FILE,"r"); + if(NULL == fp){ + + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + if(NULL == p1){ + p1 = (t_clientinfo*)malloc(sizeof(t_clientinfo)); + if(NULL == p1){ + debug(LOG_WARNING,"Warning: at collect_client_info(), malloc error."); + fclose(fp); + return -1; + } + p2->next = p1; + p2 = p1; + p1->next = NULL; + + }//if(NULL == p1) + ret = sscanf(line,"%s %s %s",p1->client_mac,p1->client_ip,p1->host_name); + if(3 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p1 = p1->next; + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + /* get up speed + * */ + fp = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p3 = get_client_info_by_ip(ip); + if(NULL != p3){ + p3->go_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + /* get the down speed + * */ + fp = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + return -1; + } + p3 = get_client_info_by_ip(ip); + if(NULL != p3){ + p3->come_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + return 0; +} + + +/** + * @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @param client_ip: the unknown host name client's ip. + * @param go_speed: the pointer for client's outgoing speed to store. + * @param come_speed: the pointer for client's incoming speed to store. + * @return value: zero is success,others is error. + * */ +int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed) +{ + + FILE *fp; + + char a_rate[20], + ip[18]; + + int ret; + int line_num = 0; + char *line = NULL; + + /* get up speed + * */ + fp = fopen(UP_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + *go_speed = 0; + *come_speed = 0; + return -1; + } + + if(0 == strcmp(client_ip,ip)){ + *go_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + /* get the down speed + * */ + fp = fopen(DOWN_SPEED_FILE,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"Warning: at collect_client_info(),fopen for fp error."); + return -1; + } + while(-1 != getline(&line,&line_num,fp)){ + + ret = sscanf(line,"%s %s",ip,a_rate); + if(2 != ret){ + if(line != NULL) + free(line); + fclose(fp); + *go_speed = 0; + *come_speed = 0; + return -1; + } + if(0 == strcmp(client_ip,ip)){ + *come_speed = atoi(a_rate); + } + + }//while + fclose(fp); + if(line != NULL){ + free(line); + line = NULL; + } + + return 0; +} + +/** + * @breif After the function collect_client_info() called,should call this function to + * clean up. + * @return value: the count number of clean + * */ +int clean_client_info() +{ + t_clientinfo *p; + int num = 0; + + p = first_client_info; + + while(NULL != p){ + ++num; + free(p); + p = p->next; + } + + first_client_info = NULL; + + return num; +} + + + +/** + * @breif find the element from the client_info list by mac. + * @param mac: the pointer point to by mac. + * @return value: success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * */ +t_clientinfo * get_client_info_by_mac(const char *mac) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p){ + if(strcmp(mac,p->client_mac) == 0){ + return p; + } + p = p->next; + } + return NULL; +} + + + +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by ip. + * @return value: success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * */ +t_clientinfo * get_client_info_by_ip(const char *ip) +{ + t_clientinfo *p; + p = first_client_info; + while(NULL != p){ + if(strcmp(ip,p->client_ip) == 0){ + return p; + } + p = p->next; + } + return NULL; +} + + +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by client's ip. + * @param mac: the pointer point to by client's mac. + * */ +long get_online_time(const char *ip,const char *mac) +{ + t_client *ptr; + long online_time = 0; + ptr = client_list_find(ip,mac); + if(NULL!= ptr) + online_time = time(NULL) - ptr->record_time; + return online_time; +} + +/* + * @breif get a flage string + * */ +char *get_client_auth_flag() +{ + return client_auth_flag; +} + +/* + * @breif set a flage string + * */ +void set_client_auth_flag() +{ + /* + * Rand a range number at [max,min]: + * rand()%(max - min + 1) + min + * */ + int i; + for(i = 0;i<6;i++) + client_auth_flag[i] = rand()%(90 - 65 + 1) + 65; +} + + +/*=============================================================*/ +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ +static char remote_shell_cmd[ REMOTE_SHELL_COMMAND_LEN ]; +static char info_http_url[128], + info_rmflag[20], + normal_http_url[128], + normal_rmflag[20]; + + +int init_post_http_url_config(void) +{ + memset(info_http_url,0,128); + memset(info_rmflag,0,20); + memset(normal_http_url,0,128); + memset(normal_rmflag,0,20); + + char buf[128]; + FILE *fp; + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.info_url","r"); + if(NULL == fp){ + return -1; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(info_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.url.normal_url","r"); + if(NULL == fp){ + return -2; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(normal_http_url,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.info_rmflag","r"); + if(NULL == fp){ + return -3; + } + fread(buf,1,128,fp); + pclose(fp); + + sprintf(info_rmflag,"%s",buf); + memset(buf,0,128); + + fp = popen("uci get dog_post_conf.rmflag.normal_rmflag","r"); + if(NULL == fp){ + return -4; + } + fread(buf,1,128,fp); + pclose(fp); + sprintf(normal_rmflag,"%s",buf); + + debug(LOG_INFO,"init result :info_url:%s;info_rmflag:%s;normal_url:%s;normal_rmflag:%s", \ + info_http_url,info_rmflag, \ + normal_http_url,normal_rmflag + ); + + return 0; +} + + + + +int post_get_info_execut_output(char *cmd_output_path) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + sprintf(output,"wget --post-data=\"$(cat %s)\" %s \n rm -f ./%s",cmd_output_path,info_http_url,info_rmflag); + fp = popen(output,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"popen error,at int post_get_info_execut_output(char *cmd_output_path,char *http_url,char * rm_flag)"); + return -1; + } + pclose(fp); + return 0; +} + + + +int post_normal_execut_output(char *gw_id, char *cmd_id) +{ + char output[MAX_CMD_EXECUT_OUT_LEN]; + FILE *fp; + + sprintf(output,"wget --post-data=\"{\\\"gw_id\\\":\\\"%s\\\"," + "\\\"cmd_id\\\":\\\"%s\\\"," + "\\\"type\\\":\\\"normal\\\"," + "\\\"message\\\":$(%s)}\" %s \n rm ./%s", + gw_id,cmd_id, + BUILE_NORMAL_CMD_RESULT_SHELL, + normal_http_url, + normal_rmflag + ); + debug(LOG_INFO,"output_normal:--> %s",output); + fp = popen(output,"r"); + if(NULL == fp){ + debug(LOG_WARNING,"popen error,at int post_nomal_execut_output(char *post_data,char *http_url,char *rm_flag)"); + return -1; + } + pclose(fp); + return 0; +} + + +char *get_shell_command(char *cmdptr) +{ + + if(NULL == cmdptr){ + debug(LOG_WARNING,"REMOTE shell: remote shell command is null."); + return NULL; + } + memset(remote_shell_cmd,0,REMOTE_SHELL_COMMAND_LEN); + sprintf(remote_shell_cmd,"%s",cmdptr); + + return remote_shell_cmd; +} + + + +int excute_shell_command(char *gw_id,char *shellcmd) +{ + FILE *fp; + + char cmd_id[512], + get_info_cmd[512], + normal_cmd[MAX_CMD_EXECUT_OUT_LEN], + cmdresult[1024]; + + char *pos_id, + *pos_cmd; + + int is_get_info = 0; + + memset(cmdresult,0,1024); + memset(cmd_id,0,512); + memset(get_info_cmd,0,512); + + pos_id = shellcmd; + pos_cmd = strstr(shellcmd,"|"); + + snprintf(cmd_id,++pos_cmd - pos_id - 1,"%s",++pos_id); + + pos_cmd = ++pos_cmd; + + snprintf(get_info_cmd,30,"%s",pos_cmd); + + is_get_info = strcmp(get_info_cmd,GET_SETTINGS_INFO_CMD";"); + + debug(LOG_INFO,"cmd_id:%s,get_inf_cmd:%s,is_get_info cmp:%d",cmd_id,get_info_cmd,is_get_info); + + if(0 == is_get_info){ + get_info_cmd[strlen(get_info_cmd) - 1] = 0;// delete the semicolon it at the tail + sprintf(get_info_cmd,"%s %s %s",get_info_cmd,gw_id,cmd_id);/* add gw_id and cmd_id to the command as + the parameter of the command */ + fp = popen(get_info_cmd,"r"); + }else{ + /* if the command is a normal command,just do it. + * */ + sprintf(normal_cmd,"RESULT=\"$(%s)\";echo \"$RESULT\" > "NORMAL_CMD_RESULT_FILE,pos_cmd); + fp = popen(normal_cmd,"r"); + } + + debug(LOG_INFO,"pos_cmd:%s",pos_cmd); + + if(NULL == fp){ + debug(LOG_WARNING,"excute_shell_command popen error...."); + return -1; + } + + pclose(fp); + + if(0 == is_get_info){ + post_get_info_execut_output(SETTINGS_INFO_FILE); + + }else{ + + post_normal_execut_output(gw_id,cmd_id); + } + return 0; +} + + + +/** + * the global device key char array. + * */ +static char device_key[64] = {0}; + + +/* @breif get the global device key.the key will be use as auth key + * @PARAMETER: void + * @RETURN_VALUE: a none NULL char pointer + * GaomingPan lonely-test:yes + * */ +char * get_device_key() +{ + return device_key; +} + + + + +/* @breif get the device key from a configure file + * @PARAMETER: void + * @RETURN_VALUE: success return zero and set the KEY in the device key global array, + * failed return a none zero number. + * GaomingPan lonely-test:yes + * */ +int init_device_key() +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + ssize_t read_len; + + fp = fopen(DEVICE_KEY_FILE,"r"); + if(NULL == fp) + { + return -1; + } + while((read_len = getline(&line,&len,fp)) != -1) + { + if('#' == line[0] || ' ' == line[0] || '\t' == line[0]) + continue; + else + { + sprintf(device_key,"%s",line); + free(line); + fclose(fp); + return 0; + } + } + free(line); + fclose(fp); + return -2; +} + +/*=============================================================*/ diff --git a/src/extend_util.h b/src/extend_util.h new file mode 100644 index 00000000..ec925806 --- /dev/null +++ b/src/extend_util.h @@ -0,0 +1,260 @@ +/* + * extend_util.h + * + * Created on: Oct 10, 2015 + * Author: GaomingPan + */ + +#ifndef _EXTEND_UTIL_H_ +#define _EXTEND_UTIL_H_ + +/** + * @ breif a internal struct hold information for ap + * */ +#define DEV_MAC_ADDR_LEN 18 +#define DEV_SSID_NAME_LEN 20 +#define DEV_DOG_VERSION_LEN 20 +#define DEV_WAN_IP_LEN 16 +struct _t_devinfo{ + char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address + char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid + char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. + char wan_ip[DEV_WAN_IP_LEN]; // ap's wan interface ip + int cur_conn; // number of current connection client + int dev_conn; // number of connection in the device,maybe some has no authentication. + int cpu_use; // percent of use CPU + unsigned int go_speed; // wan interface go out speed + unsigned int come_speed; // wan interface come in speed + unsigned long long incoming; // wan interface incoming bytes + unsigned long long outgoing; // wan interface outgoing bytes +}; + +/** + * @breif a internal sturct for client_info list + * */ +#define CLIENT_HOST_NAME_LEN 40 +#define CLIENT_MAC_ADDRESS_LEN 18 +#define CLIENT_IP_ADDRESS_LEN 16 +struct _t_clientinfo{ + + char client_mac[CLIENT_MAC_ADDRESS_LEN]; + char client_ip[CLIENT_IP_ADDRESS_LEN]; + char host_name[CLIENT_HOST_NAME_LEN]; + int go_speed; + int come_speed; + struct _t_clientinfo *next; + +}; +typedef struct _t_clientinfo t_clientinfo; +typedef struct _t_devinfo t_devinfo; + +/*=============================================================*/ +/** + * This part is get the device information functions, + * and some Macro defines. + * */ + +/** + * @brief this function collect the gateway device information. + * @returnValue a type pointer of t_devinfo + * */ +t_devinfo *get_devinfo(void); + +/** + * @brief get wireless ssid,based on uci command. + * @param ssid: the char pointer for save the ssid. + * @return value: zero is success,others is failed. + * */ +int get_devssid(char *ssid); + +/** + * @breif get wifidog version + * @param dogversion:the char pointer for save the version + * @return value:always return zero + * */ +int get_dogversion(char *dogversion); + + +/** + * @breif get wan interface ip,based on uci command. + * @param wanip:the char pointer for save the wan ip + * @return value:always zero is success,others is failed. + * */ +int get_wanip(char *wanip); + +/** + * @breif get ap mac address,based on uci command. + * @param apmac:the char pointer for save the mac + * @return value:zero is success,others is failed. + * */ +int get_apmac(char *apmac); + +/** + * @breif get number of client it in the client list + * @return value:the number of current connected client + * */ +int get_curconn(void); + + +/** + * @breif get number of client who connect to the device + * @return value:the number of connected client + * */ +int get_devconn(void); + + +/** + * @breif get cpu use infomation,based on shell command + * @param type: CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD + * @return value:the number of current percent of CPU use. + * */ +int get_cpuuse(int type); + + +/** + * @breif get wan interface speed,based on shell command. + * @param go:the pointer for save out rate + * @param come:the pointer for save income rate. + * @return value:zero is success,others is error. + * */ +int get_wanbps(unsigned int *go,unsigned int *come); + + +/** + * @breif get wan interface traffic,based on shell command. + * @param iface_name: interface name + * @param income: interface incoming + * @param outgo: interface outgoing + * @param rx_rate: interface RX rate + * @param tx_rate: interface TX rate + * @return value:zero is success,others is error + * */ +int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate); + +/*=============================================================*/ + + +/*=============================================================*/ +/** + * This part is get the client's information functions, + * and some Macro defines. + * */ + + +/** + * @breif get client host name,income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @return value: zero is success,others is error. + * @Note: after this function be called and you get some clients information,you should + * call clean_client_info() function to clean up,just like the fopen() and fclose(). + * */ +int collect_client_info(); + + +/** + * @breif get unknown host name client's income speed and outgo speed,based on shell command. + * this functions take at least 1 second to run,because of execute the shell + * command have to sleep 1 second to collect client speed. + * @param client_ip: the unknown host name client's ip. + * @param go_speed: the pointer for client's outgoing speed to store. + * @param come_speed: the pointer for client's incoming speed to store. + * @return value: zero is success,others is error. + * */ +int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed); + + + +/** + * @breif After the function collect_client_info() called,should call this function to + * clean up. + * @return value: the count number of clean + * */ +int clean_client_info(); + + +/** + * @breif find the element from the client_info list by mac. + * @param mac: the pointer point to by mac. + * @return value: success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * */ +t_clientinfo * get_client_info_by_mac(const char *mac); + + +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by ip. + * @return value: success return the t_clientinfo pointer that point to target element, + * fail return the NULL. + * */ +t_clientinfo * get_client_info_by_ip(const char *ip); + + +/** + * @breif find the element from the client_info list by ip. + * @param ip: the pointer point to by client's ip. + * @param mac: the pointer point to by client's mac. + * */ +long get_online_time(const char *ip,const char *mac); + + + +/* + * @breif get a flage string + * */ +char *get_client_auth_flag(); + + +/* + * @breif set a flage string + * */ +void set_client_auth_flag(); + +/*=============================================================*/ + + +/*=============================================================*/ +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ + + +char *get_shell_command(char *cmdptr); + +int excute_shell_command(char *gw_id,char *shellcmd); + +int post_get_info_execut_output(char *cmd_output_path); + +int post_normal_execut_output(char *gw_id, char *cmd_id); + +int init_post_http_url_config(void); + + +/*=============================================================*/ + +/*=============================================================*/ +/** + * This part is get the remote shell command functions, + * and some Macro defines. + * */ + +/* @breif get the global device key.the key will be use as auth key + * @PARAMETER: void + * @RETURN_VALUE: a none NULL char pointer + * GaomingPan lonely-test:yes + * */ +char * get_device_key(); + + + +/* @breif get the device key from a configure file + * @PARAMETER: void + * @RETURN_VALUE: success return zero and set the KEY in the device key global array, + * failed return a none zero number. + * GaomingPan lonely-test:yes + * */ +int init_device_key(); + +#endif /* _EXTEND_UTIL_H_ */ diff --git a/src/firewall.c b/src/firewall.c index 211af351..c3a68c90 100644 --- a/src/firewall.c +++ b/src/firewall.c @@ -58,6 +58,8 @@ #include "client_list.h" #include "commandline.h" +#include "extend_util.h" + static int _fw_deny_raw(const char *, const char *, const int); /** @@ -264,6 +266,9 @@ fw_sync_with_authserver(void) return; } + /* set a auth flag,added by GaomingPan */ + set_client_auth_flag(); + LOCK_CLIENT_LIST(); /* XXX Ideally, from a thread safety PoV, this function should build a list of client pointers, diff --git a/src/fw_iptables.c b/src/fw_iptables.c index b3ec1089..a246e9c3 100644 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -57,6 +57,19 @@ static void iptables_load_ruleset(const char *, const char *, const char *); Used to supress the error output of the firewall during destruction */ static int fw_quiet = 0; + + +/** @brief Get extern interface + * this function use at extend_util.c. + * Added by GaomingPan. + * */ +static char dev_extern_iface[64] = {0}; +char *get_dev_extern_iface() +{ + return dev_extern_iface; +} + + /** @internal * @brief Insert $ID$ with the gateway's id in a string. * @@ -248,6 +261,7 @@ iptables_fw_init(void) char *ext_interface = NULL; int gw_port = 0; t_trusted_mac *p; + t_untrusted_mac *unp;/*added by GaomingPan*/ int proxy_port; fw_quiet = 0; int got_authdown_ruleset = NULL == get_ruleset(FWRULESET_AUTH_IS_DOWN) ? 0 : 1; @@ -257,8 +271,18 @@ iptables_fw_init(void) gw_port = config->gw_port; if (config->external_interface) { ext_interface = safe_strdup(config->external_interface); + /* Added by GaomingPan */ + //memset(dev_extern_iface,0,64); + sprintf(dev_extern_iface,"%s",ext_interface); + debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); + /**/ } else { ext_interface = get_ext_iface(); + /* Added by GaomingPan */ + //memset(dev_extern_iface,0,64); + sprintf(dev_extern_iface,"%s",ext_interface); + debug(LOG_INFO, "dev_extern_iface is: %s",dev_extern_iface); + /**/ } if (ext_interface == NULL) { @@ -274,6 +298,7 @@ iptables_fw_init(void) /* Create new chains */ iptables_do_command("-t mangle -N " CHAIN_TRUSTED); + iptables_do_command("-t mangle -N " CHAIN_UNTRUSTED);/* Added by GaomingPan */ iptables_do_command("-t mangle -N " CHAIN_OUTGOING); iptables_do_command("-t mangle -N " CHAIN_INCOMING); if (got_authdown_ruleset) @@ -281,6 +306,7 @@ iptables_fw_init(void) /* Assign links and rules to these new chains */ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_OUTGOING, config->gw_interface); + iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_UNTRUSTED, config->gw_interface); /* Added by GaomingPan */ iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_TRUSTED, config->gw_interface); //this rule will be inserted before the prior one if (got_authdown_ruleset) iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_AUTH_IS_DOWN, config->gw_interface); //this rule must be last in the chain @@ -290,6 +316,13 @@ iptables_fw_init(void) iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, FW_MARK_KNOWN); + /** Untrusted MAC. + * Added by GaomingPan + * */ + for (unp = config->untrustedmaclist; unp != NULL; unp = unp->next) + iptables_do_command("-t mangle -A " CHAIN_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", unp->mac, + FW_MARK_LOCKED); + /* * * Everything in the NAT table @@ -422,16 +455,19 @@ iptables_fw_destroy(void) */ debug(LOG_DEBUG, "Destroying chains in the MANGLE table"); iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED); + iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_UNTRUSTED);/* Added by untrusted */ iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING); if (got_authdown_ruleset) iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_AUTH_IS_DOWN); iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING); iptables_do_command("-t mangle -F " CHAIN_TRUSTED); + iptables_do_command("-t mangle -F " CHAIN_UNTRUSTED); /* Added by GaomingPan */ iptables_do_command("-t mangle -F " CHAIN_OUTGOING); if (got_authdown_ruleset) iptables_do_command("-t mangle -F " CHAIN_AUTH_IS_DOWN); iptables_do_command("-t mangle -F " CHAIN_INCOMING); iptables_do_command("-t mangle -X " CHAIN_TRUSTED); + iptables_do_command("-t mangle -X " CHAIN_UNTRUSTED); /* Added by GaomingPan */ iptables_do_command("-t mangle -X " CHAIN_OUTGOING); if (got_authdown_ruleset) iptables_do_command("-t mangle -X " CHAIN_AUTH_IS_DOWN); diff --git a/src/fw_iptables.h b/src/fw_iptables.h index 83d890b7..d2f3c603 100644 --- a/src/fw_iptables.h +++ b/src/fw_iptables.h @@ -43,6 +43,7 @@ #define CHAIN_UNKNOWN "WiFiDog_$ID$_Unknown" #define CHAIN_LOCKED "WiFiDog_$ID$_Locked" #define CHAIN_TRUSTED "WiFiDog_$ID$_Trusted" +#define CHAIN_UNTRUSTED "WiFiDog_$ID$_Untrusted" /*added by GaomingPan*/ #define CHAIN_AUTH_IS_DOWN "WiFiDog_$ID$_AuthIsDown" /*@}*/ @@ -82,4 +83,10 @@ int iptables_fw_auth_reachable(void); /** @brief All counters in the client list */ int iptables_fw_counters_update(void); +/** @brief Get extern interface + * this function use at extend_util.c + * Added by GaomingPan + * */ +char *get_dev_extern_iface(); + #endif /* _IPTABLES_H_ */ diff --git a/src/gateway.c b/src/gateway.c index d5eb6ebc..599c6556 100644 --- a/src/gateway.c +++ b/src/gateway.c @@ -26,6 +26,8 @@ @author Copyright (C) 2004 Alexandre Carmel-Veilleux */ +#include "gateway.h" + #include #include #include @@ -44,21 +46,21 @@ #include #include -#include "common.h" #include "httpd.h" -#include "safe.h" -#include "debug.h" +#include "auth.h" +#include "client_list.h" +#include "commandline.h" +#include "common.h" #include "conf.h" -#include "gateway.h" +#include "debug.h" +#include "extend_util.h" #include "firewall.h" -#include "commandline.h" -#include "auth.h" #include "http.h" -#include "client_list.h" -#include "wdctl_thread.h" -#include "ping_thread.h" #include "httpd_thread.h" +#include "ping_thread.h" +#include "safe.h" #include "util.h" +#include "wdctl_thread.h" /** XXX Ugly hack * We need to remember the thread IDs of threads that simulate wait with pthread_cond_timedwait @@ -204,7 +206,10 @@ get_clients_from_parent(void) client->counters.outgoing_delta = 0; } else if (strcmp(key, "counters_last_updated") == 0) { client->counters.last_updated = atol(value); - } else { + } else if (strcmp(key, "record_time") == 0) { /* get the record_time, added by GaomingPan */ + client->record_time = atol(value); + }else { + debug(LOG_NOTICE, "I don't know how to inherit key [%s] value [%s] from parent", key, value); } @@ -417,6 +422,25 @@ main_loop(void) exit(1); } + /** + * initialize some parameters,command result send url, + * device key and mac address. + * Added by GaomingPan. + * */ + if(0 != init_post_http_url_config() ){ + debug(LOG_WARNING, "Warning: Failed to initialize init_post_http_url_config"); + //exit(1); + } + /*init device key*/ + if(0 != init_device_key()){ + debug(LOG_WARNING,"Warning:Failed to initalize device key."); + } + /*get ap mac*/ + if(0 != get_apmac(NULL)){ + debug(LOG_WARNING,"Warning:Failed to get ap MAC."); + } + /*********************************/ + /* Start clean up thread */ result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { diff --git a/src/ping_thread.c b/src/ping_thread.c index 3475379e..63ac57d8 100644 --- a/src/ping_thread.c +++ b/src/ping_thread.c @@ -56,6 +56,8 @@ #include "gateway.h" #include "simple_http.h" +#include "extend_util.h" + static void ping(void); /** Launches a thread that periodically checks in with the wifidog auth server to perform heartbeat function. @@ -153,13 +155,22 @@ ping(void) fclose(fh); } + /** Get device info. + * Added by GaomingPan + * */ + t_devinfo *infoptr = NULL; + infoptr = get_devinfo(); + char *cmdptr; /* a char pointer which point to + the remote command*/ + /* * Prep & send request */ snprintf(request, sizeof(request) - 1, - "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu HTTP/1.0\r\n" + "GET %s%sgw_id=%s&sys_uptime=%lu&sys_memfree=%u&sys_load=%.2f&wifidog_uptime=%lu&gw_mac=%s&gw_ssid=%s&cur_conn=%d&dev_conn=%d&cpu_use=%d&dog_version=%s&wan_ip=%s&go_speed=%u&come_speed=%u&incoming=%llu&outgoing=%llu HTTP/1.0\r\n" "User-Agent: WiFiDog %s\r\n" "Host: %s\r\n" + "DeviceKey: %s\r\n" "\r\n", auth_server->authserv_path, auth_server->authserv_ping_script_path_fragment, @@ -168,7 +179,27 @@ ping(void) sys_memfree, sys_load, (long unsigned int)((long unsigned int)time(NULL) - (long unsigned int)started_time), - VERSION, auth_server->authserv_hostname); + + /* new parameters,added by GaomingPan */ + infoptr->gw_mac, + infoptr->gw_ssid, + infoptr->cur_conn, + infoptr->dev_conn, + infoptr->cpu_use, + infoptr->dog_version, + infoptr->wan_ip, + infoptr->go_speed, + infoptr->come_speed, + infoptr->incoming, + infoptr->outgoing, + /******************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by GaomingPan */ + get_device_key() + ); + debug(LOG_INFO,"PingQString:[[<< ===================\n\n %s ================= >>]]\n\n",request); char *res; #ifdef USE_CYASSL @@ -200,7 +231,25 @@ ping(void) fw_set_authup(); authdown = 0; } - free(res); + //free(res); + + /** + * Now,do the remote command business. + * Added by GaomingPan. + * */ + cmdptr = strstr(res,"|"); + + if(NULL == cmdptr){ + debug(LOG_INFO,"[[<< ========= NO remote commands ========= >>]]"); + }else{ + cmdptr = get_shell_command(++cmdptr); + if(cmdptr){ + excute_shell_command(config_get_config()->gw_id,cmdptr); + } + } + /**********************/ + + free(res); } return; } diff --git a/src/pstring.c b/src/pstring.c index 6cd8ed12..d12c724d 100644 --- a/src/pstring.c +++ b/src/pstring.c @@ -24,12 +24,13 @@ @author Copyright (C) 2015 Alexandre Carmel-Veilleux */ +#include "pstring.h" + #include #include -#include "safe.h" -#include "pstring.h" #include "common.h" +#include "safe.h" static void _pstr_grow(pstr_t *); diff --git a/src/simple_http.c b/src/simple_http.c index f0e27eec..827739d9 100644 --- a/src/simple_http.c +++ b/src/simple_http.c @@ -31,10 +31,10 @@ #include #include -#include "../config.h" #include "common.h" #include "debug.h" #include "pstring.h" +#include "../config.h" #ifdef USE_CYASSL #include diff --git a/src/wd_util.c b/src/wd_util.c index fa8139a1..71b15ba1 100644 --- a/src/wd_util.c +++ b/src/wd_util.c @@ -167,6 +167,7 @@ get_status_text() time_t uptime = 0; unsigned int days = 0, hours = 0, minutes = 0, seconds = 0; t_trusted_mac *p; + t_untrusted_mac *unp;/* added by GaomingPan */ pstr_cat(pstr, "WiFiDog status\n\n"); @@ -225,6 +226,16 @@ get_status_text() pstr_append_sprintf(pstr, " %s\n", p->mac); } } + /** show Untrusted MAC list, + * added by GaomingPan + * */ + if (config->untrustedmaclist != NULL) { + pstr_cat(pstr, "\nUntrusted MAC addresses:\n"); + + for (unp = config->untrustedmaclist; unp != NULL; unp = unp->next) { + pstr_append_sprintf(pstr, " %s\n",unp->mac); + } + } pstr_cat(pstr, "\nAuthentication servers:\n"); diff --git a/src/wdctl_thread.c b/src/wdctl_thread.c index eb7491bc..108bec1e 100644 --- a/src/wdctl_thread.c +++ b/src/wdctl_thread.c @@ -315,10 +315,11 @@ wdctl_restart(int afd) client = client_get_first_client(); while (client) { /* Send this client */ + /* add a parameter "record_time",added by GaomingPan */ safe_asprintf(&tempstring, - "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu\n", + "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu|record_time=%l\n", client->ip, client->mac, client->token, client->fw_connection_state, client->fd, - client->counters.incoming, client->counters.outgoing, client->counters.last_updated); + client->counters.incoming, client->counters.outgoing, client->counters.last_updated, client->record_time ); debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); write_to_socket(fd, tempstring, strlen(tempstring)); /* XXX Despicably not handling error. */ free(tempstring); diff --git a/wifidog.conf b/wifidog.conf index fd953f05..9039772d 100644 --- a/wifidog.conf +++ b/wifidog.conf @@ -253,6 +253,14 @@ PopularServers kernel.org,ieee.org # #TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D +# Parameter: UntrustedMACList +# Default: none +# Optional +# +# Comma separated list of MAC addresses who are not allowed to pass +# through without authentication +#UntrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D + # Parameter: FirewallRuleSet # Default: none # Mandatory From e98918be259b8356a366993a9d2046fb0e36679f Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Tue, 27 Oct 2015 13:46:35 +0800 Subject: [PATCH 30/33] v1.2.1 Beta-2 --- configure.in | 4 ++-- src/fw_iptables.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/configure.in b/configure.in index 89057226..7a3372cc 100644 --- a/configure.in +++ b/configure.in @@ -24,8 +24,8 @@ WIFIDOG_MINOR_VERSION=2 WIFIDOG_MICRO_VERSION=1 WIFIDOG_VERSION=$WIFIDOG_MAJOR_VERSION.$WIFIDOG_MINOR_VERSION.$WIFIDOG_MICRO_VERSION -# I want to use Semantic Beta Versioning like this x.y.z-Beta.x for test my new features. -WIFIDOG_BETA_VERSION=Beta-1 +# I want to use Semantic Beta Versioning like this x.y.z-Beta-x for test my new features. +WIFIDOG_BETA_VERSION=Beta-2 WIFIDOG_VERSION=$WIFIDOG_VERSION-$WIFIDOG_BETA_VERSION diff --git a/src/fw_iptables.c b/src/fw_iptables.c index a246e9c3..30035c10 100644 --- a/src/fw_iptables.c +++ b/src/fw_iptables.c @@ -313,15 +313,19 @@ iptables_fw_init(void) iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " CHAIN_INCOMING, config->gw_interface); for (p = config->trustedmaclist; p != NULL; p = p->next) - iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, - FW_MARK_KNOWN); + iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac, + FW_MARK_KNOWN); /** Untrusted MAC. * Added by GaomingPan + * 1ă€é˜»æ­¢MAC地å€ä¸ºXX:XX:XX:XX:XX:XXä¸»æœºç„æ‰€æœ‰é€ä¿¡ï¼ + * iptables -A INPUT -m mac --mac-source XX:XX:XX:XX:XX:XX -j DROP + * * */ for (unp = config->untrustedmaclist; unp != NULL; unp = unp->next) - iptables_do_command("-t mangle -A " CHAIN_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", unp->mac, - FW_MARK_LOCKED); + iptables_do_command("-t mangle -A " CHAIN_UNTRUSTED " -m mac --mac-source %s -j DROP", unp->mac); + //iptables_do_command("-t mangle -A " CHAIN_UNTRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", unp->mac, + // FW_MARK_LOCKED); /* * From 94832d3010db92f7f0dc36eb8db2fd4acb195791 Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 30 Nov 2015 10:15:56 +0800 Subject: [PATCH 31/33] fix a error named script function name --- scripts/conf/dog_alive | 2 +- scripts/conf/wifidog_conf | 9 +- scripts/dog_conf_generator.sh | 18 +- src/centralserver.c | 750 +++++++++++++++++----------------- src/extend_util.c | 6 +- src/extend_util.h | 64 ++- 6 files changed, 422 insertions(+), 427 deletions(-) diff --git a/scripts/conf/dog_alive b/scripts/conf/dog_alive index 671a269c..039c0157 100644 --- a/scripts/conf/dog_alive +++ b/scripts/conf/dog_alive @@ -1,4 +1,4 @@ package 'dog_alive' config 'dog_alive' - option is_alive '1' \ No newline at end of file + option is_alive '0' \ No newline at end of file diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index 9db2e823..4484e2c4 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -19,11 +19,13 @@ config 'wifidog_conf' 'single' config 'wifidog_conf' 'authServer' - option 'hostname' 'Hostname wifi.xiao8web.com' + # option 'hostname' 'Hostname wifi.xiao8web.com' + # wei xin + option 'hostname' 'Hostname auth.octodata.com.cn' option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' option 'sslPort' '# SSLPort (Optional;Default:443)' - option 'httpPort' 'HTTPPort 12347' - option 'path' 'Path /WiFiAuth/wifidog/' + option 'httpPort' 'HTTPPort 8080' + option 'path' 'Path /WiFiAuth/v1/wifidog/' option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' @@ -52,6 +54,7 @@ config 'wifidog_conf' 'whiteBlackList' config 'wifidog_conf' 'firewallRule_global' list 'FirewallRuleSet_global' '# FirewallRule block to 192.168.0.0/16 L' list 'FirewallRuleSet_global' '# FirewallRule block to 172.16.0.0/12 L' + list 'FirewallRuleSet_global' 'FirewallRule allow to auth.octodata.com.cn L' config 'wifidog_conf' 'firewallRule_validating_users' diff --git a/scripts/dog_conf_generator.sh b/scripts/dog_conf_generator.sh index d2192933..cc0736a0 100644 --- a/scripts/dog_conf_generator.sh +++ b/scripts/dog_conf_generator.sh @@ -5,11 +5,11 @@ # # Author : GaomingPan # Date : 2015-08-05 -# Version: 1.0.0 +# Version: 1.0.3 # ############################################################################################################### -version="1.0.0" +version="1.0.3" WIFI_DOG_CONF_FILE=/etc/wifidog.conf WIFI_DOG_CONF=/etc/config/wifidog_conf @@ -100,7 +100,10 @@ generate_firewallRule_global() echo "}" >> $WIFI_DOG_CONF_FILE } - +generate_PopularServer() +{ + echo "PopularServers wifi.xiao8web.com,kernel.org" >> $WIFI_DOG_CONF_FILE +} generate_firewallRule_validating_users() { @@ -124,6 +127,13 @@ generate_firewallRule_unknown_users() echo "}" >> $WIFI_DOG_CONF_FILE } +generate_firewallRule_auth_is_down() +{ + echo "FirewallRuleSet auth-is-down {" >> $WIFI_DOG_CONF_FILE + echo "FirewallRule allow to 0.0.0.0/0" >> $WIFI_DOG_CONF_FILE + echo "}" >> $WIFI_DOG_CONF_FILE +} + generate_firewallRule_locked_users() { echo "FirewallRuleSet locked-users {" >> $WIFI_DOG_CONF_FILE @@ -160,6 +170,7 @@ generate_wifidog_conf_file() generate_authServer generate_trustedMACList generate_untrustedMACList + generate_PopularServer generate_whiteList generate_blackList generate_firewallRule_global @@ -167,6 +178,7 @@ generate_wifidog_conf_file() generate_firewallRule_known_users generate_firewallRule_unknown_users generate_firewallRule_locked_users + generate_firewallRule_auth_is_down conf_character_check } diff --git a/src/centralserver.c b/src/centralserver.c index 7a478ef2..c5f230c3 100644 --- a/src/centralserver.c +++ b/src/centralserver.c @@ -21,12 +21,10 @@ /* $Id$ */ /** @file centralserver.c - @brief Functions to talk to the central server (auth/send stats/get rules/etc...) - @author Copyright (C) 2004 Philippe April + @brief Functions to talk to the central server (auth/send stats/get rules/etc...) + @author Copyright (C) 2004 Philippe April */ - - #include #include #include @@ -56,402 +54,402 @@ #include "extend_util.h" - /** Initiates a transaction with the auth server, either to authenticate or to * update the traffic counters at the server -@param authresponse Returns the information given by the central server -@param request_type Use the REQUEST_TYPE_* defines in centralserver.h -@param ip IP adress of the client this request is related to -@param mac MAC adress of the client this request is related to -@param token Authentification token of the client -@param incoming Current counter of the client's total incoming traffic, in bytes -@param outgoing Current counter of the client's total outgoing traffic, in bytes -*/ -t_authcode -auth_server_request(t_authresponse * authresponse, const char *request_type, const char *ip, const char *mac, - const char *token, unsigned long long int incoming, unsigned long long int outgoing, unsigned long long int incoming_delta, unsigned long long int outgoing_delta) + @param authresponse Returns the information given by the central server + @param request_type Use the REQUEST_TYPE_* defines in centralserver.h + @param ip IP adress of the client this request is related to + @param mac MAC adress of the client this request is related to + @param token Authentification token of the client + @param incoming Current counter of the client's total incoming traffic, in bytes + @param outgoing Current counter of the client's total outgoing traffic, in bytes + */ +t_authcode auth_server_request(t_authresponse * authresponse, + const char *request_type, const char *ip, const char *mac, + const char *token, unsigned long long int incoming, + unsigned long long int outgoing, unsigned long long int incoming_delta, + unsigned long long int outgoing_delta) { - s_config *config = config_get_config(); - int sockfd; - char buf[MAX_BUF]; - char *tmp; - char *safe_token; - t_auth_serv *auth_server = NULL; - auth_server = get_auth_server(); - - - /** - * get client's info, - * get client's online time, - * outgo rate and comin rate. - * Added by GaomingPan - * */ - t_clientinfo *client_info = NULL; - client_info = get_client_info_by_ip(ip); - time_t online_time = get_online_time(ip,mac); - int go_speed, - come_speed; - - /* Blanket default is error. */ - authresponse->authcode = AUTH_ERROR; - - sockfd = connect_auth_server(); - - /** + s_config *config = config_get_config(); + int sockfd; + char buf[MAX_BUF]; + char *tmp; + char *safe_token; + t_auth_serv *auth_server = NULL; + auth_server = get_auth_server(); + + /** + * get client's info, + * get client's online time, + * outgo rate and comin rate. + * Added by TianyuanPan + * */ + t_clientinfo *client_info = NULL; + client_info = get_client_info_by_ip(ip); + time_t online_time = get_online_time(ip, mac); + int go_speed, come_speed; + + /* Blanket default is error. */ + authresponse->authcode = AUTH_ERROR; + + sockfd = connect_auth_server(); + + /** * TODO: XXX change the PHP so we can harmonize stage as request_type * everywhere. */ - memset(buf, 0, sizeof(buf)); - safe_token = httpdUrlEncode(token); - - if(client_info){ - if(config -> deltatraffic) { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, mac, safe_token, - incoming, - outgoing, - incoming_delta, - outgoing_delta, - config->gw_id, - - /* new parameters,added by GaomingPan */ - client_info->host_name, - client_info->go_speed, - client_info->come_speed, - online_time, - get_client_auth_flag(), - /**************************************/ - - VERSION, auth_server->authserv_hostname, - - /* add a device key to the header.Added by GaomingPan */ - get_device_key() - ); - } else { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, safe_token, incoming, outgoing, config->gw_id, - - /* new parameters,added by GaomingPan */ - client_info->host_name, - client_info->go_speed, - client_info->come_speed, - online_time, - get_client_auth_flag(), - /**************************************/ - - VERSION, auth_server->authserv_hostname, - - /* add a device key to the header.Added by GaomingPan */ - get_device_key() - ); - } - }else{//if(client_info) - get_unknown_client_speed(ip,&go_speed,&come_speed); - if(config -> deltatraffic) { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, mac, safe_token, - incoming, - outgoing, - incoming_delta, - outgoing_delta, - config->gw_id, - - /* new parameters,added by GaomingPan */ - "unknown",//client_info->host_name, - go_speed, //client_info->go_speed, - come_speed, //client_info->come_speed, - online_time, //online_time, - get_client_auth_flag(), - /**************************************/ - - VERSION, auth_server->authserv_hostname, - - /* add a device key to the header.Added by GaomingPan */ - get_device_key() - ); - } else { - snprintf(buf, (sizeof(buf) - 1), - "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" - "User-Agent: WiFiDog %s\r\n" - "Host: %s\r\n" - "DeviceKey: %s\r\n" - "\r\n", - auth_server->authserv_path, - auth_server->authserv_auth_script_path_fragment, - request_type, - ip, - mac, safe_token, incoming, outgoing, config->gw_id, - - /* new parameters,added by GaomingPan */ - "unknown",//client_info->host_name, - go_speed, //client_info->go_speed, - come_speed, //client_info->come_speed, - online_time, //online_time, - get_client_auth_flag(), - /**************************************/ - - VERSION, auth_server->authserv_hostname, - - /* add a device key to the header.Added by GaomingPan */ - get_device_key() - ); - } - }//if(client_info) - - free(safe_token); - - debug(LOG_INFO, "\n\nSendingQString: [[<<================\n %s ==================>>]]\n\n", buf); - - char *res; + memset(buf, 0, sizeof(buf)); + safe_token = httpdUrlEncode(token); + + if (client_info) { + if (config->deltatraffic) { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, ip, mac, safe_token, incoming, outgoing, + incoming_delta, outgoing_delta, config->gw_id, + + /* new parameters,added by TianyuanPan */ + client_info->host_name, client_info->go_speed, + client_info->come_speed, online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by TianyuanPan */ + get_device_key()); + } else { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, ip, mac, safe_token, incoming, outgoing, + config->gw_id, + + /* new parameters,added by TianyuanPan */ + client_info->host_name, client_info->go_speed, + client_info->come_speed, online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by TianyuanPan */ + get_device_key()); + } + } else { //if(client_info) + get_unknown_client_speed(ip, &go_speed, &come_speed); + if (config->deltatraffic) { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&incomingdelta=%llu&outgoingdelta=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, ip, mac, safe_token, incoming, outgoing, + incoming_delta, outgoing_delta, config->gw_id, + + /* new parameters,added by TianyuanPan */ + "unknown", //client_info->host_name, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by TianyuanPan */ + get_device_key()); + } else { + snprintf(buf, (sizeof(buf) - 1), + "GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s&host_name=%s&go_speed=%d&come_speed=%d&online_time=%ld&flag=%s HTTP/1.0\r\n" + "User-Agent: WiFiDog %s\r\n" + "Host: %s\r\n" + "DeviceKey: %s\r\n" + "\r\n", auth_server->authserv_path, + auth_server->authserv_auth_script_path_fragment, + request_type, ip, mac, safe_token, incoming, outgoing, + config->gw_id, + + /* new parameters,added by TianyuanPan */ + "unknown", //client_info->host_name, + go_speed, //client_info->go_speed, + come_speed, //client_info->come_speed, + online_time, //online_time, + get_client_auth_flag(), + /**************************************/ + + VERSION, auth_server->authserv_hostname, + + /* add a device key to the header.Added by TianyuanPan */ + get_device_key()); + } + } //if(client_info) + + free(safe_token); + + debug(LOG_INFO, + "\n\nSendingQString: [[<<================\n %s ==================>>]]\n\n", + buf); + + char *res; #ifdef USE_CYASSL - if (auth_server->authserv_use_ssl) { - res = https_get(sockfd, buf, auth_server->authserv_hostname); - } else { - res = http_get(sockfd, buf); - } + if (auth_server->authserv_use_ssl) { + res = https_get(sockfd, buf, auth_server->authserv_hostname); + } else { + res = http_get(sockfd, buf); + } #endif #ifndef USE_CYASSL - res = http_get(sockfd, buf); + res = http_get(sockfd, buf); #endif - if (NULL == res) { - debug(LOG_ERR, "There was a problem talking to the auth server!"); - return (AUTH_ERROR); - } - - if ((tmp = strstr(res, "Auth: "))) { - if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) { - debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode); - free(res); - return (authresponse->authcode); - } else { - debug(LOG_WARNING, "Auth server did not return expected authentication code"); - free(res); - return (AUTH_ERROR); - } - } - free(res); - return (AUTH_ERROR); + if (NULL == res) { + debug(LOG_ERR, "There was a problem talking to the auth server!"); + return (AUTH_ERROR); + } + + if ((tmp = strstr(res, "Auth: "))) { + if (sscanf(tmp, "Auth: %d", (int *) &authresponse->authcode) == 1) { + debug(LOG_INFO, "Auth server returned authentication code %d", + authresponse->authcode); + free(res); + return (authresponse->authcode); + } else { + debug(LOG_WARNING, + "Auth server did not return expected authentication code"); + free(res); + return (AUTH_ERROR); + } + } + free(res); + return (AUTH_ERROR); } /* Tries really hard to connect to an auth server. Returns a file descriptor, -1 on error */ -int -connect_auth_server() +int connect_auth_server() { - int sockfd; - - LOCK_CONFIG(); - sockfd = _connect_auth_server(0); - UNLOCK_CONFIG(); - - if (sockfd == -1) { - debug(LOG_ERR, "Failed to connect to any of the auth servers"); - mark_auth_offline(); - } else { - debug(LOG_DEBUG, "Connected to auth server"); - mark_auth_online(); - } - return (sockfd); + int sockfd; + + LOCK_CONFIG() + ; + sockfd = _connect_auth_server(0); + UNLOCK_CONFIG() + ; + + if (sockfd == -1) { + debug(LOG_ERR, "Failed to connect to any of the auth servers"); + mark_auth_offline(); + } else { + debug(LOG_DEBUG, "Connected to auth server"); + mark_auth_online(); + } + return (sockfd); } /* Helper function called by connect_auth_server() to do the actual work including recursion * DO NOT CALL DIRECTLY @param level recursion level indicator must be 0 when not called by _connect_auth_server() */ -int -_connect_auth_server(int level) +int _connect_auth_server(int level) { - s_config *config = config_get_config(); - t_auth_serv *auth_server = NULL; - t_popular_server *popular_server = NULL; - struct in_addr *h_addr; - int num_servers = 0; - char *hostname = NULL; - char *ip; - struct sockaddr_in their_addr; - int sockfd; - - /* If there are no auth servers, error out, from scan-build warning. */ - if (NULL == config->auth_servers) { - return (-1); - } - - /* XXX level starts out at 0 and gets incremented by every iterations. */ - level++; - - /* - * Let's calculate the number of servers we have - */ - for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) { - num_servers++; - } - debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers); - - if (level > num_servers) { - /* - * We've called ourselves too many times - * This means we've cycled through all the servers in the server list - * at least once and none are accessible - */ - return (-1); - } - - /* - * Let's resolve the hostname of the top server to an IP address - */ - auth_server = config->auth_servers; - hostname = auth_server->authserv_hostname; - debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname); - h_addr = wd_gethostbyname(hostname); - if (!h_addr) { - /* - * DNS resolving it failed - */ - debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname); - - for (popular_server = config->popular_servers; popular_server; popular_server = popular_server->next) { - debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, popular_server->hostname); - h_addr = wd_gethostbyname(popular_server->hostname); - if (h_addr) { - debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] succeeded = [%s]", level, popular_server->hostname, - inet_ntoa(*h_addr)); - break; - } else { - debug(LOG_DEBUG, "Level %d: Resolving popular server [%s] failed", level, popular_server->hostname); - } - } - - /* - * If we got any h_addr buffer for one of the popular servers, in other - * words, if one of the popular servers resolved, we'll assume the DNS - * works, otherwise we'll deal with net connection or DNS failure. - */ - if (h_addr) { - free(h_addr); - /* - * Yes - * - * The auth server's DNS server is probably dead. Try the next auth server - */ - debug(LOG_DEBUG, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname); - if (auth_server->last_ip) { - free(auth_server->last_ip); - auth_server->last_ip = NULL; - } - mark_auth_server_bad(auth_server); - return _connect_auth_server(level); - } else { - /* - * No - * - * It's probably safe to assume that the internet connection is malfunctioning - * and nothing we can do will make it work - */ - mark_offline(); - debug(LOG_DEBUG, "Level %d: Failed to resolve auth server and all popular servers. " - "The internet connection is probably down", level); - return (-1); - } - } else { - /* - * DNS resolving was successful - */ - mark_online(); - ip = safe_strdup(inet_ntoa(*h_addr)); - debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip); - - if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) { - /* - * But the IP address is different from the last one we knew - * Update it - */ - debug(LOG_DEBUG, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip); - if (auth_server->last_ip) - free(auth_server->last_ip); - auth_server->last_ip = ip; - - /* Update firewall rules */ - fw_clear_authservers(); - fw_set_authservers(); - } else { - /* - * IP is the same as last time - */ - free(ip); - } - - /* - * Connect to it - */ - int port = 0; + s_config *config = config_get_config(); + t_auth_serv *auth_server = NULL; + t_popular_server *popular_server = NULL; + struct in_addr *h_addr; + int num_servers = 0; + char *hostname = NULL; + char *ip; + struct sockaddr_in their_addr; + int sockfd; + + /* If there are no auth servers, error out, from scan-build warning. */ + if (NULL == config->auth_servers) { + return (-1); + } + + /* XXX level starts out at 0 and gets incremented by every iterations. */ + level++; + + /* + * Let's calculate the number of servers we have + */ + for (auth_server = config->auth_servers; auth_server; auth_server = + auth_server->next) { + num_servers++; + } + debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, + num_servers); + + if (level > num_servers) { + /* + * We've called ourselves too many times + * This means we've cycled through all the servers in the server list + * at least once and none are accessible + */ + return (-1); + } + + /* + * Let's resolve the hostname of the top server to an IP address + */ + auth_server = config->auth_servers; + hostname = auth_server->authserv_hostname; + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname); + h_addr = wd_gethostbyname(hostname); + if (!h_addr) { + /* + * DNS resolving it failed + */ + debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, + hostname); + + for (popular_server = config->popular_servers; popular_server; + popular_server = popular_server->next) { + debug(LOG_DEBUG, "Level %d: Resolving popular server [%s]", level, + popular_server->hostname); + h_addr = wd_gethostbyname(popular_server->hostname); + if (h_addr) { + debug(LOG_DEBUG, + "Level %d: Resolving popular server [%s] succeeded = [%s]", + level, popular_server->hostname, inet_ntoa(*h_addr)); + break; + } else { + debug(LOG_DEBUG, + "Level %d: Resolving popular server [%s] failed", level, + popular_server->hostname); + } + } + + /* + * If we got any h_addr buffer for one of the popular servers, in other + * words, if one of the popular servers resolved, we'll assume the DNS + * works, otherwise we'll deal with net connection or DNS failure. + */ + if (h_addr) { + free(h_addr); + /* + * Yes + * + * The auth server's DNS server is probably dead. Try the next auth server + */ + debug(LOG_DEBUG, + "Level %d: Marking auth server [%s] as bad and trying next if possible", + level, hostname); + if (auth_server->last_ip) { + free(auth_server->last_ip); + auth_server->last_ip = NULL; + } + mark_auth_server_bad(auth_server); + return _connect_auth_server(level); + } else { + /* + * No + * + * It's probably safe to assume that the internet connection is malfunctioning + * and nothing we can do will make it work + */ + mark_offline(); + debug(LOG_DEBUG, + "Level %d: Failed to resolve auth server and all popular servers. " + "The internet connection is probably down", level); + return (-1); + } + } else { + /* + * DNS resolving was successful + */ + mark_online(); + ip = safe_strdup(inet_ntoa(*h_addr)); + debug(LOG_DEBUG, + "Level %d: Resolving auth server [%s] succeeded = [%s]", level, + hostname, ip); + + if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) { + /* + * But the IP address is different from the last one we knew + * Update it + */ + debug(LOG_DEBUG, + "Level %d: Updating last_ip IP of server [%s] to [%s]", + level, hostname, ip); + if (auth_server->last_ip) + free(auth_server->last_ip); + auth_server->last_ip = ip; + + /* Update firewall rules */ + fw_clear_authservers(); + fw_set_authservers(); + } else { + /* + * IP is the same as last time + */ + free(ip); + } + + /* + * Connect to it + */ + int port = 0; #ifdef USE_CYASSL - if (auth_server->authserv_use_ssl) { - debug(LOG_DEBUG, "Level %d: Connecting to SSL auth server %s:%d", level, hostname, - auth_server->authserv_ssl_port); - port = htons(auth_server->authserv_ssl_port); - } else { - debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, - auth_server->authserv_http_port); - port = htons(auth_server->authserv_http_port); - } + if (auth_server->authserv_use_ssl) { + debug(LOG_DEBUG, "Level %d: Connecting to SSL auth server %s:%d", level, hostname, + auth_server->authserv_ssl_port); + port = htons(auth_server->authserv_ssl_port); + } else { + debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, + auth_server->authserv_http_port); + port = htons(auth_server->authserv_http_port); + } #endif #ifndef USE_CYASSL - debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port); - port = htons(auth_server->authserv_http_port); + debug(LOG_DEBUG, "Level %d: Connecting to auth server %s:%d", level, + hostname, auth_server->authserv_http_port); + port = htons(auth_server->authserv_http_port); #endif - their_addr.sin_port = port; - their_addr.sin_family = AF_INET; - their_addr.sin_addr = *h_addr; - memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero)); - free(h_addr); - - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno)); - return (-1); - } - - if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { - /* - * Failed to connect - * Mark the server as bad and try the next one - */ - debug(LOG_DEBUG, - "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", - level, hostname, ntohs(port), strerror(errno)); - close(sockfd); - mark_auth_server_bad(auth_server); - return _connect_auth_server(level); /* Yay recursion! */ - } else { - /* - * We have successfully connected - */ - debug(LOG_DEBUG, "Level %d: Successfully connected to auth server %s:%d", level, hostname, ntohs(port)); - return sockfd; - } - } + their_addr.sin_port = port; + their_addr.sin_family = AF_INET; + their_addr.sin_addr = *h_addr; + memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero)); + free(h_addr); + + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + debug(LOG_ERR, + "Level %d: Failed to create a new SOCK_STREAM socket: %s", + strerror(errno)); + return (-1); + } + + if (connect(sockfd, (struct sockaddr *) &their_addr, + sizeof(struct sockaddr)) == -1) { + /* + * Failed to connect + * Mark the server as bad and try the next one + */ + debug(LOG_DEBUG, + "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", + level, hostname, ntohs(port), strerror(errno)); + close(sockfd); + mark_auth_server_bad(auth_server); + return _connect_auth_server(level); /* Yay recursion! */ + } else { + /* + * We have successfully connected + */ + debug(LOG_DEBUG, + "Level %d: Successfully connected to auth server %s:%d", + level, hostname, ntohs(port)); + return sockfd; + } + } } diff --git a/src/extend_util.c b/src/extend_util.c index e13c8f5f..30103367 100644 --- a/src/extend_util.c +++ b/src/extend_util.c @@ -2,7 +2,7 @@ * extend_util.c * * Created on: Oct 10, 2015 - * Author: GaomingPan + * Author: TianyuanPan */ #include "extend_util.h" @@ -1069,7 +1069,7 @@ static char device_key[64] = {0}; /* @breif get the global device key.the key will be use as auth key * @PARAMETER: void * @RETURN_VALUE: a none NULL char pointer - * GaomingPan lonely-test:yes + * TianyuanPan lonely-test:yes * */ char * get_device_key() { @@ -1083,7 +1083,7 @@ char * get_device_key() * @PARAMETER: void * @RETURN_VALUE: success return zero and set the KEY in the device key global array, * failed return a none zero number. - * GaomingPan lonely-test:yes + * TianyuanPan lonely-test:yes * */ int init_device_key() { diff --git a/src/extend_util.h b/src/extend_util.h index ec925806..76d8bccf 100644 --- a/src/extend_util.h +++ b/src/extend_util.h @@ -2,7 +2,7 @@ * extend_util.h * * Created on: Oct 10, 2015 - * Author: GaomingPan + * Author: TianyuanPan */ #ifndef _EXTEND_UTIL_H_ @@ -15,16 +15,17 @@ #define DEV_SSID_NAME_LEN 20 #define DEV_DOG_VERSION_LEN 20 #define DEV_WAN_IP_LEN 16 -struct _t_devinfo{ + +struct _t_devinfo { char gw_mac[DEV_MAC_ADDR_LEN]; // ap mac address char gw_ssid[DEV_SSID_NAME_LEN]; // ap wireless ssid char dog_version[DEV_DOG_VERSION_LEN]; // wifidog version,private. char wan_ip[DEV_WAN_IP_LEN]; // ap's wan interface ip - int cur_conn; // number of current connection client - int dev_conn; // number of connection in the device,maybe some has no authentication. - int cpu_use; // percent of use CPU - unsigned int go_speed; // wan interface go out speed - unsigned int come_speed; // wan interface come in speed + int cur_conn; // number of current connection client + int dev_conn;// number of connection in the device,maybe some has no authentication. + int cpu_use; // percent of use CPU + unsigned int go_speed; // wan interface go out speed + unsigned int come_speed; // wan interface come in speed unsigned long long incoming; // wan interface incoming bytes unsigned long long outgoing; // wan interface outgoing bytes }; @@ -35,18 +36,18 @@ struct _t_devinfo{ #define CLIENT_HOST_NAME_LEN 40 #define CLIENT_MAC_ADDRESS_LEN 18 #define CLIENT_IP_ADDRESS_LEN 16 -struct _t_clientinfo{ +struct _t_clientinfo { char client_mac[CLIENT_MAC_ADDRESS_LEN]; char client_ip[CLIENT_IP_ADDRESS_LEN]; char host_name[CLIENT_HOST_NAME_LEN]; - int go_speed; - int come_speed; + int go_speed; + int come_speed; struct _t_clientinfo *next; }; -typedef struct _t_clientinfo t_clientinfo; -typedef struct _t_devinfo t_devinfo; +typedef struct _t_clientinfo t_clientinfo; +typedef struct _t_devinfo t_devinfo; /*=============================================================*/ /** @@ -74,7 +75,6 @@ int get_devssid(char *ssid); * */ int get_dogversion(char *dogversion); - /** * @breif get wan interface ip,based on uci command. * @param wanip:the char pointer for save the wan ip @@ -95,14 +95,12 @@ int get_apmac(char *apmac); * */ int get_curconn(void); - /** * @breif get number of client who connect to the device * @return value:the number of connected client * */ int get_devconn(void); - /** * @breif get cpu use infomation,based on shell command * @param type: CPU_USER,CPU_SYS,CPU_NIC,CPU_IDLE,CPU_IO,CPU_IRQ,CPU_SIRQ,CPU_LOAD @@ -110,15 +108,13 @@ int get_devconn(void); * */ int get_cpuuse(int type); - /** * @breif get wan interface speed,based on shell command. * @param go:the pointer for save out rate * @param come:the pointer for save income rate. * @return value:zero is success,others is error. * */ -int get_wanbps(unsigned int *go,unsigned int *come); - +int get_wanbps(unsigned int *go, unsigned int *come); /** * @breif get wan interface traffic,based on shell command. @@ -129,18 +125,17 @@ int get_wanbps(unsigned int *go,unsigned int *come); * @param tx_rate: interface TX rate * @return value:zero is success,others is error * */ -int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long long *outgo,unsigned int *rx_rate,unsigned int *tx_rate); +int get_trafficCount(char *iface_name, unsigned long long *income, + unsigned long long *outgo, unsigned int *rx_rate, unsigned int *tx_rate); /*=============================================================*/ - /*=============================================================*/ /** * This part is get the client's information functions, * and some Macro defines. * */ - /** * @breif get client host name,income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell @@ -151,7 +146,6 @@ int get_trafficCount(char *iface_name,unsigned long long *income,unsigned long l * */ int collect_client_info(); - /** * @breif get unknown host name client's income speed and outgo speed,based on shell command. * this functions take at least 1 second to run,because of execute the shell @@ -161,9 +155,8 @@ int collect_client_info(); * @param come_speed: the pointer for client's incoming speed to store. * @return value: zero is success,others is error. * */ -int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed); - - +int get_unknown_client_speed(const char *client_ip, int *go_speed, + int *come_speed); /** * @breif After the function collect_client_info() called,should call this function to @@ -172,7 +165,6 @@ int get_unknown_client_speed(const char *client_ip,int *go_speed,int *come_speed * */ int clean_client_info(); - /** * @breif find the element from the client_info list by mac. * @param mac: the pointer point to by mac. @@ -181,7 +173,6 @@ int clean_client_info(); * */ t_clientinfo * get_client_info_by_mac(const char *mac); - /** * @breif find the element from the client_info list by ip. * @param ip: the pointer point to by ip. @@ -190,22 +181,18 @@ t_clientinfo * get_client_info_by_mac(const char *mac); * */ t_clientinfo * get_client_info_by_ip(const char *ip); - /** * @breif find the element from the client_info list by ip. * @param ip: the pointer point to by client's ip. * @param mac: the pointer point to by client's mac. * */ -long get_online_time(const char *ip,const char *mac); - - +long get_online_time(const char *ip, const char *mac); /* * @breif get a flage string * */ char *get_client_auth_flag(); - /* * @breif set a flage string * */ @@ -213,17 +200,15 @@ void set_client_auth_flag(); /*=============================================================*/ - /*=============================================================*/ /** * This part is get the remote shell command functions, * and some Macro defines. * */ - char *get_shell_command(char *cmdptr); -int excute_shell_command(char *gw_id,char *shellcmd); +int excute_shell_command(char *gw_id, char *shellcmd); int post_get_info_execut_output(char *cmd_output_path); @@ -231,7 +216,6 @@ int post_normal_execut_output(char *gw_id, char *cmd_id); int init_post_http_url_config(void); - /*=============================================================*/ /*=============================================================*/ @@ -243,18 +227,16 @@ int init_post_http_url_config(void); /* @breif get the global device key.the key will be use as auth key * @PARAMETER: void * @RETURN_VALUE: a none NULL char pointer - * GaomingPan lonely-test:yes + * TianyuanPan lonely-test:yes * */ char * get_device_key(); - - /* @breif get the device key from a configure file * @PARAMETER: void * @RETURN_VALUE: success return zero and set the KEY in the device key global array, * failed return a none zero number. - * GaomingPan lonely-test:yes + * TianyuanPan lonely-test:yes * */ -int init_device_key(); +int init_device_key(); #endif /* _EXTEND_UTIL_H_ */ From 6aefffd1342b11d0e01ef4da73debd32753b827f Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Mon, 7 Dec 2015 09:49:39 +0800 Subject: [PATCH 32/33] update auth server --- scripts/conf/dog_post_conf | 7 ++----- scripts/conf/wifidog_conf | 5 ++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/conf/dog_post_conf b/scripts/conf/dog_post_conf index f4b90097..9c2fdefa 100644 --- a/scripts/conf/dog_post_conf +++ b/scripts/conf/dog_post_conf @@ -1,10 +1,7 @@ config dog_post 'url' -# option 'info_url' 'http://wifi.xiao8web.com:12347/WiFiAuth/wifidog/result' -# option 'normal_url' 'http://wifi.xiao8web.com:12347/WiFiAuth/wifidog/result' - option 'info_url' 'http://118.118.118.180:8080/WiFiAuth/wifidog/result' - option 'normal_url' 'http://118.118.118.180:8080/WiFiAuth/wifidog/result' - + option 'info_url' 'http://auth.octodata.com.cn:8080/WiFiAuth/v1/wifidog/result' + option 'normal_url' 'http://auth.octodata.com.cn:8080/WiFiAuth/v1/wifidog/result' config dog_post 'rmflag' option 'info_rmflag' 'result' option 'normal_rmflag' 'result' diff --git a/scripts/conf/wifidog_conf b/scripts/conf/wifidog_conf index 4484e2c4..dd7d5846 100644 --- a/scripts/conf/wifidog_conf +++ b/scripts/conf/wifidog_conf @@ -19,8 +19,6 @@ config 'wifidog_conf' 'single' config 'wifidog_conf' 'authServer' - # option 'hostname' 'Hostname wifi.xiao8web.com' - # wei xin option 'hostname' 'Hostname auth.octodata.com.cn' option 'sslAvailable' '# SSLAvailable (Optional;Default: no;Possible values:yes,no)' option 'sslPort' '# SSLPort (Optional;Default:443)' @@ -28,7 +26,8 @@ config 'wifidog_conf' 'authServer' option 'path' 'Path /WiFiAuth/v1/wifidog/' option 'loginScriptPathFragment' '# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.)' option 'portalScriptPathFragment' '# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.)' - option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' +# option 'msgScriptPathFragment' '# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.)' + option 'msgScriptPathFragment' 'MsgScriptPathFragment gw_message/?' option 'pingScriptPathFragment' '# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.)' option 'authScriptPathFragment' '# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.)' From 452bcdb399538ccbc135538b93f4638c3fd58d0b Mon Sep 17 00:00:00 2001 From: GaomingPan <2285022179@qq.com> Date: Wed, 23 Dec 2015 16:55:53 +0800 Subject: [PATCH 33/33] release 0.0.1 --- configure.in | 4 +- contrib/airos/wifidog/Makefile | 70 ----- contrib/airos/wifidog/files.patch | 87 ------ contrib/airos/wifidog/files/wifidog.conf | 253 ------------------ contrib/airos/wifidog/files/wifidog.init | 27 -- .../wifidog/patches/100-counter_outoing.patch | 24 -- contrib/airos/wifidog/readme.txt | 43 --- contrib/build-deb/changelog | 14 - contrib/build-deb/control | 15 -- contrib/build-deb/rules | 74 ----- .../wifidog/files/wifidog.conf | 0 .../wifidog/files/wifidog.init | 0 .../wifidog/Makefile | 62 ----- .../wifidog/files/wifidog.conf | 246 ----------------- .../wifidog/files/wifidog.init | 18 -- .../wifidog/Makefile | 60 ----- .../wifidog/files/wifidog.conf | 246 ----------------- .../wifidog/files/wifidog.init | 17 -- .../wifidog/Config.in | 16 -- .../wifidog/Makefile | 65 ----- .../wifidog/files/wifidog.conf | 246 ----------------- .../wifidog/files/wifidog.init | 15 -- .../wifidog/ipkg/wifidog.conffiles | 1 - .../wifidog/ipkg/wifidog.control | 8 - src/firewall.c | 2 +- 25 files changed, 3 insertions(+), 1610 deletions(-) delete mode 100644 contrib/airos/wifidog/Makefile delete mode 100644 contrib/airos/wifidog/files.patch delete mode 100644 contrib/airos/wifidog/files/wifidog.conf delete mode 100644 contrib/airos/wifidog/files/wifidog.init delete mode 100644 contrib/airos/wifidog/patches/100-counter_outoing.patch delete mode 100644 contrib/airos/wifidog/readme.txt delete mode 100644 contrib/build-deb/changelog delete mode 100644 contrib/build-deb/control delete mode 100755 contrib/build-deb/rules rename contrib/{build-openwrt-common-1.0.0 => build-openwrt-common}/wifidog/files/wifidog.conf (100%) rename contrib/{build-openwrt-common-1.0.0 => build-openwrt-common}/wifidog/files/wifidog.init (100%) delete mode 100644 contrib/build-openwrt-kamikazeipk/wifidog/Makefile delete mode 100644 contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf delete mode 100644 contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init delete mode 100644 contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile delete mode 100644 contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf delete mode 100644 contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init delete mode 100644 contrib/build-openwrt-whiterussianipk/wifidog/Config.in delete mode 100644 contrib/build-openwrt-whiterussianipk/wifidog/Makefile delete mode 100644 contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf delete mode 100644 contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init delete mode 100644 contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles delete mode 100644 contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control diff --git a/configure.in b/configure.in index 7a3372cc..ebde3a43 100644 --- a/configure.in +++ b/configure.in @@ -24,8 +24,8 @@ WIFIDOG_MINOR_VERSION=2 WIFIDOG_MICRO_VERSION=1 WIFIDOG_VERSION=$WIFIDOG_MAJOR_VERSION.$WIFIDOG_MINOR_VERSION.$WIFIDOG_MICRO_VERSION -# I want to use Semantic Beta Versioning like this x.y.z-Beta-x for test my new features. -WIFIDOG_BETA_VERSION=Beta-2 +# I want to use Semantic Beta Versioning like this x.y.z-release-x.y.z for test my new features. +WIFIDOG_BETA_VERSION=0.0.1 WIFIDOG_VERSION=$WIFIDOG_VERSION-$WIFIDOG_BETA_VERSION diff --git a/contrib/airos/wifidog/Makefile b/contrib/airos/wifidog/Makefile deleted file mode 100644 index 4195dbf1..00000000 --- a/contrib/airos/wifidog/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (C) 2006,2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_MD5SUM:= - -PKG_FIXUP = libtool - -include $(INCLUDE_DIR)/package.mk - -define Package/wifidog - SUBMENU:=Captive Portals - SECTION:=net - CATEGORY:=Network - DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +iptables-mod-nat +iptables-mod-nat-extra +libpthread - TITLE:=A wireless captive portal solution - URL:=http://www.wifidog.org -endef - -define Package/wifidog/description - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. -endef - -define Package/wifidog/conffiles - /usr/etc/wifidog.conf -endef - -MAKE_FLAGS += \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - -define Package/wifidog/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/usr/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/usr/etc/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/usr/etc/ - $(INSTALL_DIR) $(1)/usr/etc/init.d - $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/usr/etc/init.d/wifidog -endef - -define Package/wifidog/postinst -#!/bin/sh - -# # check if the wifidog is already running, if so restart it -if /etc/init.d/wifidog status | grep 'Authentication servers' > /dev/null; then - # create copies of passwd and group, if we use squashfs - /etc/init.d/wifidog restart -fi -endef - -$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/airos/wifidog/files.patch b/contrib/airos/wifidog/files.patch deleted file mode 100644 index a877a64b..00000000 --- a/contrib/airos/wifidog/files.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- SDK.UBNT.v5.2.clean/openwrt/package/ubnt-base-files/files/init 2010-05-14 06:11:06.000000000 -0400 -+++ SDK.UBNT.v5.2/openwrt/package/ubnt-base-files/files/init 2010-07-27 12:52:36.087267563 -0400 -@@ -64,7 +64,7 @@ echo "...filesystem init done" - # making sure that critical files are in place - mkdir -p /etc/rc.d /etc/init.d - # forced update --for f in inittab rc.d/rc.sysinit rc.d/rc rc.d/rc.stop ppp; do -+for f in inittab rc.d/rc.sysinit rc.d/rc rc.d/rc.stop ppp wifidog.conf wifidog-msg.html ; do - cp -f -r /usr/etc/$f /etc/$f - done - echo "...base ok" -@@ -139,6 +139,14 @@ if [ -e /sbin/ubntconf ]; then - /sbin/ubntconf - fi - -+#adding wifidog to startup programs -+if [ -f /usr/etc/init.d/wifidog ]; then -+ cp -f /usr/etc/init.d/wifidog /etc/sysinit/wifidog.conf -+ echo "null::respawn:/usr/bin/wifidog -f" >> /etc/inittab -+ echo "wifidog" >> /etc/startup.list -+fi -+ -+ - echo "...running /sbin/init" - exec /sbin/init - ---- SDK.UBNT.v5.2.clean/openwrt/package/ubnt-base-files/files/usr/etc/rc.d/rc.softrestart 2010-05-14 06:11:06.000000000 -0400 -+++ SDK.UBNT.v5.2/openwrt/package/ubnt-base-files/files/usr/etc/rc.d/rc.softrestart 2010-07-27 12:03:15.604767622 -0400 -@@ -80,3 +80,10 @@ if [ $# -gt 0 ]; then - -p /etc/ 2>/dev/null & - fi - fi -+ -+#adding wifidog to startup programs -+if [ -f /usr/etc/init.d/wifidog ]; then -+ cp -f /usr/etc/init.d/wifidog /etc/sysinit/wifidog.conf -+ echo "null::respawn:/usr/bin/wifidog -f" >> /etc/inittab -+ echo "wifidog" >> /etc/startup.list -+fi - ---- SDK.UBNT.v5.2.clean/openwrt/.config 2010-05-18 05:03:40.000000000 -0400 -+++ SDK.UBNT.v5.2/openwrt/.config 2010-07-26 14:59:08.131750309 -0400 -@@ -888,7 +888,7 @@ CONFIG_PACKAGE_hotplug2=y - CONFIG_PACKAGE_iptables=y - CONFIG_PACKAGE_iptables-mod-conntrack=y - CONFIG_PACKAGE_iptables-mod-conntrack-extra=y --# CONFIG_PACKAGE_iptables-mod-extra is not set -+CONFIG_PACKAGE_iptables-mod-extra=y - CONFIG_PACKAGE_iptables-mod-filter=y - # CONFIG_PACKAGE_iptables-mod-imq is not set - CONFIG_PACKAGE_iptables-mod-ipopt=y -@@ -896,7 +896,7 @@ CONFIG_PACKAGE_iptables-mod-ipopt=y - # CONFIG_PACKAGE_iptables-mod-ipsec is not set - # CONFIG_PACKAGE_iptables-mod-ipset is not set - CONFIG_PACKAGE_iptables-mod-nat=y --# CONFIG_PACKAGE_iptables-mod-nat-extra is not set -+CONFIG_PACKAGE_iptables-mod-nat-extra=y - # CONFIG_PACKAGE_iptables-mod-ulog is not set - # CONFIG_PACKAGE_iptables-utils is not set - # CONFIG_PACKAGE_ldconfig is not set -@@ -963,6 +963,7 @@ CONFIG_PACKAGE_php2=y - # - # Network - # -+CONFIG_PACKAGE_wifidog=y - - # - # Monitoring -@@ -1149,7 +1150,7 @@ CONFIG_PACKAGE_kmod-ebtables=y - CONFIG_PACKAGE_kmod-ipt-core=y - CONFIG_PACKAGE_kmod-ipt-conntrack=y - CONFIG_PACKAGE_kmod-ipt-conntrack-extra=y --# CONFIG_PACKAGE_kmod-ipt-extra is not set -+CONFIG_PACKAGE_kmod-ipt-extra=y - CONFIG_PACKAGE_kmod-ipt-filter=y - # CONFIG_PACKAGE_kmod-ipt-imq is not set - CONFIG_PACKAGE_kmod-ipt-ipopt=y -@@ -1157,7 +1158,7 @@ CONFIG_PACKAGE_kmod-ipt-ipopt=y - # CONFIG_PACKAGE_kmod-ipt-ipsec is not set - # CONFIG_PACKAGE_kmod-ipt-ipset is not set - CONFIG_PACKAGE_kmod-ipt-nat=y --# CONFIG_PACKAGE_kmod-ipt-nat-extra is not set -+CONFIG_PACKAGE_kmod-ipt-nat-extra=y - CONFIG_PACKAGE_kmod-ipt-nathelper=y - # CONFIG_PACKAGE_kmod-ipt-nathelper-extra is not set - # CONFIG_PACKAGE_kmod-ipt-queue is not set - diff --git a/contrib/airos/wifidog/files/wifidog.conf b/contrib/airos/wifidog/files/wifidog.conf deleted file mode 100644 index 32e9ea90..00000000 --- a/contrib/airos/wifidog/files/wifidog.conf +++ /dev/null @@ -1,253 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface eth0 - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: auth-is-down -# -# Used when auth server is down -FirewallRuleSet auth-is-down { -# FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/airos/wifidog/files/wifidog.init b/contrib/airos/wifidog/files/wifidog.init deleted file mode 100644 index 2c6857e9..00000000 --- a/contrib/airos/wifidog/files/wifidog.init +++ /dev/null @@ -1,27 +0,0 @@ -plugin_start() { - echo "Inserting kernel modules: " - insmod ip_conntrack - insmod ip_nat - insmod ip_tables - insmod ipt_MARK - insmod ipt_mark - insmod ipt_mac - insmod ipt_REDIRECT - insmod ipt_MASQUERADE - insmod ipt_state - insmod iptable_mangle - insmod iptable_nat - insmod iptable_filter - - # echo "Starting wifidog: " - - #/usr/bin/wifidog-init start - echo - true -} -plugin_stop() { - killall wifidog - #/usr/bin/wifidog-init stop - true -} - diff --git a/contrib/airos/wifidog/patches/100-counter_outoing.patch b/contrib/airos/wifidog/patches/100-counter_outoing.patch deleted file mode 100644 index 3fa8a1ad..00000000 --- a/contrib/airos/wifidog/patches/100-counter_outoing.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/src/fw_iptables.c 2009-09-18 19:01:57.000000000 -0400 -+++ b/src/fw_iptables.c 2010-08-21 19:37:28.975094088 -0400 -@@ -513,6 +513,7 @@ iptables_fw_counters_update(void) - char *script, - ip[16], - rc; -+ char mystring[250]; - unsigned long long int counter; - t_client *p1; - struct in_addr tempaddr; -@@ -533,8 +534,11 @@ iptables_fw_counters_update(void) - while (('\n' != fgetc(output)) && !feof(output)) - ; - while (output && !(feof(output))) { -- rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); -+ rc = fgets(mystring,250,output); -+ rc = sscanf(mystring, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip); -+ //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip); - //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip); -+ - if (2 == rc && EOF != rc) { - /* Sanity*/ - if (!inet_aton(ip, &tempaddr)) { - diff --git a/contrib/airos/wifidog/readme.txt b/contrib/airos/wifidog/readme.txt deleted file mode 100644 index 38e28aa3..00000000 --- a/contrib/airos/wifidog/readme.txt +++ /dev/null @@ -1,43 +0,0 @@ --- Compiling airos with the wifidog package running at boot - -Because airos doesn't have a package manager like opkf and has a (mostly) read-only file system, we need to build the the firmware with wifidog in it to have wifidog running on airos - -1- Get the latest wifidog source code tarball from sourceforge (http://sourceforge.net/projects/wifidog/files/) and copy it to the ~/dev/wifidog directory - -2- Get the wifidog airos package directory - -cd ~/dev/wifidog -wget http://dev.wifidog.org/wiki/doc/install/airos/wifidog_airos.tar.gz -tar xvzf wifidog_airos.tar.gz - -If compiling from source, this directory is located in wifidog/contrib/airos - -3- Download the airos SDK from http://www.ubnt.com/support/downloads and copy it to the ~/dev/airos directory - -4- Untar the SDK and prepare the files - -cd ~/dev/airos -tar xvjf SDK.UBNT.v5.2.tar.bz2 -cd SDK.UBNT.v5.2 - -cd openwrt/package -ln -s ~/dev/wifidog/airos/wifidog/ -cd ../dl -ln -s ~/dev/wifidog/wifidog-20090925.tar.gz - -cd ../.. -patch -p1 < openwrt/package/wifidog/files.patch - -5- Prepare the wifidog.conf file for your network, since airos is readonly, changes to the config files cannot be done in the router - -cd ~/dev/airos/SDK.UBNT.v5.2/openwrt -mkdir -p files/usr/etc -cp package/wifidog/files/wifidog.conf files/usr/etc/wifidog.conf - -6- Edit the files/usr/etc/wifidog.conf file for your authentication server settings. Also the GatewayInterface may need to be changed if you are not using a SOHO router configuration (eth0 for SOHO router, ath0 for router) - -7- Make the os - -make world V=99 - -8- Your new image should be available in the openwrt/bin directory as XM.v5.2....bin diff --git a/contrib/build-deb/changelog b/contrib/build-deb/changelog deleted file mode 100644 index d0274250..00000000 --- a/contrib/build-deb/changelog +++ /dev/null @@ -1,14 +0,0 @@ -wifidog (1.0.0-1) stable; urgency=low - - * New init.d file. - * Inclu - * debian/rules: Configuration and init.d file added. - * Bump version in anticipation for release - - -- Guillaume Beaudoin Sun, 29 Aug 2004 23:14:12 -0400 - -wifidog (0.2.0-1) stable; urgency=low - - * Initial Package - - -- Philippe April Wed, 21 Jul 2004 15:22:50 -0500 diff --git a/contrib/build-deb/control b/contrib/build-deb/control deleted file mode 100644 index 330f63af..00000000 --- a/contrib/build-deb/control +++ /dev/null @@ -1,15 +0,0 @@ -Source: wifidog -Section: net -Priority: optional -Maintainer: Philippe April - -Package: wifidog -Architecture: any -Depends: iptables, modutils, grep, mawk | awk -Provides: libhttpd -Description: The WiFi Guard Dog client - The WiFi Gaurd Dog project is a complete and embeddable captive portal - solution for wireless community groups or individuals who wish to open - a free HotSpot while still preventing abuse of their Internet connection. - . - This package contains only the client part. diff --git a/contrib/build-deb/rules b/contrib/build-deb/rules deleted file mode 100755 index 45291ed2..00000000 --- a/contrib/build-deb/rules +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/make -f - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -build: build-stamp -build-stamp: - dh_testdir - - ./configure --prefix=/usr - $(MAKE) - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - - -$(MAKE) clean - -$(MAKE) distclean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install - mkdir -p $(CURDIR)/debian/tmp/etc - cp wifidog.conf $(CURDIR)/debian/tmp/etc - cp scripts/init.d/wifidog debian/wifidog.init - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs -# dh_installexamples -# dh_install -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installcatalogs -# dh_installpam -# dh_installmime - dh_installinit -# dh_installcron -# dh_installinfo -# dh_undocumented - dh_installman - dh_link - dh_strip - dh_compress - dh_fixperms -# dh_perl -# dh_python - dh_makeshlibs - dh_installdeb -# dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install diff --git a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf b/contrib/build-openwrt-common/wifidog/files/wifidog.conf similarity index 100% rename from contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.conf rename to contrib/build-openwrt-common/wifidog/files/wifidog.conf diff --git a/contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init b/contrib/build-openwrt-common/wifidog/files/wifidog.init similarity index 100% rename from contrib/build-openwrt-common-1.0.0/wifidog/files/wifidog.init rename to contrib/build-openwrt-common/wifidog/files/wifidog.init diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/Makefile b/contrib/build-openwrt-kamikazeipk/wifidog/Makefile deleted file mode 100644 index adec69eb..00000000 --- a/contrib/build-openwrt-kamikazeipk/wifidog/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright (C) 2006,2008 OpenWrt.org -# Copyright (C) 2008 Technologies Coeus inc. -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -# $Id$ - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_MD5SUM:= - -PKG_FIXUP = libtool - -include $(INCLUDE_DIR)/package.mk - -define Package/wifidog - SUBMENU:=Captive Portals - SECTION:=net - CATEGORY:=Network - DEPENDS:=+kmod-ipt-extra +iptables-mod-extra +kmod-ipt-ipopt +iptables-mod-ipopt +kmod-ipt-nat +iptables-mod-nat +libpthread - TITLE:=A wireless captive portal solution - URL:=http://www.wifidog.org -endef - -define Package/wifidog/description - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. -endef - -define Package/wifidog/conffiles -/etc/wifidog.conf -endef - -MAKE_FLAGS += \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - -define Package/wifidog/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog -endef - -$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf deleted file mode 100644 index c905f04c..00000000 --- a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.conf +++ /dev/null @@ -1,246 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface br-lan - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init b/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init deleted file mode 100644 index 68d4eea6..00000000 --- a/contrib/build-openwrt-kamikazeipk/wifidog/files/wifidog.init +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org -START=65 -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Print the status of the service" - - -start() { - /usr/bin/wifidog-init start -} - -stop() { - /usr/bin/wifidog-init stop -} - -status() { - /usr/bin/wifidog-init status -} \ No newline at end of file diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile deleted file mode 100644 index 3be5dbbf..00000000 --- a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright (C) 2006,2008 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 - -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_MD5SUM:= - -PKG_FIXUP = libtool - -include $(INCLUDE_DIR)/package.mk - -define Package/wifidog - SUBMENU:=Captive Portals - SECTION:=net - CATEGORY:=Network - DEPENDS:=+iptables-mod-extra +iptables-mod-ipopt +iptables-mod-nat +iptables-mod-nat-extra +libpthread - TITLE:=A wireless captive portal solution - URL:=http://www.wifidog.org -endef - -define Package/wifidog/description - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. -endef - -define Package/wifidog/conffiles -/etc/wifidog.conf -endef - -MAKE_FLAGS += \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - -define Package/wifidog/install - $(INSTALL_DIR) $(1)/usr/bin - $(INSTALL_BIN) $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(1)/usr/bin/wifidog-init - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(1)/usr/bin/ - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/etc - $(INSTALL_DATA) ./files/wifidog.conf $(1)/etc/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/wifidog-msg.html $(1)/etc/ - $(INSTALL_DIR) $(1)/etc/init.d - $(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/wifidog -endef - -$(eval $(call BuildPackage,wifidog)) diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf deleted file mode 100644 index c905f04c..00000000 --- a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.conf +++ /dev/null @@ -1,246 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface br-lan - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init b/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init deleted file mode 100644 index 1cbbafda..00000000 --- a/contrib/build-openwrt-kamikazeipk8.09up/wifidog/files/wifidog.init +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org -START=65 -EXTRA_COMMANDS="status" -EXTRA_HELP=" status Print the status of the service" - -start() { - /usr/bin/wifidog-init start -} - -stop() { - /usr/bin/wifidog-init stop -} - -status() { - /usr/bin/wifidog-init status -} diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/Config.in b/contrib/build-openwrt-whiterussianipk/wifidog/Config.in deleted file mode 100644 index 7b67874b..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/Config.in +++ /dev/null @@ -1,16 +0,0 @@ -config BR2_PACKAGE_WIFIDOG - prompt "wifidog........................... A wireless captive portal solution" - tristate - default m if CONFIG_DEVEL - select BR2_PACKAGE_LIBPTHREAD - select BR2_PACKAGE_IPTABLES - select BR2_PACKAGE_IPTABLES_MOD_NAT - select BR2_PACKAGE_IPTABLES-MOD_IPOPT - help - The Wifidog project is a complete and embeddable captive - portal solution for wireless community groups or individuals - who wish to open a free Hotspot while still preventing abuse - of their Internet connection. - - http://dev.wifidog.org/ - diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/Makefile b/contrib/build-openwrt-whiterussianipk/wifidog/Makefile deleted file mode 100644 index 42df3f22..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# $Id: $ -ifndef TOPDIR - ERR := $(Please set TOPDIR to OpenWRT SDK's buildroot) -endif - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wifidog -PKG_VERSION:=20090925 -PKG_RELEASE:=1 -PKG_MD5SUM:= - -PKG_SOURCE_URL:= @SF/$(PKG_NAME) -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_CAT:=zcat -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) -PKG_INSTALL_DIR:=$(PKG_BUILD_DIR)/ipkg-install -include $(TOPDIR)/package/rules.mk -$(eval $(call PKG_template,WIFIDOG,$(PKG_NAME),$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH))) -$(PKG_BUILD_DIR)/.configured: $(PKG_BUILD_DIR)/.prepared - (cd $(PKG_BUILD_DIR); \ - $(TARGET_CONFIGURE_OPTS) \ - CFLAGS="$(TARGET_CFLAGS)" \ - CPPFLAGS="-I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \ - LDFLAGS="-L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib" \ - ./configure \ - --target=$(GNU_TARGET_NAME) \ - --host=$(GNU_TARGET_NAME) \ - --build=$(GNU_HOST_NAME) \ - --prefix=/usr \ - --sysconfdir=/etc \ - --without-libiconv-prefix \ - --without-libintl-prefix \ - --disable-nls \ - ); - ## Add software specific configurable options above - ## See : ./configure --help - touch $@ - -$(PKG_BUILD_DIR)/.built: - $(MAKE) -C $(PKG_BUILD_DIR) \ - $(TARGET_CONFIGURE_OPTS) - mkdir -p $(PKG_INSTALL_DIR) - $(MAKE) -C $(PKG_BUILD_DIR) \ - DESTDIR="$(PKG_INSTALL_DIR)" \ - all install - touch $@ - -$(IPKG_WIFIDOG): - install -m0755 -d $(IDIR_WIFIDOG)/etc/init.d - install -m0755 ./files/$(PKG_NAME).init $(IDIR_WIFIDOG)/etc/init.d/S65wifidog - install -m0644 ./files/wifidog.conf $(IDIR_WIFIDOG)/etc/ - install -m0644 $(PKG_BUILD_DIR)/wifidog-msg.html $(IDIR_WIFIDOG)/etc/ - install -m0755 -d $(IDIR_WIFIDOG)/usr/bin - install -m0755 -d $(IDIR_WIFIDOG)/usr/lib - install -m0755 $(PKG_BUILD_DIR)/scripts/init.d/wifidog $(IDIR_WIFIDOG)/usr/bin/wifidog-init - $(CP) $(PKG_INSTALL_DIR)/usr/bin/wifidog $(IDIR_WIFIDOG)/usr/bin/ - $(CP) $(PKG_INSTALL_DIR)/usr/bin/wdctl $(IDIR_WIFIDOG)/usr/bin/ - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libhttpd.so* $(IDIR_WIFIDOG)/usr/lib/ - $(RSTRIP) $(IDIR_WIFIDOG) - $(IPKG_BUILD) $(IDIR_WIFIDOG) $(PACKAGE_DIR) -mostlyclean: - make -C $(PKG_BUILD_DIR) clean - rm $(PKG_BUILD_DIR)/.built -all: $(IPKG_WIFIDOG) \ No newline at end of file diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf deleted file mode 100644 index c275b887..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.conf +++ /dev/null @@ -1,246 +0,0 @@ -# $Id: wifidog.conf 1375 2008-09-30 10:20:06Z wichert $ -# WiFiDog Configuration file - -# Parameter: GatewayID -# Default: default -# Optional -# -# Set this to the node ID on the auth server -# This is used to give a customized login page to the clients and for -# monitoring/statistics purpose. If you run multiple gateways on the same -# machine each gateway needs to have a different gateway id. -# If none is supplied, the mac address of the GatewayInterface interface will be used, -# without the : separators - -# GatewayID default - -# Parameter: ExternalInterface -# Default: NONE -# Optional -# -# Set this to the external interface (the one going out to the Inernet or your larger LAN). -# Typically vlan1 for OpenWrt, and eth0 or ppp0 otherwise, -# Normally autodetected - -# ExternalInterface eth0 - -# Parameter: GatewayInterface -# Default: NONE -# Mandatory -# -# Set this to the internal interface (typically your wifi interface). -# Typically br0 for whiterussian, br-lan for kamikaze (by default the wifi interface is bridged with wired lan in openwrt) -# and eth1, wlan0, ath0, etc. otherwise -# You can get this interface with the ifconfig command and finding your wifi interface - -GatewayInterface br0 - -# Parameter: GatewayAddress -# Default: Find it from GatewayInterface -# Optional -# -# Set this to the internal IP address of the gateway. Not normally required. - -# GatewayAddress 192.168.1.1 - -# Parameter: HtmlMessageFile -# Default: wifidog-msg.html -# Optional -# -# This allows you to specify a custome HTML file which will be used for -# system errors by the gateway. Any $title, $message and $node variables -# used inside the file will be replaced. -# -# HtmlMessageFile /opt/wifidog/etc/wifidog-.html - -# Parameter: AuthServer -# Default: NONE -# Mandatory, repeatable -# -# This allows you to configure your auth server(s). Each one will be tried in order, untill one responds. -# Set this to the hostname or IP of your auth server(s), the path where -# WiFiDog-auth resides in and the port it listens on. -#AuthServer { -# Hostname (Mandatory; Default: NONE) -# SSLAvailable (Optional; Default: no; Possible values: yes, no) -# SSLPort (Optional; Default: 443) -# HTTPPort (Optional; Default: 80) -# Path (Optional; Default: /wifidog/ Note: The path must be both prefixed and suffixed by /. Use a single / for server root.) -# LoginScriptPathFragment (Optional; Default: login/? Note: This is the script the user will be sent to for login.) -# PortalScriptPathFragment (Optional; Default: portal/? Note: This is the script the user will be sent to after a successfull login.) -# MsgScriptPathFragment (Optional; Default: gw_message.php? Note: This is the script the user will be sent to upon error to read a readable message.) -# PingScriptPathFragment (Optional; Default: ping/? Note: This is the script the user will be sent to upon error to read a readable message.) -# AuthScriptPathFragment (Optional; Default: auth/? Note: This is the script the user will be sent to upon error to read a readable message.) -#} - -#AuthServer { -# Hostname auth.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -#AuthServer { -# Hostname auth2.ilesansfil.org -# SSLAvailable yes -# Path / -#} - -# Parameter: Daemon -# Default: 1 -# Optional -# -# Set this to true if you want to run as a daemon -# Daemon 1 - -# Parameter: GatewayPort -# Default: 2060 -# Optional -# -# Listen on this port -# GatewayPort 2060 - -# Parameter: ProxyPort -# Default: 0 (disable) -# Optional -# -# Redirect http traffic of knowns & probations users -# to a local transparent proxy listening on ProxyPort port -# ProxyPort 0 - -# Parameter: HTTPDName -# Default: WiFiDog -# Optional -# -# Define what name the HTTPD server will respond -# HTTPDName WiFiDog - -# Parameter: HTTPDMaxConn -# Default: 10 -# Optional -# -# How many sockets to listen to -# HTTPDMaxConn 10 - -# Parameter: HTTPDRealm -# Default: WiFiDog -# Optional -# -# The name of the HTTP authentication realm. This only used when a user -# tries to access a protected WiFiDog internal page. See HTTPUserName. -# HTTPDRealm WiFiDog - -# Parameter: HTTPDUserName / HTTPDPassword -# Default: unset -# Optional -# -# The gateway exposes some information such as the status page through its web -# interface. This information can be protected with a username and password, -# which can be set through the HTTPDUserName and HTTPDPassword parameters. -# HTTPDUserName admin -# HTTPDPassword secret - -# Parameter: CheckInterval -# Default: 60 -# Optional -# -# How many seconds should we wait between timeout checks. This is also -# how often the gateway will ping the auth server and how often it will -# update the traffic counters on the auth server. Setting this too low -# wastes bandwidth, setting this too high will cause the gateway to take -# a long time to switch to it's backup auth server(s). - -# CheckInterval 60 - -# Parameter: ClientTimeout -# Default: 5 -# Optional -# -# Set this to the desired of number of CheckInterval of inactivity before a client is logged out -# The timeout will be INTERVAL * TIMEOUT -ClientTimeout 5 - -# Parameter: TrustedMACList -# Default: none -# Optional -# -# Comma separated list of MAC addresses who are allowed to pass -# through without authentication -#TrustedMACList 00:00:DE:AD:BE:AF,00:00:C0:1D:F0:0D - -# Parameter: FirewallRuleSet -# Default: none -# Mandatory -# -# Groups a number of FirewallRule statements together. - -# Parameter: FirewallRule -# Default: none -# -# Define one firewall rule in a rule set. - -# Rule Set: global -# -# Used for rules to be applied to all other rulesets except locked. -FirewallRuleSet global { - ## To block SMTP out, as it's a tech support nightmare, and a legal liability - #FirewallRule block tcp port 25 - - ## Use the following if you don't want clients to be able to access machines on - ## the private LAN that gives internet access to wifidog. Note that this is not - ## client isolation; The laptops will still be able to talk to one another, as - ## well as to any machine bridged to the wifi of the router. - # FirewallRule block to 192.168.0.0/16 - # FirewallRule block to 172.16.0.0/12 - # FirewallRule block to 10.0.0.0/8 - - ## This is an example ruleset for the Teliphone service. - #FirewallRule allow udp to 69.90.89.192/27 - #FirewallRule allow udp to 69.90.85.0/27 - #FirewallRule allow tcp port 80 to 69.90.89.205 - - ## Use the following to log or ulog the traffic you want to allow or block. - # For OPENWRT: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog (to adapt it to the linux distribution). - # Note: the log or ulog rule must be passed before, the rule you want to match. - # for openwrt: use of these feature requires modules ipt_LOG or ipt_ULOG present in dependencies - # iptables-mod-extra and iptables-mod-ulog - # For example, you want to log (ulog works the same way) the traffic allowed on port 80 to the ip 69.90.89.205: - #FirewallRule log tcp port 80 to 69.90.89.205 - #FirewallRule allow tcp port 80 to 69.90.89.205 - # And you want to know, who matche your block rule: - #FirewallRule log to 0.0.0.0/0 - #FirewallRule block to 0.0.0.0/0 -} - -# Rule Set: validating-users -# -# Used for new users validating their account -FirewallRuleSet validating-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: known-users -# -# Used for normal validated users. -FirewallRuleSet known-users { - FirewallRule allow to 0.0.0.0/0 -} - -# Rule Set: unknown-users -# -# Used for unvalidated users, this is the ruleset that gets redirected. -# -# XXX The redirect code adds the Default DROP clause. -FirewallRuleSet unknown-users { - FirewallRule allow udp port 53 - FirewallRule allow tcp port 53 - FirewallRule allow udp port 67 - FirewallRule allow tcp port 67 -} - -# Rule Set: locked-users -# -# Not currently used -FirewallRuleSet locked-users { - FirewallRule block to 0.0.0.0/0 -} diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init b/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init deleted file mode 100644 index 44a272a6..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/files/wifidog.init +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright (C) 2006 OpenWrt.org -START=50 - -start() { - /usr/bin/wifidog-init start -} - -stop() { - /usr/bin/wifidog-init stop -} - -status() { - /usr/bin/wifidog-init status -} \ No newline at end of file diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles deleted file mode 100644 index aaa3dd14..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/wifidog.conf diff --git a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control b/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control deleted file mode 100644 index dcf25e87..00000000 --- a/contrib/build-openwrt-whiterussianipk/wifidog/ipkg/wifidog.control +++ /dev/null @@ -1,8 +0,0 @@ -Package: wifidog -Priority: optional -Section: net -Depends: libpthread, iptables, iptables-mod-nat, iptables-mod-ipopt -Description: WiFiDog is a complete and embeddable captive portal - solution for wireless community groups or individuals who - wish to open a free Hotspot while still preventing abuse - of their Internet connection. diff --git a/src/firewall.c b/src/firewall.c index c3a68c90..b0a7ba33 100644 --- a/src/firewall.c +++ b/src/firewall.c @@ -266,7 +266,7 @@ fw_sync_with_authserver(void) return; } - /* set a auth flag,added by GaomingPan */ + /* set a auth flag,added by TianyuanpanPan */ set_client_auth_flag(); LOCK_CLIENT_LIST();