This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree".
The branch, next has been updated via 5564841b1055082190e544d0a2e3c611139648f4 (commit) via a3fe88a5400f91219046b368509a8ca368ad7834 (commit) via 9accc1c76e767c4ff725934e72c69ac2974645fe (commit) via 20be628a9746488dcca2272fdfaca278637dea5f (commit) via fe65a459559eabd65db2493d5b3d23d87093e2c3 (commit) via a158a5a62d70a1b1928d62a4ed479b068997b455 (commit) via d44debdcc594b759ac978b820800d659d869d0ac (commit) via 5fd797bfb1ec3c2ac7d722f28b720b26bf7eb249 (commit) via 15b6f6f99a2456d1d10165d01d7cb2d4030a215a (commit) via 41d06f42b78ff9692340413586fde6d18dad3864 (commit) via 5e2daa787666daddb5fb1c5f504acb32f2440919 (commit) via 6edc270abc1699d02f61cf119447208b5b1bcd69 (commit) via f539ff6d5d6cbbe550bb11e3fdaa10cda7c7436a (commit) via dec5269370dfc4a2fe10100f1fa1f1830c2b4cb5 (commit) via 0d6cc79d98e9ae9ff9fbc215112fa985a747538f (commit) via 12b0bd949a4151a8e9e58411d54eb8efd87d00bc (commit) from b587a27e6d0437975da3f2acac69f18d8226b383 (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 5564841b1055082190e544d0a2e3c611139648f4 Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Aug 15 11:58:38 2017 +0100
core113: Add latest packages
Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit a3fe88a5400f91219046b368509a8ca368ad7834 Author: Erik Kapfer erik.kapfer@ipfire.org Date: Thu Aug 10 15:03:31 2017 +0200
iftop: This is an Update release to ver. 1.0pre4
Signed-off-by: Erik Kapfer erik.kapfer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 9accc1c76e767c4ff725934e72c69ac2974645fe Author: Matthias Fischer matthias.fischer@ipfire.org Date: Mon Aug 14 18:30:34 2017 +0200
logrotate: Update to 3.12.3
For details see: https://github.com/logrotate/logrotate/releases
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 20be628a9746488dcca2272fdfaca278637dea5f Author: Matthias Fischer matthias.fischer@ipfire.org Date: Mon Aug 14 18:27:29 2017 +0200
nano: Update to 2.8.6
For details see: https://www.nano-editor.org/news.php
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit fe65a459559eabd65db2493d5b3d23d87093e2c3 Author: Matthias Fischer matthias.fischer@ipfire.org Date: Mon Aug 14 18:22:57 2017 +0200
pcre: Update to 8.41
For details see: http://www.pcre.org/original/changelog.txt
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit a158a5a62d70a1b1928d62a4ed479b068997b455 Author: Matthias Fischer matthias.fischer@ipfire.org Date: Mon Aug 14 18:17:20 2017 +0200
bind: Update to 9.11.2
For details see: https://ftp.isc.org/isc/bind9/9.11.2/RELEASE-NOTES-bind-9.11.2.html
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit d44debdcc594b759ac978b820800d659d869d0ac Author: Matthias Fischer matthias.fischer@ipfire.org Date: Mon Aug 14 18:06:52 2017 +0200
gnutls: Update to 3.5.14
For details see: https://lists.gnupg.org/pipermail/gnutls-devel/2017-May/008427.html https://lists.gnupg.org/pipermail/gnutls-devel/2017-June/008446.html https://lists.gnupg.org/pipermail/gnutls-devel/2017-July/008469.html
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 5fd797bfb1ec3c2ac7d722f28b720b26bf7eb249 Author: Matthias Fischer matthias.fischer@ipfire.org Date: Sun Aug 13 16:03:34 2017 +0200
libgcrypt: Update to 1.8.0
Changes (see: https://gnupg.org/download/release_notes.html):
"gpg: Sending very large keys to the keyservers works again. gpg: Validity strings in key listings are now again translatable. gpg: Emit FAILURE status lines to help GPGME. gpg: Does not anymore link to Libksba to reduce dependencies. gpgsm: Export of secret keys via Assuan is now possible. agent: Raise the maximum passphrase length from 100 to 255 bytes. agent: Fix regression using EdDSA keys with ssh. Does not anymore use a build timestamp by default. The fallback encoding for broken locale settings changed from Latin-1 to UTF-8. Many code cleanups and improved internal documentation. Various minor bug fixes."
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 15b6f6f99a2456d1d10165d01d7cb2d4030a215a Author: Matthias Fischer matthias.fischer@ipfire.org Date: Sun Aug 13 15:56:28 2017 +0200
hostapd: Update to 2.6
For details see: https://w1.fi/cgit/hostap/plain/hostapd/ChangeLog
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 41d06f42b78ff9692340413586fde6d18dad3864 Author: Matthias Fischer matthias.fischer@ipfire.org Date: Sun Aug 13 15:30:01 2017 +0200
unbound: Update to 1.6.4
Hi, ("...back in town...") ;-)
For details see: http://www.unbound.net/download.html
I had to remove the patch file: it wouldn't apply.
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 5e2daa787666daddb5fb1c5f504acb32f2440919 Author: Matthias Fischer matthias.fischer@ipfire.org Date: Sun Aug 13 15:37:29 2017 +0200
tor: Update to 0.3.0.10
Fixes CVE-2017-0377 and others.
For details see: https://gitweb.torproject.org/tor.git/plain/ReleaseNotes?id=tor-0.3.0.10
Best, Matthias
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 6edc270abc1699d02f61cf119447208b5b1bcd69 Author: Matthias Fischer matthias.fischer@ipfire.org Date: Sun Aug 13 15:41:07 2017 +0200
squid 3.5.26: latest patches (14169-14182)
Signed-off-by: Matthias Fischer matthias.fischer@ipfire.org Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit f539ff6d5d6cbbe550bb11e3fdaa10cda7c7436a Author: Stephan Feddersen sfeddersen@ipfire.org Date: Tue Jul 18 21:26:34 2017 +0200
WIO: minor changes
correct typo in wio.en.pl language file add button in wio.cgi to change to systems logs (section wio)
Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit dec5269370dfc4a2fe10100f1fa1f1830c2b4cb5 Author: Stephan Feddersen sfeddersen@ipfire.org Date: Tue Jul 18 20:26:17 2017 +0200
WIO: patch log.dat to show wio logs
Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 0d6cc79d98e9ae9ff9fbc215112fa985a747538f Author: Stephan Feddersen sfeddersen@ipfire.org Date: Fri Jul 14 12:26:55 2017 +0200
WIO: first addon release v1.3.1
Signed-off-by: Michael Tremer michael.tremer@ipfire.org
commit 12b0bd949a4151a8e9e58411d54eb8efd87d00bc Author: Michael Tremer michael.tremer@ipfire.org Date: Tue Aug 15 11:44:50 2017 +0100
Start Core Update 113
Signed-off-by: Michael Tremer michael.tremer@ipfire.org
-----------------------------------------------------------------------
Summary of changes: config/rootfiles/common/gnutls | 2 +- config/rootfiles/common/pcre | 140 +- config/rootfiles/common/unbound | 2 +- config/rootfiles/core/{112 => 113}/exclude | 0 config/rootfiles/core/113/filelists/files | 3 + .../rootfiles/core/{112 => 113}/filelists/gnutls | 0 .../core/{112 => 113}/filelists/libgcrypt | 0 .../{oldcore/111 => core/113}/filelists/logrotate | 0 .../{oldcore/101 => core/113}/filelists/pcre | 0 .../{oldcore/100 => core/113}/filelists/squid | 0 .../rootfiles/core/{112 => 113}/filelists/unbound | 0 config/rootfiles/core/{112 => 113}/meta | 0 config/rootfiles/core/{112 => 113}/update.sh | 7 +- config/rootfiles/{core => oldcore}/112/exclude | 0 .../112/filelists/armv5tel/binutils | 0 .../{core => oldcore}/112/filelists/armv5tel/gcc | 0 .../{core => oldcore}/112/filelists/armv5tel/glibc | 0 .../112/filelists/armv5tel/util-linux | 0 .../{core => oldcore}/112/filelists/autoconf | 0 .../rootfiles/{core => oldcore}/112/filelists/bc | 0 .../{core => oldcore}/112/filelists/boost | 0 .../{core => oldcore}/112/filelists/cmake | 0 .../{core => oldcore}/112/filelists/files | 0 .../rootfiles/{core => oldcore}/112/filelists/flex | 0 .../rootfiles/{core => oldcore}/112/filelists/fuse | 0 .../rootfiles/{core => oldcore}/112/filelists/gawk | 0 .../{core => oldcore}/112/filelists/gnutls | 0 .../{core => oldcore}/112/filelists/i586/binutils | 0 .../{core => oldcore}/112/filelists/i586/gcc | 0 .../{core => oldcore}/112/filelists/i586/glibc | 0 .../{core => oldcore}/112/filelists/i586/python | 0 .../112/filelists/i586/util-linux | 0 .../rootfiles/{core => oldcore}/112/filelists/kbd | 0 .../{core => oldcore}/112/filelists/libarchive | 0 .../{core => oldcore}/112/filelists/libgcrypt | 0 .../{core => oldcore}/112/filelists/libgpg-error | 0 .../{core => oldcore}/112/filelists/libxml2 | 0 .../{core => oldcore}/112/filelists/ncurses | 0 .../{core => oldcore}/112/filelists/reiserfsprogs | 0 .../rootfiles/{core => oldcore}/112/filelists/sudo | 0 .../{core => oldcore}/112/filelists/tzdata | 0 .../{core => oldcore}/112/filelists/unbound | 0 .../112/filelists/web-user-interface | 0 .../112/filelists/x86_64/binutils | 0 .../{core => oldcore}/112/filelists/x86_64/gcc | 0 .../{core => oldcore}/112/filelists/x86_64/glibc | 0 .../{core => oldcore}/112/filelists/x86_64/python | 0 .../112/filelists/x86_64/util-linux | 0 config/rootfiles/{core => oldcore}/112/meta | 0 config/rootfiles/{core => oldcore}/112/update.sh | 0 config/rootfiles/packages/iftop | 2 + config/rootfiles/packages/wio | 45 + html/cgi-bin/logs.cgi/log.dat | 2 + lfs/bind | 4 +- lfs/gnutls | 6 +- lfs/hostapd | 10 +- lfs/{logrotate => iftop} | 23 +- lfs/libgcrypt | 4 +- lfs/logrotate | 4 +- lfs/nano | 6 +- lfs/pcre | 4 +- lfs/squid | 14 + lfs/tor | 6 +- lfs/unbound | 5 +- lfs/wio | 65 + make.sh | 3 +- src/misc-progs/Makefile | 2 +- src/misc-progs/list.h | 129 ++ src/misc-progs/wiohelper.c | 31 + src/misc-progs/wioscan.c | 665 ++++++ .../core/112/update.sh => src/paks/wio/install.sh | 50 +- .../112/update.sh => src/paks/wio/uninstall.sh | 49 +- src/paks/{apcupsd => wio}/update.sh | 0 src/patches/squid/squid-3.5-14169.patch | 881 ++++++++ src/patches/squid/squid-3.5-14170.patch | 85 + src/patches/squid/squid-3.5-14171.patch | 45 + src/patches/squid/squid-3.5-14172.patch | 40 + src/patches/squid/squid-3.5-14173.patch | 254 +++ src/patches/squid/squid-3.5-14174.patch | 274 +++ src/patches/squid/squid-3.5-14175.patch | 34 + src/patches/squid/squid-3.5-14176.patch | 42 + src/patches/squid/squid-3.5-14177.patch | 52 + src/patches/squid/squid-3.5-14178.patch | 36 + src/patches/squid/squid-3.5-14179.patch | 105 + src/patches/squid/squid-3.5-14180.patch | 448 ++++ src/patches/squid/squid-3.5-14181.patch | 30 + src/patches/squid/squid-3.5-14182.patch | 35 + ...ting-validator-permissive-mode-at-runtime.patch | 43 - src/wio/EX-wio.menu | 6 + src/wio/config/backup/includes/wio | 2 + src/wio/images/add.png | Bin 0 -> 300 bytes {html/html => src/wio}/images/back.png | Bin src/wio/images/blue.png | Bin 0 -> 177 bytes src/wio/images/fqdn.png | Bin 0 -> 526 bytes src/wio/images/graph.png | Bin 0 -> 260 bytes src/wio/images/green.png | Bin 0 -> 177 bytes src/wio/images/http.png | Bin 0 -> 349 bytes src/wio/images/https.png | Bin 0 -> 444 bytes src/wio/images/ip.png | Bin 0 -> 326 bytes src/wio/images/mailgreenoff.png | Bin 0 -> 540 bytes src/wio/images/mailgreenon.png | Bin 0 -> 566 bytes src/wio/images/mailredoff.png | Bin 0 -> 534 bytes src/wio/images/mailredon.png | Bin 0 -> 552 bytes src/wio/images/no_graph.png | Bin 0 -> 276 bytes src/wio/images/none.png | Bin 0 -> 297 bytes src/wio/images/orange.png | Bin 0 -> 178 bytes src/wio/images/ovpn.png | Bin 0 -> 178 bytes src/wio/images/ovpnn2n.png | Bin 0 -> 207 bytes src/wio/images/ovpnrw.png | Bin 0 -> 188 bytes src/wio/images/red.png | Bin 0 -> 177 bytes src/wio/images/refresh.png | Bin 0 -> 1751 bytes src/wio/images/vpn.png | Bin 0 -> 178 bytes src/wio/images/vpnn2n.png | Bin 0 -> 207 bytes src/wio/images/vpnrw.png | Bin 0 -> 188 bytes src/wio/images/white.png | Bin 0 -> 214 bytes src/wio/lang/wio.de.pl | 156 ++ src/wio/lang/wio.en.pl | 156 ++ .../includes/lcdproc => src/wio/main/wio.conf | 0 src/wio/main/wio.pl | 385 ++++ src/wio/main/wiovpn.pl | 293 +++ src/wio/wio | 24 + src/wio/wio-graphs.pl | 127 ++ src/wio/wio-lib.pl | 206 ++ src/wio/wio.cgi | 2143 ++++++++++++++++++++ src/wio/wiographs.cgi | 73 + config/backup/includes/lcdproc => src/wio/wioips | 0 126 files changed, 7019 insertions(+), 239 deletions(-) copy config/rootfiles/core/{112 => 113}/exclude (100%) create mode 100644 config/rootfiles/core/113/filelists/files copy config/rootfiles/core/{112 => 113}/filelists/gnutls (100%) copy config/rootfiles/core/{112 => 113}/filelists/libgcrypt (100%) copy config/rootfiles/{oldcore/111 => core/113}/filelists/logrotate (100%) copy config/rootfiles/{oldcore/101 => core/113}/filelists/pcre (100%) copy config/rootfiles/{oldcore/100 => core/113}/filelists/squid (100%) copy config/rootfiles/core/{112 => 113}/filelists/unbound (100%) copy config/rootfiles/core/{112 => 113}/meta (100%) copy config/rootfiles/core/{112 => 113}/update.sh (97%) rename config/rootfiles/{core => oldcore}/112/exclude (100%) rename config/rootfiles/{core => oldcore}/112/filelists/armv5tel/binutils (100%) rename config/rootfiles/{core => oldcore}/112/filelists/armv5tel/gcc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/armv5tel/glibc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/armv5tel/util-linux (100%) rename config/rootfiles/{core => oldcore}/112/filelists/autoconf (100%) rename config/rootfiles/{core => oldcore}/112/filelists/bc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/boost (100%) rename config/rootfiles/{core => oldcore}/112/filelists/cmake (100%) rename config/rootfiles/{core => oldcore}/112/filelists/files (100%) rename config/rootfiles/{core => oldcore}/112/filelists/flex (100%) rename config/rootfiles/{core => oldcore}/112/filelists/fuse (100%) rename config/rootfiles/{core => oldcore}/112/filelists/gawk (100%) rename config/rootfiles/{core => oldcore}/112/filelists/gnutls (100%) rename config/rootfiles/{core => oldcore}/112/filelists/i586/binutils (100%) rename config/rootfiles/{core => oldcore}/112/filelists/i586/gcc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/i586/glibc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/i586/python (100%) rename config/rootfiles/{core => oldcore}/112/filelists/i586/util-linux (100%) rename config/rootfiles/{core => oldcore}/112/filelists/kbd (100%) rename config/rootfiles/{core => oldcore}/112/filelists/libarchive (100%) rename config/rootfiles/{core => oldcore}/112/filelists/libgcrypt (100%) rename config/rootfiles/{core => oldcore}/112/filelists/libgpg-error (100%) rename config/rootfiles/{core => oldcore}/112/filelists/libxml2 (100%) rename config/rootfiles/{core => oldcore}/112/filelists/ncurses (100%) rename config/rootfiles/{core => oldcore}/112/filelists/reiserfsprogs (100%) rename config/rootfiles/{core => oldcore}/112/filelists/sudo (100%) rename config/rootfiles/{core => oldcore}/112/filelists/tzdata (100%) rename config/rootfiles/{core => oldcore}/112/filelists/unbound (100%) rename config/rootfiles/{core => oldcore}/112/filelists/web-user-interface (100%) rename config/rootfiles/{core => oldcore}/112/filelists/x86_64/binutils (100%) rename config/rootfiles/{core => oldcore}/112/filelists/x86_64/gcc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/x86_64/glibc (100%) rename config/rootfiles/{core => oldcore}/112/filelists/x86_64/python (100%) rename config/rootfiles/{core => oldcore}/112/filelists/x86_64/util-linux (100%) rename config/rootfiles/{core => oldcore}/112/meta (100%) copy config/rootfiles/{core => oldcore}/112/update.sh (100%) create mode 100644 config/rootfiles/packages/iftop create mode 100644 config/rootfiles/packages/wio copy lfs/{logrotate => iftop} (90%) create mode 100644 lfs/wio create mode 100644 src/misc-progs/list.h create mode 100644 src/misc-progs/wiohelper.c create mode 100644 src/misc-progs/wioscan.c copy config/rootfiles/core/112/update.sh => src/paks/wio/install.sh (66%) rename config/rootfiles/core/112/update.sh => src/paks/wio/uninstall.sh (65%) copy src/paks/{apcupsd => wio}/update.sh (100%) create mode 100644 src/patches/squid/squid-3.5-14169.patch create mode 100644 src/patches/squid/squid-3.5-14170.patch create mode 100644 src/patches/squid/squid-3.5-14171.patch create mode 100644 src/patches/squid/squid-3.5-14172.patch create mode 100644 src/patches/squid/squid-3.5-14173.patch create mode 100644 src/patches/squid/squid-3.5-14174.patch create mode 100644 src/patches/squid/squid-3.5-14175.patch create mode 100644 src/patches/squid/squid-3.5-14176.patch create mode 100644 src/patches/squid/squid-3.5-14177.patch create mode 100644 src/patches/squid/squid-3.5-14178.patch create mode 100644 src/patches/squid/squid-3.5-14179.patch create mode 100644 src/patches/squid/squid-3.5-14180.patch create mode 100644 src/patches/squid/squid-3.5-14181.patch create mode 100644 src/patches/squid/squid-3.5-14182.patch delete mode 100644 src/patches/unbound-allow-setting-validator-permissive-mode-at-runtime.patch create mode 100644 src/wio/EX-wio.menu create mode 100644 src/wio/config/backup/includes/wio create mode 100644 src/wio/images/add.png copy {html/html => src/wio}/images/back.png (100%) create mode 100644 src/wio/images/blue.png create mode 100644 src/wio/images/fqdn.png create mode 100644 src/wio/images/graph.png create mode 100644 src/wio/images/green.png create mode 100644 src/wio/images/http.png create mode 100644 src/wio/images/https.png create mode 100644 src/wio/images/ip.png create mode 100644 src/wio/images/mailgreenoff.png create mode 100644 src/wio/images/mailgreenon.png create mode 100644 src/wio/images/mailredoff.png create mode 100644 src/wio/images/mailredon.png create mode 100644 src/wio/images/no_graph.png create mode 100644 src/wio/images/none.png create mode 100644 src/wio/images/orange.png create mode 100644 src/wio/images/ovpn.png create mode 100644 src/wio/images/ovpnn2n.png create mode 100644 src/wio/images/ovpnrw.png create mode 100644 src/wio/images/red.png create mode 100644 src/wio/images/refresh.png create mode 100644 src/wio/images/vpn.png create mode 100644 src/wio/images/vpnn2n.png create mode 100644 src/wio/images/vpnrw.png create mode 100644 src/wio/images/white.png create mode 100644 src/wio/lang/wio.de.pl create mode 100644 src/wio/lang/wio.en.pl copy config/backup/includes/lcdproc => src/wio/main/wio.conf (100%) create mode 100644 src/wio/main/wio.pl create mode 100644 src/wio/main/wiovpn.pl create mode 100644 src/wio/wio create mode 100644 src/wio/wio-graphs.pl create mode 100644 src/wio/wio-lib.pl create mode 100644 src/wio/wio.cgi create mode 100644 src/wio/wiographs.cgi copy config/backup/includes/lcdproc => src/wio/wioips (100%)
Difference in files: diff --git a/config/rootfiles/common/gnutls b/config/rootfiles/common/gnutls index 009289b..13d97c6 100644 --- a/config/rootfiles/common/gnutls +++ b/config/rootfiles/common/gnutls @@ -33,7 +33,7 @@ usr/lib/libgnutls-dane.so.0.4.1 #usr/lib/libgnutls.la #usr/lib/libgnutls.so usr/lib/libgnutls.so.30 -usr/lib/libgnutls.so.30.14.2 +usr/lib/libgnutls.so.30.14.6 #usr/lib/libgnutlsxx.la #usr/lib/libgnutlsxx.so usr/lib/libgnutlsxx.so.28 diff --git a/config/rootfiles/common/pcre b/config/rootfiles/common/pcre index c551c0d..2493447 100644 --- a/config/rootfiles/common/pcre +++ b/config/rootfiles/common/pcre @@ -10,15 +10,15 @@ #usr/lib/libpcre.la usr/lib/libpcre.so usr/lib/libpcre.so.1 -usr/lib/libpcre.so.1.2.8 +usr/lib/libpcre.so.1.2.9 #usr/lib/libpcre16.la usr/lib/libpcre16.so usr/lib/libpcre16.so.0 -usr/lib/libpcre16.so.0.2.8 +usr/lib/libpcre16.so.0.2.9 #usr/lib/libpcre32.la usr/lib/libpcre32.so usr/lib/libpcre32.so.0 -usr/lib/libpcre32.so.0.0.8 +usr/lib/libpcre32.so.0.0.9 #usr/lib/libpcrecpp.la usr/lib/libpcrecpp.so usr/lib/libpcrecpp.so.0 @@ -26,78 +26,78 @@ usr/lib/libpcrecpp.so.0.0.1 #usr/lib/libpcreposix.la usr/lib/libpcreposix.so usr/lib/libpcreposix.so.0 -usr/lib/libpcreposix.so.0.0.4 +usr/lib/libpcreposix.so.0.0.5 #usr/lib/pkgconfig/libpcre.pc #usr/lib/pkgconfig/libpcre16.pc #usr/lib/pkgconfig/libpcre32.pc #usr/lib/pkgconfig/libpcrecpp.pc #usr/lib/pkgconfig/libpcreposix.pc -#usr/share/doc/pcre-pcre-8.40 -#usr/share/doc/pcre-pcre-8.40/AUTHORS -#usr/share/doc/pcre-pcre-8.40/COPYING -#usr/share/doc/pcre-pcre-8.40/ChangeLog -#usr/share/doc/pcre-pcre-8.40/LICENCE -#usr/share/doc/pcre-pcre-8.40/NEWS -#usr/share/doc/pcre-pcre-8.40/README -#usr/share/doc/pcre-pcre-8.40/html -#usr/share/doc/pcre-pcre-8.40/html/NON-AUTOTOOLS-BUILD.txt -#usr/share/doc/pcre-pcre-8.40/html/README.txt -#usr/share/doc/pcre-pcre-8.40/html/index.html -#usr/share/doc/pcre-pcre-8.40/html/pcre-config.html -#usr/share/doc/pcre-pcre-8.40/html/pcre.html -#usr/share/doc/pcre-pcre-8.40/html/pcre16.html -#usr/share/doc/pcre-pcre-8.40/html/pcre32.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_assign_jit_stack.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_compile.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_compile2.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_config.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_copy_named_substring.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_copy_substring.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_dfa_exec.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_exec.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_free_study.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_free_substring.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_free_substring_list.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_fullinfo.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_get_named_substring.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_get_stringnumber.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_get_stringtable_entries.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_get_substring.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_get_substring_list.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_jit_exec.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_jit_stack_alloc.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_jit_stack_free.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_maketables.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_pattern_to_host_byte_order.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_refcount.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_study.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_utf16_to_host_byte_order.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_utf32_to_host_byte_order.html -#usr/share/doc/pcre-pcre-8.40/html/pcre_version.html -#usr/share/doc/pcre-pcre-8.40/html/pcreapi.html -#usr/share/doc/pcre-pcre-8.40/html/pcrebuild.html -#usr/share/doc/pcre-pcre-8.40/html/pcrecallout.html -#usr/share/doc/pcre-pcre-8.40/html/pcrecompat.html -#usr/share/doc/pcre-pcre-8.40/html/pcrecpp.html -#usr/share/doc/pcre-pcre-8.40/html/pcredemo.html -#usr/share/doc/pcre-pcre-8.40/html/pcregrep.html -#usr/share/doc/pcre-pcre-8.40/html/pcrejit.html -#usr/share/doc/pcre-pcre-8.40/html/pcrelimits.html -#usr/share/doc/pcre-pcre-8.40/html/pcrematching.html -#usr/share/doc/pcre-pcre-8.40/html/pcrepartial.html -#usr/share/doc/pcre-pcre-8.40/html/pcrepattern.html -#usr/share/doc/pcre-pcre-8.40/html/pcreperform.html -#usr/share/doc/pcre-pcre-8.40/html/pcreposix.html -#usr/share/doc/pcre-pcre-8.40/html/pcreprecompile.html -#usr/share/doc/pcre-pcre-8.40/html/pcresample.html -#usr/share/doc/pcre-pcre-8.40/html/pcrestack.html -#usr/share/doc/pcre-pcre-8.40/html/pcresyntax.html -#usr/share/doc/pcre-pcre-8.40/html/pcretest.html -#usr/share/doc/pcre-pcre-8.40/html/pcreunicode.html -#usr/share/doc/pcre-pcre-8.40/pcre-config.txt -#usr/share/doc/pcre-pcre-8.40/pcre.txt -#usr/share/doc/pcre-pcre-8.40/pcregrep.txt -#usr/share/doc/pcre-pcre-8.40/pcretest.txt +#usr/share/doc/pcre-pcre-8.41 +#usr/share/doc/pcre-pcre-8.41/AUTHORS +#usr/share/doc/pcre-pcre-8.41/COPYING +#usr/share/doc/pcre-pcre-8.41/ChangeLog +#usr/share/doc/pcre-pcre-8.41/LICENCE +#usr/share/doc/pcre-pcre-8.41/NEWS +#usr/share/doc/pcre-pcre-8.41/README +#usr/share/doc/pcre-pcre-8.41/html +#usr/share/doc/pcre-pcre-8.41/html/NON-AUTOTOOLS-BUILD.txt +#usr/share/doc/pcre-pcre-8.41/html/README.txt +#usr/share/doc/pcre-pcre-8.41/html/index.html +#usr/share/doc/pcre-pcre-8.41/html/pcre-config.html +#usr/share/doc/pcre-pcre-8.41/html/pcre.html +#usr/share/doc/pcre-pcre-8.41/html/pcre16.html +#usr/share/doc/pcre-pcre-8.41/html/pcre32.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_assign_jit_stack.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_compile.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_compile2.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_config.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_copy_named_substring.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_copy_substring.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_dfa_exec.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_exec.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_free_study.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_free_substring.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_free_substring_list.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_fullinfo.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_get_named_substring.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_get_stringnumber.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_get_stringtable_entries.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_get_substring.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_get_substring_list.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_jit_exec.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_jit_stack_alloc.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_jit_stack_free.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_maketables.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_pattern_to_host_byte_order.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_refcount.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_study.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_utf16_to_host_byte_order.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_utf32_to_host_byte_order.html +#usr/share/doc/pcre-pcre-8.41/html/pcre_version.html +#usr/share/doc/pcre-pcre-8.41/html/pcreapi.html +#usr/share/doc/pcre-pcre-8.41/html/pcrebuild.html +#usr/share/doc/pcre-pcre-8.41/html/pcrecallout.html +#usr/share/doc/pcre-pcre-8.41/html/pcrecompat.html +#usr/share/doc/pcre-pcre-8.41/html/pcrecpp.html +#usr/share/doc/pcre-pcre-8.41/html/pcredemo.html +#usr/share/doc/pcre-pcre-8.41/html/pcregrep.html +#usr/share/doc/pcre-pcre-8.41/html/pcrejit.html +#usr/share/doc/pcre-pcre-8.41/html/pcrelimits.html +#usr/share/doc/pcre-pcre-8.41/html/pcrematching.html +#usr/share/doc/pcre-pcre-8.41/html/pcrepartial.html +#usr/share/doc/pcre-pcre-8.41/html/pcrepattern.html +#usr/share/doc/pcre-pcre-8.41/html/pcreperform.html +#usr/share/doc/pcre-pcre-8.41/html/pcreposix.html +#usr/share/doc/pcre-pcre-8.41/html/pcreprecompile.html +#usr/share/doc/pcre-pcre-8.41/html/pcresample.html +#usr/share/doc/pcre-pcre-8.41/html/pcrestack.html +#usr/share/doc/pcre-pcre-8.41/html/pcresyntax.html +#usr/share/doc/pcre-pcre-8.41/html/pcretest.html +#usr/share/doc/pcre-pcre-8.41/html/pcreunicode.html +#usr/share/doc/pcre-pcre-8.41/pcre-config.txt +#usr/share/doc/pcre-pcre-8.41/pcre.txt +#usr/share/doc/pcre-pcre-8.41/pcregrep.txt +#usr/share/doc/pcre-pcre-8.41/pcretest.txt #usr/share/man/man1/pcre-config.1 #usr/share/man/man1/pcregrep.1 #usr/share/man/man1/pcretest.1 diff --git a/config/rootfiles/common/unbound b/config/rootfiles/common/unbound index ee4b7fd..5d33140 100644 --- a/config/rootfiles/common/unbound +++ b/config/rootfiles/common/unbound @@ -11,7 +11,7 @@ etc/unbound/unbound.conf #usr/lib/libunbound.la #usr/lib/libunbound.so usr/lib/libunbound.so.2 -usr/lib/libunbound.so.2.5.2 +usr/lib/libunbound.so.2.5.3 usr/sbin/unbound usr/sbin/unbound-anchor usr/sbin/unbound-checkconf diff --git a/config/rootfiles/core/112/exclude b/config/rootfiles/core/113/exclude similarity index 100% rename from config/rootfiles/core/112/exclude rename to config/rootfiles/core/113/exclude diff --git a/config/rootfiles/core/113/filelists/files b/config/rootfiles/core/113/filelists/files new file mode 100644 index 0000000..168c7d1 --- /dev/null +++ b/config/rootfiles/core/113/filelists/files @@ -0,0 +1,3 @@ +etc/system-release +etc/issue +var/ipfire/langs diff --git a/config/rootfiles/core/112/filelists/gnutls b/config/rootfiles/core/113/filelists/gnutls similarity index 100% rename from config/rootfiles/core/112/filelists/gnutls rename to config/rootfiles/core/113/filelists/gnutls diff --git a/config/rootfiles/core/112/filelists/libgcrypt b/config/rootfiles/core/113/filelists/libgcrypt similarity index 100% rename from config/rootfiles/core/112/filelists/libgcrypt rename to config/rootfiles/core/113/filelists/libgcrypt diff --git a/config/rootfiles/core/113/filelists/logrotate b/config/rootfiles/core/113/filelists/logrotate new file mode 120000 index 0000000..bc192c0 --- /dev/null +++ b/config/rootfiles/core/113/filelists/logrotate @@ -0,0 +1 @@ +../../../common/logrotate \ No newline at end of file diff --git a/config/rootfiles/core/113/filelists/pcre b/config/rootfiles/core/113/filelists/pcre new file mode 120000 index 0000000..b390d9a --- /dev/null +++ b/config/rootfiles/core/113/filelists/pcre @@ -0,0 +1 @@ +../../../common/pcre \ No newline at end of file diff --git a/config/rootfiles/core/113/filelists/squid b/config/rootfiles/core/113/filelists/squid new file mode 120000 index 0000000..2dc8372 --- /dev/null +++ b/config/rootfiles/core/113/filelists/squid @@ -0,0 +1 @@ +../../../common/squid \ No newline at end of file diff --git a/config/rootfiles/core/112/filelists/unbound b/config/rootfiles/core/113/filelists/unbound similarity index 100% rename from config/rootfiles/core/112/filelists/unbound rename to config/rootfiles/core/113/filelists/unbound diff --git a/config/rootfiles/core/112/meta b/config/rootfiles/core/113/meta similarity index 100% rename from config/rootfiles/core/112/meta rename to config/rootfiles/core/113/meta diff --git a/config/rootfiles/core/113/update.sh b/config/rootfiles/core/113/update.sh new file mode 100644 index 0000000..0b993a4 --- /dev/null +++ b/config/rootfiles/core/113/update.sh @@ -0,0 +1,66 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 3 of the License, or # +# (at your option) any later version. # +# # +# IPFire 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2017 IPFire-Team info@ipfire.org. # +# # +############################################################################ +# +. /opt/pakfire/lib/functions.sh +/usr/local/bin/backupctrl exclude >/dev/null 2>&1 + +core=113 + +# Remove old core updates from pakfire cache to save space... +for (( i=1; i<=$core; i++ )); do + rm -f /var/cache/pakfire/core-upgrade-*-$i.ipfire +done + +# Stop services +/etc/init.d/squid stop +/etc/init.d/unbound stop + +# Extract files +extract_files + +# update linker config +ldconfig + +# Update Language cache +/usr/local/bin/update-lang-cache + +# Start services +/etc/init.d/unbound start +/etc/init.d/squid start + +# This update need a reboot... +touch /var/run/need_reboot + +# Finish +/etc/init.d/fireinfo start +sendprofile + +# Update grub config to display new core version +if [ -e /boot/grub/grub.cfg ]; then + grub-mkconfig -o /boot/grub/grub.cfg +fi + +sync + +# Don't report the exitcode last command +exit 0 diff --git a/config/rootfiles/oldcore/112/exclude b/config/rootfiles/oldcore/112/exclude new file mode 100644 index 0000000..d6fd053 --- /dev/null +++ b/config/rootfiles/oldcore/112/exclude @@ -0,0 +1,30 @@ +boot/config.txt +boot/grub/grub.cfg +boot/grub/grubenv +etc/alternatives +etc/collectd.custom +etc/default/grub +etc/ipsec.conf +etc/ipsec.secrets +etc/ipsec.user.conf +etc/ipsec.user.secrets +etc/localtime +etc/shadow +etc/snort/snort.conf +etc/ssh/ssh_config +etc/ssh/sshd_config +etc/ssl/openssl.cnf +etc/sudoers +etc/sysconfig/firewall.local +etc/sysconfig/rc.local +etc/udev/rules.d/30-persistent-network.rules +srv/web/ipfire/html/proxy.pac +var/ipfire/dma +var/ipfire/time +var/ipfire/ovpn +var/lib/alternatives +var/log/cache +var/log/dhcpcd.log +var/log/messages +var/state/dhcp/dhcpd.leases +var/updatecache diff --git a/config/rootfiles/core/112/filelists/armv5tel/binutils b/config/rootfiles/oldcore/112/filelists/armv5tel/binutils similarity index 100% rename from config/rootfiles/core/112/filelists/armv5tel/binutils rename to config/rootfiles/oldcore/112/filelists/armv5tel/binutils diff --git a/config/rootfiles/core/112/filelists/armv5tel/gcc b/config/rootfiles/oldcore/112/filelists/armv5tel/gcc similarity index 100% rename from config/rootfiles/core/112/filelists/armv5tel/gcc rename to config/rootfiles/oldcore/112/filelists/armv5tel/gcc diff --git a/config/rootfiles/core/112/filelists/armv5tel/glibc b/config/rootfiles/oldcore/112/filelists/armv5tel/glibc similarity index 100% rename from config/rootfiles/core/112/filelists/armv5tel/glibc rename to config/rootfiles/oldcore/112/filelists/armv5tel/glibc diff --git a/config/rootfiles/core/112/filelists/armv5tel/util-linux b/config/rootfiles/oldcore/112/filelists/armv5tel/util-linux similarity index 100% rename from config/rootfiles/core/112/filelists/armv5tel/util-linux rename to config/rootfiles/oldcore/112/filelists/armv5tel/util-linux diff --git a/config/rootfiles/core/112/filelists/autoconf b/config/rootfiles/oldcore/112/filelists/autoconf similarity index 100% rename from config/rootfiles/core/112/filelists/autoconf rename to config/rootfiles/oldcore/112/filelists/autoconf diff --git a/config/rootfiles/core/112/filelists/bc b/config/rootfiles/oldcore/112/filelists/bc similarity index 100% rename from config/rootfiles/core/112/filelists/bc rename to config/rootfiles/oldcore/112/filelists/bc diff --git a/config/rootfiles/core/112/filelists/boost b/config/rootfiles/oldcore/112/filelists/boost similarity index 100% rename from config/rootfiles/core/112/filelists/boost rename to config/rootfiles/oldcore/112/filelists/boost diff --git a/config/rootfiles/core/112/filelists/cmake b/config/rootfiles/oldcore/112/filelists/cmake similarity index 100% rename from config/rootfiles/core/112/filelists/cmake rename to config/rootfiles/oldcore/112/filelists/cmake diff --git a/config/rootfiles/core/112/filelists/files b/config/rootfiles/oldcore/112/filelists/files similarity index 100% rename from config/rootfiles/core/112/filelists/files rename to config/rootfiles/oldcore/112/filelists/files diff --git a/config/rootfiles/core/112/filelists/flex b/config/rootfiles/oldcore/112/filelists/flex similarity index 100% rename from config/rootfiles/core/112/filelists/flex rename to config/rootfiles/oldcore/112/filelists/flex diff --git a/config/rootfiles/core/112/filelists/fuse b/config/rootfiles/oldcore/112/filelists/fuse similarity index 100% rename from config/rootfiles/core/112/filelists/fuse rename to config/rootfiles/oldcore/112/filelists/fuse diff --git a/config/rootfiles/core/112/filelists/gawk b/config/rootfiles/oldcore/112/filelists/gawk similarity index 100% rename from config/rootfiles/core/112/filelists/gawk rename to config/rootfiles/oldcore/112/filelists/gawk diff --git a/config/rootfiles/oldcore/112/filelists/gnutls b/config/rootfiles/oldcore/112/filelists/gnutls new file mode 120000 index 0000000..8dbe60b --- /dev/null +++ b/config/rootfiles/oldcore/112/filelists/gnutls @@ -0,0 +1 @@ +../../../common/gnutls \ No newline at end of file diff --git a/config/rootfiles/core/112/filelists/i586/binutils b/config/rootfiles/oldcore/112/filelists/i586/binutils similarity index 100% rename from config/rootfiles/core/112/filelists/i586/binutils rename to config/rootfiles/oldcore/112/filelists/i586/binutils diff --git a/config/rootfiles/core/112/filelists/i586/gcc b/config/rootfiles/oldcore/112/filelists/i586/gcc similarity index 100% rename from config/rootfiles/core/112/filelists/i586/gcc rename to config/rootfiles/oldcore/112/filelists/i586/gcc diff --git a/config/rootfiles/core/112/filelists/i586/glibc b/config/rootfiles/oldcore/112/filelists/i586/glibc similarity index 100% rename from config/rootfiles/core/112/filelists/i586/glibc rename to config/rootfiles/oldcore/112/filelists/i586/glibc diff --git a/config/rootfiles/core/112/filelists/i586/python b/config/rootfiles/oldcore/112/filelists/i586/python similarity index 100% rename from config/rootfiles/core/112/filelists/i586/python rename to config/rootfiles/oldcore/112/filelists/i586/python diff --git a/config/rootfiles/core/112/filelists/i586/util-linux b/config/rootfiles/oldcore/112/filelists/i586/util-linux similarity index 100% rename from config/rootfiles/core/112/filelists/i586/util-linux rename to config/rootfiles/oldcore/112/filelists/i586/util-linux diff --git a/config/rootfiles/core/112/filelists/kbd b/config/rootfiles/oldcore/112/filelists/kbd similarity index 100% rename from config/rootfiles/core/112/filelists/kbd rename to config/rootfiles/oldcore/112/filelists/kbd diff --git a/config/rootfiles/core/112/filelists/libarchive b/config/rootfiles/oldcore/112/filelists/libarchive similarity index 100% rename from config/rootfiles/core/112/filelists/libarchive rename to config/rootfiles/oldcore/112/filelists/libarchive diff --git a/config/rootfiles/oldcore/112/filelists/libgcrypt b/config/rootfiles/oldcore/112/filelists/libgcrypt new file mode 120000 index 0000000..2df12a2 --- /dev/null +++ b/config/rootfiles/oldcore/112/filelists/libgcrypt @@ -0,0 +1 @@ +../../../common/libgcrypt \ No newline at end of file diff --git a/config/rootfiles/core/112/filelists/libgpg-error b/config/rootfiles/oldcore/112/filelists/libgpg-error similarity index 100% rename from config/rootfiles/core/112/filelists/libgpg-error rename to config/rootfiles/oldcore/112/filelists/libgpg-error diff --git a/config/rootfiles/core/112/filelists/libxml2 b/config/rootfiles/oldcore/112/filelists/libxml2 similarity index 100% rename from config/rootfiles/core/112/filelists/libxml2 rename to config/rootfiles/oldcore/112/filelists/libxml2 diff --git a/config/rootfiles/core/112/filelists/ncurses b/config/rootfiles/oldcore/112/filelists/ncurses similarity index 100% rename from config/rootfiles/core/112/filelists/ncurses rename to config/rootfiles/oldcore/112/filelists/ncurses diff --git a/config/rootfiles/core/112/filelists/reiserfsprogs b/config/rootfiles/oldcore/112/filelists/reiserfsprogs similarity index 100% rename from config/rootfiles/core/112/filelists/reiserfsprogs rename to config/rootfiles/oldcore/112/filelists/reiserfsprogs diff --git a/config/rootfiles/core/112/filelists/sudo b/config/rootfiles/oldcore/112/filelists/sudo similarity index 100% rename from config/rootfiles/core/112/filelists/sudo rename to config/rootfiles/oldcore/112/filelists/sudo diff --git a/config/rootfiles/core/112/filelists/tzdata b/config/rootfiles/oldcore/112/filelists/tzdata similarity index 100% rename from config/rootfiles/core/112/filelists/tzdata rename to config/rootfiles/oldcore/112/filelists/tzdata diff --git a/config/rootfiles/oldcore/112/filelists/unbound b/config/rootfiles/oldcore/112/filelists/unbound new file mode 120000 index 0000000..66adf09 --- /dev/null +++ b/config/rootfiles/oldcore/112/filelists/unbound @@ -0,0 +1 @@ +../../../common/unbound \ No newline at end of file diff --git a/config/rootfiles/core/112/filelists/web-user-interface b/config/rootfiles/oldcore/112/filelists/web-user-interface similarity index 100% rename from config/rootfiles/core/112/filelists/web-user-interface rename to config/rootfiles/oldcore/112/filelists/web-user-interface diff --git a/config/rootfiles/core/112/filelists/x86_64/binutils b/config/rootfiles/oldcore/112/filelists/x86_64/binutils similarity index 100% rename from config/rootfiles/core/112/filelists/x86_64/binutils rename to config/rootfiles/oldcore/112/filelists/x86_64/binutils diff --git a/config/rootfiles/core/112/filelists/x86_64/gcc b/config/rootfiles/oldcore/112/filelists/x86_64/gcc similarity index 100% rename from config/rootfiles/core/112/filelists/x86_64/gcc rename to config/rootfiles/oldcore/112/filelists/x86_64/gcc diff --git a/config/rootfiles/core/112/filelists/x86_64/glibc b/config/rootfiles/oldcore/112/filelists/x86_64/glibc similarity index 100% rename from config/rootfiles/core/112/filelists/x86_64/glibc rename to config/rootfiles/oldcore/112/filelists/x86_64/glibc diff --git a/config/rootfiles/core/112/filelists/x86_64/python b/config/rootfiles/oldcore/112/filelists/x86_64/python similarity index 100% rename from config/rootfiles/core/112/filelists/x86_64/python rename to config/rootfiles/oldcore/112/filelists/x86_64/python diff --git a/config/rootfiles/core/112/filelists/x86_64/util-linux b/config/rootfiles/oldcore/112/filelists/x86_64/util-linux similarity index 100% rename from config/rootfiles/core/112/filelists/x86_64/util-linux rename to config/rootfiles/oldcore/112/filelists/x86_64/util-linux diff --git a/config/rootfiles/oldcore/112/meta b/config/rootfiles/oldcore/112/meta new file mode 100644 index 0000000..d547fa8 --- /dev/null +++ b/config/rootfiles/oldcore/112/meta @@ -0,0 +1 @@ +DEPS="" diff --git a/config/rootfiles/core/112/update.sh b/config/rootfiles/oldcore/112/update.sh similarity index 100% rename from config/rootfiles/core/112/update.sh rename to config/rootfiles/oldcore/112/update.sh diff --git a/config/rootfiles/packages/iftop b/config/rootfiles/packages/iftop new file mode 100644 index 0000000..aaa4d9d --- /dev/null +++ b/config/rootfiles/packages/iftop @@ -0,0 +1,2 @@ +usr/sbin/iftop +#usr/share/man/man8/iftop.8 diff --git a/config/rootfiles/packages/wio b/config/rootfiles/packages/wio new file mode 100644 index 0000000..f238662 --- /dev/null +++ b/config/rootfiles/packages/wio @@ -0,0 +1,45 @@ +srv/web/ipfire/cgi-bin/wio.cgi +srv/web/ipfire/cgi-bin/wiographs.cgi +etc/fcron.minutely/wio +var/ipfire/wio +var/ipfire/wio/wio.conf +var/ipfire/wio/wio.pl +var/ipfire/wio/wiovpn.pl +usr/lib/wio +usr/lib/wio/wio-lib.pl +usr/lib/wio/wio-graphs.pl +usr/local/bin/wiohelper +usr/local/bin/wioscan +var/log/wio +var/log/wio/wioips +var/log/rrd/wio +var/ipfire/addon-lang/wio.de.pl +var/ipfire/addon-lang/wio.en.pl +var/ipfire/menu.d/EX-wio.menu +srv/web/ipfire/html/images/wio +srv/web/ipfire/html/images/wio/add.png +srv/web/ipfire/html/images/wio/back.png +srv/web/ipfire/html/images/wio/blue.png +srv/web/ipfire/html/images/wio/fqdn.png +srv/web/ipfire/html/images/wio/graph.png +srv/web/ipfire/html/images/wio/green.png +srv/web/ipfire/html/images/wio/http.png +srv/web/ipfire/html/images/wio/https.png +srv/web/ipfire/html/images/wio/ip.png +srv/web/ipfire/html/images/wio/mailgreenoff.png +srv/web/ipfire/html/images/wio/mailgreenon.png +srv/web/ipfire/html/images/wio/mailredoff.png +srv/web/ipfire/html/images/wio/mailredon.png +srv/web/ipfire/html/images/wio/no_graph.png +srv/web/ipfire/html/images/wio/none.png +srv/web/ipfire/html/images/wio/orange.png +srv/web/ipfire/html/images/wio/ovpn.png +srv/web/ipfire/html/images/wio/ovpnn2n.png +srv/web/ipfire/html/images/wio/ovpnrw.png +srv/web/ipfire/html/images/wio/red.png +srv/web/ipfire/html/images/wio/refresh.png +srv/web/ipfire/html/images/wio/vpnn2n.png +srv/web/ipfire/html/images/wio/vpn.png +srv/web/ipfire/html/images/wio/vpnrw.png +srv/web/ipfire/html/images/wio/white.png +var/ipfire/backup/addons/includes/wio diff --git a/html/cgi-bin/logs.cgi/log.dat b/html/cgi-bin/logs.cgi/log.dat index 3597799..5734fed 100644 --- a/html/cgi-bin/logs.cgi/log.dat +++ b/html/cgi-bin/logs.cgi/log.dat @@ -50,6 +50,7 @@ $cgiparams{'SECTION'} = 'ipfire';
my %sections = ( 'auth' => '(\w+(pam_unix)[.*]: )', + 'wio' => '(wio|wio[.*])', 'clamav' => '(clamd[.*]: |freshclam[.*]: )', 'collectd' => '(collectd[.*]: )', 'cron' => '(fcron[.*]: )', @@ -75,6 +76,7 @@ my %sections = ( # Translations for the %sections array. my %trsections = ( 'auth' => "$Lang::tr{'loginlogout'}", + 'wio' => 'Who Is Online?', 'clamav' => 'ClamAV', 'collectd' => 'Collectd', 'cron' => 'Cron', diff --git a/lfs/bind b/lfs/bind index 1269e41..2ad1ebd 100644 --- a/lfs/bind +++ b/lfs/bind @@ -25,7 +25,7 @@
include Config
-VER = 9.11.1 +VER = 9.11.2
THISAPP = bind-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -43,7 +43,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = c384ab071d902bac13487c1268e5a32f +$(DL_FILE)_MD5 = efca7e5a63a07efba264da9be2fbb57f
install : $(TARGET)
diff --git a/lfs/gnutls b/lfs/gnutls index 1a6fadf..86e7fb2 100644 --- a/lfs/gnutls +++ b/lfs/gnutls @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2016 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2017 IPFire Team info@ipfire.org # # # # 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 # @@ -24,7 +24,7 @@
include Config
-VER = 3.5.11 +VER = 3.5.14
THISAPP = gnutls-$(VER) DL_FILE = $(THISAPP).tar.xz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = a3ff8cf5ca7522e3ba14f487e6326e11 +$(DL_FILE)_MD5 = 1e84b57a472b5f3b01f2c1b7a3a2bcbe
install : $(TARGET)
diff --git a/lfs/hostapd b/lfs/hostapd index 1a2436c..d94c0e7 100644 --- a/lfs/hostapd +++ b/lfs/hostapd @@ -1,7 +1,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2016 IPFire Team info@ipfire.org # +# Copyright (C) 2007-2017 IPFire Team info@ipfire.org # # # # 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 # @@ -24,7 +24,7 @@
include Config
-VER = 2.5 +VER = 2.6
THISAPP = hostapd-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = hostapd -PAK_VER = 37 +PAK_VER = 38
DEPS = ""
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 69f9cec3f76d74f402864a43e4f8624f +$(DL_FILE)_MD5 = eaa56dce9bd8f1d195eb62596eab34c7
install : $(TARGET)
@@ -54,7 +54,7 @@ download :$(patsubst %,$(DIR_DL)/%,$(objects))
md5 : $(subst %,%_MD5,$(objects))
-dist: +dist: @$(PAK)
############################################################################### diff --git a/lfs/iftop b/lfs/iftop new file mode 100644 index 0000000..4353b40 --- /dev/null +++ b/lfs/iftop @@ -0,0 +1,87 @@ +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 IPFire Team info@ipfire.org # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VER = 1.0pre4 + +THISAPP = iftop-$(VER) +DL_FILE = $(THISAPP).tar.gz +DL_FROM = $(URL_IPFIRE) +DIR_APP = $(DIR_SRC)/$(THISAPP) +TARGET = $(DIR_INFO)/$(THISAPP) +PROG = iftop +PAK_VER = 2 + +DEPS = "" + +############################################################################### +# Top-level Rules +############################################################################### + +objects = $(DL_FILE) + +$(DL_FILE) = $(DL_FROM)/$(DL_FILE) + +$(DL_FILE)_MD5 = 7e6decb4958e8a4890cccac335239f24 + +install : $(TARGET) + +check : $(patsubst %,$(DIR_CHK)/%,$(objects)) + +download :$(patsubst %,$(DIR_DL)/%,$(objects)) + +md5 : $(subst %,%_MD5,$(objects)) + +dist: + @$(PAK) + +############################################################################### +# Downloading, checking, md5sum +############################################################################### + +$(patsubst %,$(DIR_CHK)/%,$(objects)) : + @$(CHECK) + +$(patsubst %,$(DIR_DL)/%,$(objects)) : + @$(LOAD) + +$(subst %,%_MD5,$(objects)) : + @$(MD5) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && ./configure --prefix=/usr + + cd $(DIR_APP) && make $(MAKETUNING) + cd $(DIR_APP) && make install + + @rm -rf $(DIR_APP) + @$(POSTBUILD) + diff --git a/lfs/libgcrypt b/lfs/libgcrypt index 5d5572c..997bc06 100644 --- a/lfs/libgcrypt +++ b/lfs/libgcrypt @@ -24,7 +24,7 @@
include Config
-VER = 1.7.7 +VER = 1.8.0
THISAPP = libgcrypt-$(VER) DL_FILE = $(THISAPP).tar.bz2 @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = d1769481b1b506a632fd66c5e5f62e41 +$(DL_FILE)_MD5 = 530db74602b558209f9ad7356a680971
install : $(TARGET)
diff --git a/lfs/logrotate b/lfs/logrotate index 476f146..b047327 100644 --- a/lfs/logrotate +++ b/lfs/logrotate @@ -24,7 +24,7 @@
include Config
-VER = 3.12.1 +VER = 3.12.3
THISAPP = logrotate-$(VER) DL_FILE = logrotate-$(VER).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 066b49891bad2849d5044c1952613ea6 +$(DL_FILE)_MD5 = d1c41bdf63b9993c8e4e8b48a7bd5b8b
install : $(TARGET)
diff --git a/lfs/nano b/lfs/nano index 34e8444..3799831 100644 --- a/lfs/nano +++ b/lfs/nano @@ -24,7 +24,7 @@
include Config
-VER = 2.8.1 +VER = 2.8.6
THISAPP = nano-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = nano -PAK_VER = 15 +PAK_VER = 16
DEPS = ""
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 0dec96d839657e7f1a8396d7dbb19c07 +$(DL_FILE)_MD5 = e05d83c0f1687b733322f806c080d256
install : $(TARGET)
diff --git a/lfs/pcre b/lfs/pcre index 49656f1..0b68c59 100644 --- a/lfs/pcre +++ b/lfs/pcre @@ -24,7 +24,7 @@
include Config
-VER = 8.40 +VER = 8.41
THISAPP = pcre-$(VER) DL_FILE = $(THISAPP).tar.bz2 @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = 41a842bf7dcecd6634219336e2167d1d +$(DL_FILE)_MD5 = c160d22723b1670447341b08c58981c1
install : $(TARGET)
diff --git a/lfs/squid b/lfs/squid index 22659ed..8440cf8 100644 --- a/lfs/squid +++ b/lfs/squid @@ -70,6 +70,20 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar xaf $(DIR_DL)/$(DL_FILE) + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14169.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14170.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14171.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14172.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14173.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14174.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14175.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14176.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14177.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14178.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14179.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14180.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14181.patch + cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-3.5-14182.patch cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid-3.5.26-fix-max-file-descriptors.patch
cd $(DIR_APP) && autoreconf -vfi diff --git a/lfs/tor b/lfs/tor index f718843..9e46344 100644 --- a/lfs/tor +++ b/lfs/tor @@ -24,7 +24,7 @@
include Config
-VER = 0.3.0.8 +VER = 0.3.0.10
THISAPP = tor-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -32,7 +32,7 @@ DL_FROM = $(URL_IPFIRE) DIR_APP = $(DIR_SRC)/$(THISAPP) TARGET = $(DIR_INFO)/$(THISAPP) PROG = tor -PAK_VER = 21 +PAK_VER = 22
DEPS = ""
@@ -44,7 +44,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = c5c88b7e17f652c9fb4fc2c2ee92943c +$(DL_FILE)_MD5 = c9920169798c28b60b03fa3f0e592509
install : $(TARGET)
diff --git a/lfs/unbound b/lfs/unbound index 1270b35..5046f45 100644 --- a/lfs/unbound +++ b/lfs/unbound @@ -24,7 +24,7 @@
include Config
-VER = 1.6.3 +VER = 1.6.4
THISAPP = unbound-$(VER) DL_FILE = $(THISAPP).tar.gz @@ -40,7 +40,7 @@ objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-$(DL_FILE)_MD5 = d964d04c8d2b25f3271ac60fc630b654 +$(DL_FILE)_MD5 = ab6f7c07610907f1d87191c9ac2db87a
install : $(TARGET)
@@ -70,7 +70,6 @@ $(subst %,%_MD5,$(objects)) : $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @$(PREBUILD) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE) - cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/unbound-allow-setting-validator-permissive-mode-at-runtime.patch cd $(DIR_APP) && \ ./configure \ --prefix=/usr \ diff --git a/lfs/wio b/lfs/wio new file mode 100644 index 0000000..a3c00d9 --- /dev/null +++ b/lfs/wio @@ -0,0 +1,65 @@ +############################################################################### +# IPFire.org - An Open Source Firewall Solution # +# Copyright (C) - IPFire Development Team info@ipfire.org # +############################################################################### + +############################################################################### +# Definitions +############################################################################### + +include Config + +VER = 1.3.1 + +THISAPP = wio-$(VER) +DIR_APP = $(DIR_SRC)/$(THISAPP) +TARGET = $(DIR_INFO)/$(THISAPP) +PROG = wio +PAK_VER = 1 + +############################################################################### +# Top-level Rules +############################################################################### + +install : $(TARGET) + +check : + +download : + +md5 : + +dist: + @$(PAK) + +############################################################################### +# Installation Details +############################################################################### + +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) + @$(PREBUILD) + @rm -rf $(DIR_APP) && mkdir $(DIR_APP) && cp -R $(DIR_SRC)/src/wio/ $(DIR_APP) + cd $(DIR_APP) + mkdir -p /usr/lib/wio + mkdir -p /var/log/wio + mkdir -p /var/log/rrd/wio + mkdir -p /srv/web/ipfire/html/images/wio + mkdir -p /var/ipfire/wio + + install -v -m 755 $(DIR_APP)/wio/wio.cgi /srv/web/ipfire/cgi-bin/ + install -v -m 755 $(DIR_APP)/wio/wiographs.cgi /srv/web/ipfire/cgi-bin/ + install -v -m 755 $(DIR_APP)/wio/wio /etc/fcron.minutely/ + install -v -m 644 $(DIR_APP)/wio/main/wio.conf /var/ipfire/wio/ + install -v -m 754 $(DIR_APP)/wio/main/wio.pl /var/ipfire/wio/ + install -v -m 754 $(DIR_APP)/wio/main/wiovpn.pl /var/ipfire/wio/ + install -v -m 644 $(DIR_APP)/wio/wio-lib.pl /usr/lib/wio/ + install -v -m 644 $(DIR_APP)/wio/wio-graphs.pl /usr/lib/wio/ + install -v -m 644 $(DIR_APP)/wio/wioips /var/log/wio/ + install -v -m 644 $(DIR_APP)/wio/images/* /srv/web/ipfire/html/images/wio/ + install -v -m 655 $(DIR_APP)/wio/lang/wio.de.pl /var/ipfire/addon-lang/ + install -v -m 655 $(DIR_APP)/wio/lang/wio.en.pl /var/ipfire/addon-lang/ + install -v -m 655 $(DIR_APP)/wio/EX-wio.menu /var/ipfire/menu.d/ + install -v -m 644 $(DIR_APP)/wio/config/backup/includes/wio /var/ipfire/backup/addons/includes/wio + + @rm -rf $(DIR_APP) + @$(POSTBUILD) diff --git a/make.sh b/make.sh index 663f23f..f48c92f 100755 --- a/make.sh +++ b/make.sh @@ -25,7 +25,7 @@ NAME="IPFire" # Software name SNAME="ipfire" # Short name VERSION="2.19" # Version number -CORE="112" # Core Level (Filename) +CORE="113" # Core Level (Filename) PAKFIRE_CORE="112" # Core Level (PAKFIRE) GIT_BRANCH=`git rev-parse --abbrev-ref HEAD` # Git Branch SLOGAN="www.ipfire.org" # Software slogan @@ -885,6 +885,7 @@ buildipfire() { lfsmake2 perl-common-sense lfsmake2 perl-inotify2 lfsmake2 perl-Net-IP + lfsmake2 wio }
buildinstaller() { diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile index 08a4e37..7cc70b4 100644 --- a/src/misc-progs/Makefile +++ b/src/misc-progs/Makefile @@ -26,7 +26,7 @@ PROGS = iowrap SUID_PROGS = squidctrl sshctrl ipfirereboot \ ipsecctrl timectrl dhcpctrl snortctrl \ applejuicectrl rebuildhosts backupctrl collectdctrl \ - logwatch openvpnctrl firewallctrl \ + logwatch wioscan wiohelper openvpnctrl firewallctrl \ wirelessctrl getipstat qosctrl launch-ether-wake \ redctrl syslogdctrl extrahdctrl sambactrl upnpctrl \ smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \ diff --git a/src/misc-progs/list.h b/src/misc-progs/list.h new file mode 100644 index 0000000..19bd21e --- /dev/null +++ b/src/misc-progs/list.h @@ -0,0 +1,129 @@ +/* list.h by Jan Bobrowski. Inspired by list.h from Linux */ + +#ifndef LIST_H +#define LIST_H + +typedef struct list { + struct list *next, *prev; +} list_t; + +static inline void list_link(struct list *a, struct list *b) +{ + a->next = b; + b->prev = a; +} + +static inline void list_add(struct list *head, struct list *item) +{ + struct list *first = head->next; + list_link(head, item); + list_link(item, first); +} + +static inline void list_add_end(struct list *head, struct list *item) +{ + struct list *last = head->prev; + list_link(item, head); + list_link(last, item); +} + +static inline list_t *list_del(struct list *item) +{ + struct list *prev = item->prev, *next = item->next; + list_link(prev, next); + return next; +} + +static inline void list_init(struct list *head) +{ + list_link(head, head); +} + +/* delete item from one list and add it to another */ +static inline void list_del_add(list_t *head, list_t *item) +{ + list_t *prev = item->prev, *next = item->next; + list_link(prev, next); + next = head->next; + list_link(head, item); + list_link(item, next); +} + +/*static inline list_check(list_t *l) +{ + list_t *a = l; + list_t *b; + do { + b = a->next; + assert(b->prev == a); + if(a==l) break; + a = b; + } while(1); +}*/ + +static inline void list_del_add_end(list_t *head, list_t *item) +{ + list_t *prev = item->prev, *next = item->next; + list_link(prev, next); + prev = head->prev; + list_link(item, head); + item->prev = prev; + prev->next = item; +} + +static inline void list_del_init(struct list *item) +{ + struct list *prev = item->prev, *next = item->next; + list_link(item, item); + list_link(prev, next); +} + +static inline void list_join(struct list *a, struct list *b) +{ + list_t *ae = a->prev; + list_t *be = b->prev; + b->prev = ae; + a->prev = be; + ae->next = b; + be->next = a; +} + +static inline int list_empty(struct list *head) +{ + return head->next == head; +} + +#define LIST(L) struct list L = {&L, &L} + +#define list_entry(L, T, M) ((T*)((char*)(L) - (long)(&((T*)0)->M))) +#define list_item(L, T, M) ((T*)((char*)(L) - (long)(&((T*)0)->M))) + +#define list_first(H, T, M) list_item((H)->next, T, M) +#define list_last(H, T, M) list_item((H)->prev, T, M) +#define list_next(O, M) list_item((O)->M.next, typeof(*(O)), M) + +/* remove first element and return it */ +static inline struct list *list_get(struct list *head) +{ + struct list *item = head->next; + struct list *next = item->next; + list_link(head, next); + return item; +} + +/* remove first element, initialize and return it */ +static inline struct list *list_get_init(struct list *head) +{ + struct list *item = head->next; + struct list *next = item->next; + list_link(item, item); + list_link(head, next); + return item; +} + +#define list_get_entry(H, T, M) list_item(list_get((H)), T, M) +#define list_get_init_entry(H, T, M) list_item(list_get_init((H)), T, M) +#define list_get_item(H, T, M) list_item(list_get((H)), T, M) +#define list_get_init_item(H, T, M) list_item(list_get_init((H)), T, M) + +#endif diff --git a/src/misc-progs/wiohelper.c b/src/misc-progs/wiohelper.c new file mode 100644 index 0000000..0f7fd86 --- /dev/null +++ b/src/misc-progs/wiohelper.c @@ -0,0 +1,31 @@ +/* wiohelper - a Who Is Online? Addon helper program + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * This program is distributed under the terms of the GNU General Public + * Licence. See the file COPYING for details. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * IPFire.org - A linux based firewall + * Copyright (C) 2017 Stephan Feddersen addons@h-loit.de + * + * All Rights Reserved. + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Simple program intended to be installed setuid(0) that can be used from WIO + * +*/ + +#include "setuid.h" + +int main(void) +{ + if (!(initsetuid())) + exit(1); + + safe_system("/var/ipfire/wio/wio.pl"); + + return 0; +} diff --git a/src/misc-progs/wioscan.c b/src/misc-progs/wioscan.c new file mode 100644 index 0000000..206456c --- /dev/null +++ b/src/misc-progs/wioscan.c @@ -0,0 +1,665 @@ +/* + * wioscan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#define _GNU_SOURCE +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <poll.h> +#include <errno.h> +#include <err.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <netpacket/packet.h> +#include <net/ethernet.h> +#include <net/if.h> +#include <net/if_arp.h> +#include <netinet/ether.h> +#include <arpa/inet.h> +#include <stdint.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/mman.h> + +#define _STR(S) #S +#define STR(S) _STR(S) + +#define ARP htons(ETHERTYPE_ARP) +#define IP htons(ETHERTYPE_IP) + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +#include "list.h" +#define elemof(T) (sizeof T/sizeof*T) +#define endof(T) (T+elemof(T)) +#ifndef offsetof +#define offsetof(T,M) ((int)(long)&((T*)0)->M) +#endif + +#define HWMAX 8 + +union addr { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_ll ll; +}; + +int sock; /* packet socket */ +union addr bcast; + +struct opts { + unsigned sort:1; + unsigned noown:1; + unsigned noethn:1; + unsigned proui:1; + unsigned isrange:1; + unsigned passive:1; + unsigned nsend; + unsigned wait; +} opts = {nsend:8, wait:250}; + +void print_oui(int sp, u8 a[6]); + +struct he; +void print_he(struct he *he); + +struct hwaddr { + u8 len, addr[HWMAX]; +}; + +static inline hw_eq(struct hwaddr *h, int hl, u8 *ha) +{ + return h->len == hl && memcmp(h->addr, ha, hl) == 0; +} + +static inline void hw_set(struct hwaddr *h, int hl, u8 *ha) +{ + memcpy(h->addr, ha, (h->len = hl)); +} + +struct ifinfo { + int index; + char *name; + u32 ip, net, mask, bcast; + u16 hw_type; + struct hwaddr hw; +} ifinfo; + +static inline u32 ip_from_sa(struct sockaddr *sa) +{ + return ntohl(((struct sockaddr_in*)sa)->sin_addr.s_addr); +} + +/* TABLE */ + +struct list hashtbl[128]; +struct he { + struct list hash; + u32 ip; + struct hwaddr hw; + struct hwaddr from; +}; + +static void init_hash() __attribute__((constructor)); +static void init_hash() +{ + int i; + for(i=0;i<elemof(hashtbl);i++) list_init(&hashtbl[i]); +} + +int he_for(u32 ip, struct he **ret, int alloc) +{ + struct list *h, *l; + struct he *he; + int v = 1; + h = &hashtbl[ip & elemof(hashtbl)-1]; + for(l=h->next; l!=h; l=l->next) { + he = list_entry(l, struct he, hash); + if(he->ip == ip) + goto ret; + if(he->ip > ip) + break; + } + v = 0; + if(alloc) { + he = (struct he*)malloc(sizeof *he); + he->ip = ip; + list_add(l->prev, &he->hash); +ret: + if(ret) *ret = he; + } + return v; +} + +/* INTERFACE */ + +static int net; + +static void my__ioctl(int i, struct ifreq *r, char *t) +{ + if(ioctl(net, i, r) < 0) + err(1, "ioctl(%s,%s)", t, r->ifr_name); +} +#define my_ioctl(I,R) my__ioctl(I,R,#I) + +void fill_ifinfo(char *name) +{ + struct ifreq ir; + int flags; + + ifinfo.index = if_nametoindex(name); + if(!ifinfo.index) errx(1, "No such interface: %s", name); + ifinfo.name = name; + + net = socket(PF_INET, SOCK_DGRAM, 0); + if(net<0) err(1, "socket(PF_INET)"); + strcpy(ir.ifr_name, ifinfo.name); + my_ioctl(SIOCGIFFLAGS, &ir); + flags = ir.ifr_flags; + if(flags & IFF_NOARP) errx(1, "%s: ARP not supported.", name); + my_ioctl(SIOCGIFADDR, &ir); + ifinfo.ip = ip_from_sa(&ir.ifr_addr); + if(flags & IFF_POINTOPOINT) { + my_ioctl(SIOCGIFDSTADDR, &ir); + ifinfo.net = ip_from_sa(&ir.ifr_dstaddr); + ifinfo.mask = (u32)~0; + ifinfo.bcast = 0; /* none */ + } else { + my_ioctl(SIOCGIFNETMASK, &ir); + ifinfo.mask = ip_from_sa(&ir.ifr_netmask); + my_ioctl(SIOCGIFBRDADDR, &ir); + ifinfo.bcast = ip_from_sa(&ir.ifr_broadaddr); + ifinfo.net = ifinfo.ip & ifinfo.mask; + } + close(net); +} + +static inline char *str_ip(u32 ip) +{ + struct in_addr n; + n.s_addr = htonl(ip); + return inet_ntoa(n); +} + +char *str_hw(u8 *a, int l) +{ + static char buf[3*HWMAX]; + char *d = buf; + if(!l) return "*"; + if(l>HWMAX) l=HWMAX; + for(;;) { + d += sprintf(d, "%02X", *a++); + if(--l <= 0) break; + *d++ = ':'; + } + *d = 0; + return buf; +} + +static char *str_addr(union addr *addr) +{ + switch(addr->sa.sa_family) { + case AF_INET: return inet_ntoa(addr->in.sin_addr); + case AF_PACKET: return str_hw(addr->ll.sll_addr, addr->ll.sll_halen); + default: return "???"; + } +} + +static inline void setup_socket() +{ + union addr addr; + socklen_t l; + + sock = socket(PF_PACKET, SOCK_DGRAM, 0); + if(sock < 0) err(1, "socket(PF_PACKET)"); + + memset(&addr.ll, 0, sizeof addr.ll); + addr.sa.sa_family = AF_PACKET; + addr.ll.sll_protocol = ARP; + addr.ll.sll_ifindex = ifinfo.index; + + if(bind(sock, &addr.sa, sizeof addr.ll)<0) + err(1, "bind"); + l = sizeof addr.ll; + if(getsockname(sock, &addr.sa, &l)<0) + err(1, "getsockname"); + + if(addr.ll.sll_halen > HWMAX) + errx(1, "hardware address too long (%d)", addr.ll.sll_halen); + ifinfo.hw.len = addr.ll.sll_halen; + memcpy(ifinfo.hw.addr, addr.ll.sll_addr, sizeof ifinfo.hw.addr); + ifinfo.hw_type = addr.ll.sll_hatype; +} + +/* SCAN */ + +struct arppkt { + u16 hrd, pro; + u8 hln, pln; + u16 op; + u8 a[2*HWMAX+2*4]; +/* u8 sha[6]; + u8 sip[4]; + u8 tha[6]; + u8 tip[4];*/ +}; + +static inline u8 *get_sha(struct arppkt *pkt) {return pkt->a;} +static inline u8 *get_tha(struct arppkt *pkt) {return pkt->a+pkt->hln+4;} +static inline u32 get_sip(struct arppkt *pkt) {return ntohl(*(u32*)(pkt->a+pkt->hln));} +static inline u32 get_tip(struct arppkt *pkt) {return ntohl(*(u32*)(pkt->a+2*pkt->hln+4));} + +#if 0 +void print_arp(struct arppkt *arp) +{ + u8 *p = arp->a; + printf("hrd:%04X pro:%04X ", ntohs(arp->hrd), ntohs(arp->pro)); + printf("hln:%d pln:%d op:%d ", arp->hln, arp->pln, ntohs(arp->op)); + printf("sha:%s ", str_hw(p, arp->hln)); p+=arp->hln; + printf("sip:%s ", str_ip(ntohl(*(u32*)p))); p+=arp->pln; + printf("tha:%s ", str_hw(p, arp->hln)); p+=arp->hln; + printf("tip:%s\n", str_ip(ntohl(*(u32*)p))); +} +#endif + +static struct scan { + u32 ip, start, end; +} scan; + +#define IN_RANGE(I) ((I) >= scan.start && (I) <= (u32)(scan.end-1)) + +int sendscan() +{ + struct arppkt arp; + int ns; + u8 *p; + + arp.hrd = htons(ifinfo.hw_type); + arp.pro = IP; + arp.hln = ifinfo.hw.len; + arp.pln = 4; + arp.op = htons(1); + p = arp.a; + memcpy(p, ifinfo.hw.addr, ifinfo.hw.len); p += ifinfo.hw.len; + *(u32*)p = htonl(ifinfo.ip); p += 4; + memset(p, 0, ifinfo.hw.len); p += ifinfo.hw.len; + + ns = 0; + while(scan.ip != scan.end) { + int v; + if(scan.ip == ifinfo.bcast || he_for(scan.ip, 0, 0)) { + scan.ip++; + continue; + } + *(u32*)p = htonl(scan.ip); + v = sendto(sock, &arp, p+4-(u8*)&arp, 0, &bcast.sa, sizeof bcast.ll); + if(v<0) { + if(errno != ENOBUFS || opts.nsend <= 1) + err(1, "send(%s)", str_addr(&bcast)); + opts.nsend--; + return -1; + } + scan.ip++; + if(++ns >= opts.nsend) break; + } + return ns; +} + +void compare_resp(struct he *he, union addr *src, int hln, u8 *sha) +{ + if(hw_eq(&he->hw, hln, sha) + && hw_eq(&he->from, src->ll.sll_halen, src->ll.sll_addr)) + return; + + fprintf(stderr, "%s: ", str_ip(he->ip)); + fprintf(stderr, "inconsistency: %s", str_hw(sha, hln)); + if(src->ll.sll_halen != hln || memcmp(src->ll.sll_addr, sha, hln)) + fprintf(stderr, " from %s", + str_hw(src->ll.sll_addr, src->ll.sll_halen)); + fprintf(stderr, ", was %s\n", str_hw(he->hw.addr, he->hw.len)); + if(!hw_eq(&he->hw, he->from.len, he->from.addr)) + fprintf(stderr, " from %s", + str_hw(he->from.addr, he->from.len)); +} + +int arp_recv(struct arppkt *pkt, union addr *src) +{ + socklen_t l = sizeof *src; + int v = recvfrom(sock, pkt, sizeof *pkt, 0, &src->sa, &l); + if(v < 0) err(1, "recvfrom"); + if(v < offsetof(struct arppkt, a)) + return 0; + if(pkt->pro != IP) + return 0; + if(pkt->hrd != htons(ifinfo.hw_type) || pkt->hln != ifinfo.hw.len) + return 0; + if(v < offsetof(struct arppkt, a) + 2*pkt->hln + 2*4) + return 0; + return 1; +} + +void receive() +{ + union addr addr; + struct arppkt arp; + struct he *he; + u32 ip; + + if(!arp_recv(&arp, &addr)) + return; + if(arp.op != htons(2)) /* only responses */ + return; + + ip = get_sip(&arp); + + if(!he_for(ip, &he, 1)) { + hw_set(&he->hw, arp.hln, get_sha(&arp)); + hw_set(&he->from, addr.ll.sll_halen, addr.ll.sll_addr); + if(opts.sort) return; + if(opts.isrange && !IN_RANGE(ip)) return; + print_he(he); + } else + compare_resp(he, &addr, arp.hln, get_sha(&arp)); +} + +/**/ + +void passive() +{ + for(;;) { + struct arppkt arp; + union addr src; + if(!arp_recv(&arp, &src)) + continue; + printf("%s: ", str_addr(&src)); + printf("%s %-15s ", str_hw(get_sha(&arp),arp.hln), + str_ip(get_sip(&arp))); + switch(htons(arp.op)) { + case 1: + printf("Q %s", str_ip(get_tip(&arp))); + break; + case 2: + printf("A %s %s", str_hw(get_tha(&arp),arp.hln), + str_ip(get_tip(&arp))); + break; + default: + printf("%X", htons(arp.op)); + } + putchar('\n'); + } +} + +/**/ + +int waitsock(int n) +{ + int v; + struct pollfd pollfd; + pollfd.fd = sock; + pollfd.events = POLLIN; + v = poll(&pollfd, 1, n); + if(v < 0) { + if(errno != EINTR) + err(1, "poll"); + v = 0; + } + return v; +} + +void print_he(struct he *he) +{ + int l, w; + if(opts.noown && he->ip == ifinfo.ip) + return; + printf("%s,", str_hw(he->hw.addr, he->hw.len)); + l = 15 - printf("%s", str_ip(he->ip)); + w = 0; + if(!opts.proui && !hw_eq(&he->from, he->hw.len, he->hw.addr)) + w = 1, l = 1; + + if(opts.proui) + print_oui(l, he->hw.addr); + else if(!opts.noethn) { +#if !defined __dietlibc_ && !defined __UCLIBC__ + char nm[1024]; + if(!ether_ntohost(nm, (struct ether_addr*)he->hw.addr)) + printf("%*s%s", l, "", nm); +#endif + } + if(w) + printf(" from %s", str_hw(he->from.addr, he->from.len)); + putchar('\n'); +} + +static int parse_iprange(char *p) +{ + char *e; + u32 ip=0; + int sh; + + for(sh = 24;; sh -= 8) { + unsigned long v; + + v = strtoul(p, &e, 10); + if(p == e || v > 255) + return 0; + + ip |= v << sh; + + p = e + 1; + if(*e == '/') { + v = strtoul(p, &e, 10); + if(p == e || *e || v > 32) + return 0; + if(v) { + v = 32 - v; + if(sh > v) + return 0; +mask: + v = ~0 << v; + } + scan.start = ip & v; + scan.end = scan.start - v; + return 1; + } + + if(!sh) break; + + v = sh; + if(!*e) + goto mask; + + if(*e != '.') + return 0; + + if(!*p || *p == '*' && !p[1]) + goto mask; + } + + scan.start = ip; + scan.end = ip + 1; + + if(*e == '-') { + u32 end = 0, m = ~0; + + do { + unsigned long v = strtoul(p, &e, 10); + if(p == e || v > 255) + return 0; + p = e + 1; + end = end<<8 | v; + m <<= 8; + } while(m && *e); + + if(*e) + return 0; + + end |= ip & m; + if(end < ip) + return 0; + + scan.end = end + 1; + return 1; + } + return *e == 0; +} + +int main(int argc, char **argv) +{ + for(;;) switch(getopt(argc, argv, "fsaepwlh")) { + case 'f': opts.sort=0; break; + case 's': opts.sort=1; break; + case 'a': opts.noown=1; break; + case 'e': opts.noethn=1; break; + case 'p': opts.proui=1; break; + case 'w': opts.nsend=2; opts.wait=1000; break; + case 'l': opts.passive=1; break; + case 'h': + printf( + "wioscan [-faep] [interface] [ip-range]\n" + "\t-s sort responses\n" + "\t-a do not list interface's own address\n" +#if !defined __dietlibc_ && !defined __UCLIBC__ + "\t-e do not include info from /etc/ethers\n" +#endif + "\t-p print vendor names\n" + "\t-w slow operation\n" + "\t-l listen only (not promiscuous)\n" + "ip-range: ip ip/bits ip-ip\n" + ); + return 0; + case EOF: + goto endopt; + } +endopt: + + { + char *dev = "eth0"; + if(optind<argc && (*argv[optind] < '0' || *argv[optind] > '9')) + dev = argv[optind++]; + fill_ifinfo(dev); + setup_socket(); + } + + if(optind>=argc) { + scan.start = ifinfo.net; + scan.end = (ifinfo.net | ~ifinfo.mask) + 1; + } else { + if(!parse_iprange(argv[optind])) + errx(1, "%s: bad IP range", argv[optind]); + opts.isrange = 1; + } + + if(ifinfo.hw_type != ARPHRD_ETHER) + opts.proui = 0, opts.noethn = 1; + + if(opts.passive) + passive(); + + /* hw broadcast address is Linux's secret, this works with Ethernet */ + bcast.sa.sa_family = AF_PACKET; + bcast.ll.sll_protocol = ARP; + bcast.ll.sll_ifindex = ifinfo.index; + bcast.ll.sll_hatype = ifinfo.hw_type; + bcast.ll.sll_pkttype = PACKET_BROADCAST; /* unused :-( */ + bcast.ll.sll_halen = ifinfo.hw.len; + memset(bcast.ll.sll_addr, 0xFF, ifinfo.hw.len); + + if(IN_RANGE(ifinfo.ip)) { + /* XXX we should add all our arpable addresses on the interface */ + struct he *he; + he_for(ifinfo.ip, &he, 1); + hw_set(&he->hw, ifinfo.hw.len, ifinfo.hw.addr); + hw_set(&he->from, ifinfo.hw.len, ifinfo.hw.addr); + if(!opts.sort) + print_he(he); + } + + /* 1st scan */ + scan.ip = scan.start; + while(sendscan()) { + while(waitsock(10)) + receive(); + } + /* 2nd scan */ + scan.ip = scan.start; + while(sendscan()) { + while(waitsock(10)) + receive(); + } + while(waitsock(opts.wait)) + receive(); + + if(opts.sort) for(scan.ip = ifinfo.net; scan.ip != scan.end; scan.ip++) { + struct he *he; + if(he_for(scan.ip, &he, 0)) + print_he(he); + } + return 0; +} + + +typedef uint8_t u8; +static int fd = -2; +static char *ouiptr, *ouiend; + +static void open_oui() +{ + struct stat st; + fd = open("oui", O_RDONLY); + if(fd < 0) { + fd = open(STR(OUI), O_RDONLY); + if(fd < 0) goto err; + } + if(fstat(fd, &st) < 0 || st.st_size == 0) goto err_cl; + ouiptr = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + ouiend = ouiptr + st.st_size; + if(ouiptr == MAP_FAILED) { +err_cl: + close(fd); fd=-1; +err: + warnx("Can't open OUI database"); + return; + } +#ifdef MADV_SEQUENTIAL + madvise(ouiptr, st.st_size, MADV_SEQUENTIAL); +#endif +} + +void print_oui(int sp, u8 a[6]) +{ + char addr[7], *p, *q; + if(fd < 0) { + if(fd == -2) + open_oui(); + if(fd < 0) + return; + } + sprintf(addr, "%02X%02X%02X", a[0], a[1], a[2]); + + for(p=ouiptr; p<ouiend; p=q+1) { + q = memchr(p, '\n', ouiend-p); + if(!q) q=ouiend; + if(q-p < 8 || memcmp(p, addr, 6)) + continue; + + p += 7; +print: + printf("%*s%.*s", sp, "", (int)(q-p), p); + return; + } + if(a[0]==0 && a[1]==0xFF) { + p = "(generated)"; + q = p + 11; + goto print; + } +} \ No newline at end of file diff --git a/src/paks/wio/install.sh b/src/paks/wio/install.sh new file mode 100644 index 0000000..f46ae35 --- /dev/null +++ b/src/paks/wio/install.sh @@ -0,0 +1,37 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire 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. # +# # +# IPFire 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2009 IPFire-Team info@ipfire.org. # +# # +############################################################################ +# +. /opt/pakfire/lib/functions.sh +extract_files +restore_backup ${NAME} + +chown -R nobody.nobody /var/ipfire/wio +chown -R nobody.nobody /var/log/rrd/wio +chown -R nobody.nobody /var/log/wio +chown root.nobody /usr/local/bin/wioscan +chown root.nobody /usr/local/bin/wiohelper + +chmod 4750 /usr/local/bin/wioscan +chmod 4750 /usr/local/bin/wiohelper + +/usr/local/bin/update-lang-cache diff --git a/src/paks/wio/uninstall.sh b/src/paks/wio/uninstall.sh new file mode 100644 index 0000000..6be522d --- /dev/null +++ b/src/paks/wio/uninstall.sh @@ -0,0 +1,28 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire 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. # +# # +# IPFire 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2014 IPFire-Team alexander.marx@ipfire.org # +# # +############################################################################ + +. /opt/pakfire/lib/functions.sh +make_backup ${NAME} +remove_files + +/usr/local/bin/update-lang-cache diff --git a/src/paks/wio/update.sh b/src/paks/wio/update.sh new file mode 100644 index 0000000..89c40d0 --- /dev/null +++ b/src/paks/wio/update.sh @@ -0,0 +1,26 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire 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. # +# # +# IPFire 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 IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2007 IPFire-Team info@ipfire.org. # +# # +############################################################################ +# +. /opt/pakfire/lib/functions.sh +./uninstall.sh +./install.sh diff --git a/src/patches/squid/squid-3.5-14169.patch b/src/patches/squid/squid-3.5-14169.patch new file mode 100644 index 0000000..464ce53 --- /dev/null +++ b/src/patches/squid/squid-3.5-14169.patch @@ -0,0 +1,881 @@ +------------------------------------------------------------ +revno: 14169 +revision-id: squid3@treenet.co.nz-20170614213720-3qmiohlx4zr2jnqq +parent: squid3@treenet.co.nz-20170601134753-6u64sl2rzmbfs67l +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=2833 +author: Eduard Bagdasaryan eduard.bagdasaryan@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Thu 2017-06-15 09:37:20 +1200 +message: + Bug 2833 pt2: Collapse internal revalidation requests (SMP-unaware caches), again. + + The security fix in v5 r14979 had a negative effect on collapsed + forwarding. All "private" entries were considered automatically + non-shareable among collapsed clients. However this is not true: there + are many situations when collapsed forwarding should work despite of + "private" entry status: 304/5xx responses are good examples of that. + This patch fixes that by means of a new StoreEntry::shareableWhenPrivate + flag. + + The suggested fix is not complete: To cover all possible situations, we + need to decide whether StoreEntry::shareableWhenPrivate is true or not + for all contexts where StoreEntry::setPrivateKey() is used. This patch + fixes only few important cases inside http.cc, making CF (as well + collapsed revalidation) work for some [non-cacheable] response status + codes, including 3xx, 5xx and some others. + + The original support for internal revalidation requests collapsing + was in trink r14755 and referred to Squid bugs 2833, 4311, and 4471. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170614213720-3qmiohlx4zr2jnqq +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 9e248e2e9d2f1defe1070eb808177df978fb4146 +# timestamp: 2017-06-14 21:51:05 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170601134753-\ +# 6u64sl2rzmbfs67l +# +# Begin patch +=== modified file 'src/HttpHdrCc.cc' +--- src/HttpHdrCc.cc 2017-01-01 00:16:45 +0000 ++++ src/HttpHdrCc.cc 2017-06-14 21:37:20 +0000 +@@ -262,8 +262,8 @@ + case CC_PUBLIC: + break; + case CC_PRIVATE: +- if (Private().size()) +- packerPrintf(p, "="" SQUIDSTRINGPH """, SQUIDSTRINGPRINT(Private())); ++ if (private_.size()) ++ packerPrintf(p, "="" SQUIDSTRINGPH """, SQUIDSTRINGPRINT(private_)); + break; + + case CC_NO_CACHE: + +=== modified file 'src/MemStore.cc' +--- src/MemStore.cc 2017-01-01 00:16:45 +0000 ++++ src/MemStore.cc 2017-06-14 21:37:20 +0000 +@@ -299,7 +299,7 @@ + e.ping_status = PING_NONE; + + EBIT_CLR(e.flags, RELEASE_REQUEST); +- EBIT_CLR(e.flags, KEY_PRIVATE); ++ e.clearPrivate(); + EBIT_SET(e.flags, ENTRY_VALIDATED); + + MemObject::MemCache &mc = e.mem_obj->memCache; + +=== modified file 'src/Store.h' +--- src/Store.h 2017-01-01 00:16:45 +0000 ++++ src/Store.h 2017-06-14 21:37:20 +0000 +@@ -95,15 +95,19 @@ + void abort(); + void unlink(); + void makePublic(const KeyScope keyScope = ksDefault); +- void makePrivate(); ++ void makePrivate(const bool shareable); ++ /// A low-level method just resetting "private key" flags. ++ /// To avoid key inconsistency please use forcePublicKey() ++ /// or similar instead. ++ void clearPrivate(); + void setPublicKey(const KeyScope keyScope = ksDefault); + /// Resets existing public key to a public key with default scope, + /// releasing the old default-scope entry (if any). + /// Does nothing if the existing public key already has default scope. + void clearPublicKeyScope(); +- void setPrivateKey(); ++ void setPrivateKey(const bool shareable); + void expireNow(); +- void releaseRequest(); ++ void releaseRequest(const bool shareable = false); + void negativeCache(); + void cacheNegatively(); /** \todo argh, why both? */ + void invokeHandlers(); +@@ -230,7 +234,13 @@ + /// update last reference timestamp and related Store metadata + void touch(); + +- virtual void release(); ++ virtual void release(const bool shareable = false); ++ ++ /// May the caller commit to treating this [previously locked] ++ /// entry as a cache hit? ++ bool mayStartHitting() const { ++ return !EBIT_TEST(flags, KEY_PRIVATE) || shareableWhenPrivate; ++ } + + #if USE_ADAPTATION + /// call back producer when more buffer space is available +@@ -252,6 +262,13 @@ + + unsigned short lock_count; /* Assume < 65536! */ + ++ /// Nobody can find/lock KEY_PRIVATE entries, but some transactions ++ /// (e.g., collapsed requests) find/lock a public entry before it becomes ++ /// private. May such transactions start using the now-private entry ++ /// they previously locked? This member should not affect transactions ++ /// that already started reading from the entry. ++ bool shareableWhenPrivate; ++ + #if USE_ADAPTATION + /// producer callback registered with deferProducer + AsyncCall::Pointer deferredProducer; +@@ -259,6 +276,8 @@ + + bool validLength() const; + bool hasOneOfEtags(const String &reqETags, const bool allowWeakMatch) const; ++ ++ friend std::ostream &operator <<(std::ostream &os, const StoreEntry &e); + }; + + std::ostream &operator <<(std::ostream &os, const StoreEntry &e); + +=== modified file 'src/client_side_reply.cc' +--- src/client_side_reply.cc 2017-05-29 13:15:55 +0000 ++++ src/client_side_reply.cc 2017-06-14 21:37:20 +0000 +@@ -396,8 +396,8 @@ + if (result.flags.error && !EBIT_TEST(http->storeEntry()->flags, ENTRY_ABORTED)) + return; + +- if (collapsedRevalidation == crSlave && EBIT_TEST(http->storeEntry()->flags, KEY_PRIVATE)) { +- debugs(88, 3, "CF slave hit private " << *http->storeEntry() << ". MISS"); ++ if (collapsedRevalidation == crSlave && !http->storeEntry()->mayStartHitting()) { ++ debugs(88, 3, "CF slave hit private non-shareable " << *http->storeEntry() << ". MISS"); + // restore context to meet processMiss() expectations + restoreState(); + http->logType = LOG_TCP_MISS; +@@ -530,7 +530,7 @@ + // The previously identified hit suddenly became unsharable! + // This is common for collapsed forwarding slaves but might also + // happen to regular hits because we are called asynchronously. +- if (EBIT_TEST(e->flags, KEY_PRIVATE)) { ++ if (!e->mayStartHitting()) { + debugs(88, 3, "unsharable " << *e << ". MISS"); + http->logType = LOG_TCP_MISS; + processMiss(); + +=== modified file 'src/fs/rock/RockSwapDir.cc' +--- src/fs/rock/RockSwapDir.cc 2017-01-01 00:16:45 +0000 ++++ src/fs/rock/RockSwapDir.cc 2017-06-14 21:37:20 +0000 +@@ -149,7 +149,7 @@ + e.ping_status = PING_NONE; + + EBIT_CLR(e.flags, RELEASE_REQUEST); +- EBIT_CLR(e.flags, KEY_PRIVATE); ++ e.clearPrivate(); + EBIT_SET(e.flags, ENTRY_VALIDATED); + + e.swap_dirn = index; + +=== modified file 'src/fs/ufs/UFSSwapDir.cc' +--- src/fs/ufs/UFSSwapDir.cc 2017-01-01 00:16:45 +0000 ++++ src/fs/ufs/UFSSwapDir.cc 2017-06-14 21:37:20 +0000 +@@ -809,7 +809,7 @@ + e->refcount = refcount; + e->flags = newFlags; + EBIT_CLR(e->flags, RELEASE_REQUEST); +- EBIT_CLR(e->flags, KEY_PRIVATE); ++ e->clearPrivate(); + e->ping_status = PING_NONE; + EBIT_CLR(e->flags, ENTRY_VALIDATED); + mapBitSet(e->swap_filen); + +=== modified file 'src/http.cc' +--- src/http.cc 2017-01-01 00:16:45 +0000 ++++ src/http.cc 2017-06-14 21:37:20 +0000 +@@ -290,7 +290,9 @@ + (Config.onoff.surrogate_is_remote + && sctusable->noStoreRemote())) { + surrogateNoStore = true; +- entry->makePrivate(); ++ // Be conservative for now and make it non-shareable because ++ // there is no enough information here to make the decision. ++ entry->makePrivate(false); + } + + /* The HttpHeader logic cannot tell if the header it's parsing is a reply to an +@@ -315,12 +317,13 @@ + } + } + +-int +-HttpStateData::cacheableReply() ++HttpStateData::ReuseDecision::Answers ++HttpStateData::reusableReply(HttpStateData::ReuseDecision &decision) + { + HttpReply const *rep = finalReply(); + HttpHeader const *hdr = &rep->header; + const char *v; ++ + #if USE_HTTP_VIOLATIONS + + const RefreshPattern *R = NULL; +@@ -337,24 +340,19 @@ + #define REFRESH_OVERRIDE(flag) 0 + #endif + +- if (EBIT_TEST(entry->flags, RELEASE_REQUEST)) { +- debugs(22, 3, "NO because " << *entry << " has been released."); +- return 0; +- } ++ if (EBIT_TEST(entry->flags, RELEASE_REQUEST)) ++ return decision.make(ReuseDecision::reuseNot, "the entry has been released"); + + // RFC 7234 section 4: a cache MUST use the most recent response + // (as determined by the Date header field) +- if (sawDateGoBack) { +- debugs(22, 3, "NO because " << *entry << " has an older date header."); +- return 0; +- } ++ // TODO: whether such responses could be shareable? ++ if (sawDateGoBack) ++ return decision.make(ReuseDecision::reuseNot, "the response has an older date header"); + + // Check for Surrogate/1.0 protocol conditions + // NP: reverse-proxy traffic our parent server has instructed us never to cache +- if (surrogateNoStore) { +- debugs(22, 3, HERE << "NO because Surrogate-Control:no-store"); +- return 0; +- } ++ if (surrogateNoStore) ++ return decision.make(ReuseDecision::reuseNot, "Surrogate-Control:no-store"); + + // RFC 2616: HTTP/1.1 Cache-Control conditions + if (!ignoreCacheControl) { +@@ -363,11 +361,10 @@ + // for now we are not reliably doing that so we waste CPU re-checking request CC + + // RFC 2616 section 14.9.2 - MUST NOT cache any response with request CC:no-store +- if (request && request->cache_control && request->cache_control->noStore() && +- !REFRESH_OVERRIDE(ignore_no_store)) { +- debugs(22, 3, HERE << "NO because client request Cache-Control:no-store"); +- return 0; +- } ++ if (request && request->cache_control && request->cache_control->hasNoStore() && ++ !REFRESH_OVERRIDE(ignore_no_store)) ++ return decision.make(ReuseDecision::reuseNot, ++ "client request Cache-Control:no-store"); + + // NP: request CC:no-cache only means cache READ is forbidden. STORE is permitted. + if (rep->cache_control && rep->cache_control->hasNoCache() && rep->cache_control->noCache().size() > 0) { +@@ -376,19 +373,18 @@ + * successfully (ie, must revalidate AND these headers are prohibited on stale replies). + * That is a bit tricky for squid right now so we avoid caching entirely. + */ +- debugs(22, 3, HERE << "NO because server reply Cache-Control:no-cache has parameters"); +- return 0; ++ return decision.make(ReuseDecision::reuseNot, ++ "server reply Cache-Control:no-cache has parameters"); + } + + // NP: request CC:private is undefined. We ignore. + // NP: other request CC flags are limiters on HIT/MISS. We don't care about here. + + // RFC 2616 section 14.9.2 - MUST NOT cache any response with CC:no-store +- if (rep->cache_control && rep->cache_control->noStore() && +- !REFRESH_OVERRIDE(ignore_no_store)) { +- debugs(22, 3, HERE << "NO because server reply Cache-Control:no-store"); +- return 0; +- } ++ if (rep->cache_control && rep->cache_control->hasNoStore() && ++ !REFRESH_OVERRIDE(ignore_no_store)) ++ return decision.make(ReuseDecision::reuseNot, ++ "server reply Cache-Control:no-store"); + + // RFC 2616 section 14.9.1 - MUST NOT cache any response with CC:private in a shared cache like Squid. + // CC:private overrides CC:public when both are present in a response. +@@ -401,27 +397,25 @@ + * successfully (ie, must revalidate AND these headers are prohibited on stale replies). + * That is a bit tricky for squid right now so we avoid caching entirely. + */ +- debugs(22, 3, HERE << "NO because server reply Cache-Control:private"); +- return 0; ++ return decision.make(ReuseDecision::reuseNot, ++ "server reply Cache-Control:private"); + } + } + + // RFC 2068, sec 14.9.4 - MUST NOT cache any response with Authentication UNLESS certain CC controls are present + // allow HTTP violations to IGNORE those controls (ie re-block caching Auth) + if (request && (request->flags.auth || request->flags.authSent) && !REFRESH_OVERRIDE(ignore_auth)) { +- if (!rep->cache_control) { +- debugs(22, 3, HERE << "NO because Authenticated and server reply missing Cache-Control"); +- return 0; +- } ++ if (!rep->cache_control) ++ return decision.make(ReuseDecision::reuseNot, ++ "authenticated and server reply missing Cache-Control"); + +- if (ignoreCacheControl) { +- debugs(22, 3, HERE << "NO because Authenticated and ignoring Cache-Control"); +- return 0; +- } ++ if (ignoreCacheControl) ++ return decision.make(ReuseDecision::reuseNot, ++ "authenticated and ignoring Cache-Control"); + + bool mayStore = false; + // HTTPbis pt6 section 3.2: a response CC:public is present +- if (rep->cache_control->Public()) { ++ if (rep->cache_control->hasPublic()) { + debugs(22, 3, HERE << "Authenticated but server reply Cache-Control:public"); + mayStore = true; + +@@ -441,15 +435,13 @@ + #endif + + // HTTPbis pt6 section 3.2: a response CC:s-maxage is present +- } else if (rep->cache_control->sMaxAge()) { ++ } else if (rep->cache_control->hasSMaxAge()) { + debugs(22, 3, HERE << "Authenticated but server reply Cache-Control:s-maxage"); + mayStore = true; + } + +- if (!mayStore) { +- debugs(22, 3, HERE << "NO because Authenticated transaction"); +- return 0; +- } ++ if (!mayStore) ++ return decision.make(ReuseDecision::reuseNot, "authenticated transaction"); + + // NP: response CC:no-cache is equivalent to CC:must-revalidate,max-age=0. We MAY cache, and do so. + // NP: other request CC flags are limiters on HIT/MISS/REFRESH. We don't care about here. +@@ -460,12 +452,26 @@ + * probably should not be cachable + */ + if ((v = hdr->getStr(HDR_CONTENT_TYPE))) +- if (!strncasecmp(v, "multipart/x-mixed-replace", 25)) { +- debugs(22, 3, HERE << "NO because Content-Type:multipart/x-mixed-replace"); +- return 0; +- } ++ if (!strncasecmp(v, "multipart/x-mixed-replace", 25)) ++ return decision.make(ReuseDecision::reuseNot, "Content-Type:multipart/x-mixed-replace"); ++ ++ // TODO: if possible, provide more specific message for each status code ++ static const char *shareableError = "shareable error status code"; ++ static const char *nonShareableError = "non-shareable error status code"; ++ ReuseDecision::Answers statusAnswer = ReuseDecision::reuseNot; ++ const char *statusReason = nonShareableError; + + switch (rep->sline.status()) { ++ ++ /* There are several situations when a non-cacheable response may be ++ * still shareable (e.g., among collapsed clients). We assume that these ++ * are 3xx and 5xx responses, indicating server problems and some of ++ * 4xx responses, common for all clients with a given cache key (e.g., ++ * 404 Not Found or 414 URI Too Long). On the other hand, we should not ++ * share non-cacheable client-specific errors, such as 400 Bad Request ++ * or 406 Not Acceptable. ++ */ ++ + /* Responses that are cacheable */ + + case Http::scOkay: +@@ -482,112 +488,90 @@ + * Don't cache objects that need to be refreshed on next request, + * unless we know how to refresh it. + */ ++ if (refreshIsCachable(entry) || REFRESH_OVERRIDE(store_stale)) ++ decision.make(ReuseDecision::cachePositively, "refresh check returned cacheable"); ++ else ++ decision.make(ReuseDecision::doNotCacheButShare, "refresh check returned non-cacheable"); + +- if (!refreshIsCachable(entry) && !REFRESH_OVERRIDE(store_stale)) { +- debugs(22, 3, "NO because refreshIsCachable() returned non-cacheable.."); +- return 0; +- } else { +- debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status()); +- return 1; +- } +- /* NOTREACHED */ + break; + + /* Responses that only are cacheable if the server says so */ + + case Http::scFound: + case Http::scTemporaryRedirect: +- if (rep->date <= 0) { +- debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status() << " and Date missing/invalid"); +- return 0; +- } +- if (rep->expires > rep->date) { +- debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status() << " and Expires > Date"); +- return 1; +- } else { +- debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status() << " and Expires <= Date"); +- return 0; +- } +- /* NOTREACHED */ ++ ++ if (rep->date <= 0) ++ decision.make(ReuseDecision::doNotCacheButShare, "Date is missing/invalid"); ++ else if (rep->expires > rep->date) ++ decision.make(ReuseDecision::cachePositively, "Expires > Date"); ++ else ++ decision.make(ReuseDecision::doNotCacheButShare, "Expires <= Date"); + break; + +- /* Errors can be negatively cached */ +- ++ /* These responses can be negatively cached. Most can also be shared. */ + case Http::scNoContent: +- + case Http::scUseProxy: +- +- case Http::scBadRequest: +- + case Http::scForbidden: +- + case Http::scNotFound: +- + case Http::scMethodNotAllowed: +- + case Http::scUriTooLong: +- + case Http::scInternalServerError: +- + case Http::scNotImplemented: +- + case Http::scBadGateway: +- + case Http::scServiceUnavailable: +- + case Http::scGatewayTimeout: + case Http::scMisdirectedRequest: +- +- debugs(22, 3, "MAYBE because HTTP status " << rep->sline.status()); +- return -1; +- +- /* NOTREACHED */ ++ statusAnswer = ReuseDecision::doNotCacheButShare; ++ statusReason = shareableError; ++ // fall through to the actual decision making below ++ ++ case Http::scBadRequest: // no sharing; perhaps the server did not like something specific to this request ++ ++#if USE_HTTP_VIOLATIONS ++ if (Config.negativeTtl > 0) ++ decision.make(ReuseDecision::cacheNegatively, "Config.negativeTtl > 0"); ++ else ++#endif ++ decision.make(statusAnswer, statusReason); + break; + +- /* Some responses can never be cached */ +- +- case Http::scPartialContent: /* Not yet supported */ +- ++ /* these responses can never be cached, some ++ of them can be shared though */ + case Http::scSeeOther: +- + case Http::scNotModified: +- + case Http::scUnauthorized: +- + case Http::scProxyAuthenticationRequired: +- +- case Http::scInvalidHeader: /* Squid header parsing error */ +- +- case Http::scHeaderTooLarge: +- + case Http::scPaymentRequired: ++ case Http::scInsufficientStorage: ++ // TODO: use more specific reason for non-error status codes ++ decision.make(ReuseDecision::doNotCacheButShare, shareableError); ++ break; ++ ++ case Http::scPartialContent: /* Not yet supported. TODO: make shareable for suitable ranges */ + case Http::scNotAcceptable: +- case Http::scRequestTimeout: +- case Http::scConflict: ++ case Http::scRequestTimeout: // TODO: is this shareable? ++ case Http::scConflict: // TODO: is this shareable? + case Http::scLengthRequired: + case Http::scPreconditionFailed: + case Http::scPayloadTooLarge: + case Http::scUnsupportedMediaType: + case Http::scUnprocessableEntity: +- case Http::scLocked: ++ case Http::scLocked: // TODO: is this shareable? + case Http::scFailedDependency: +- case Http::scInsufficientStorage: + case Http::scRequestedRangeNotSatisfied: + case Http::scExpectationFailed: +- +- debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status()); +- return 0; +- ++ case Http::scInvalidHeader: /* Squid header parsing error */ ++ case Http::scHeaderTooLarge: ++ decision.make(ReuseDecision::reuseNot, nonShareableError); ++ break; + default: + /* RFC 2616 section 6.1.1: an unrecognized response MUST NOT be cached. */ +- debugs (11, 3, HERE << "NO because unknown HTTP status code " << rep->sline.status()); +- return 0; + +- /* NOTREACHED */ ++ decision.make(ReuseDecision::reuseNot, "unknown status code"); + break; + } + +- /* NOTREACHED */ ++ return decision.answer; + } + + /// assemble a variant key (vary-mark) from the given Vary header and HTTP request +@@ -898,11 +882,12 @@ + + Ctx ctx = ctx_enter(entry->mem_obj->urlXXX()); + HttpReply *rep = finalReply(); ++ const Http::StatusCode statusCode = rep->sline.status(); + + entry->timestampsSet(); + + /* Check if object is cacheable or not based on reply code */ +- debugs(11, 3, "HTTP CODE: " << rep->sline.status()); ++ debugs(11, 3, "HTTP CODE: " << statusCode); + + if (const StoreEntry *oldEntry = findPreviouslyCachedEntry(entry)) + sawDateGoBack = rep->olderThan(oldEntry->getReply()); +@@ -919,7 +904,9 @@ + const SBuf vary(httpMakeVaryMark(request, rep)); + + if (vary.isEmpty()) { +- entry->makePrivate(); ++ // TODO: check whether such responses are shareable. ++ // Do not share for now. ++ entry->makePrivate(false); + if (!fwd->reforwardableStatus(rep->sline.status())) + EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); + varyFailure = true; +@@ -942,30 +929,31 @@ + if (!fwd->reforwardableStatus(rep->sline.status())) + EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); + +- switch (cacheableReply()) { +- +- case 1: ++ ReuseDecision decision(entry, statusCode); ++ ++ switch (reusableReply(decision)) { ++ ++ case ReuseDecision::reuseNot: ++ entry->makePrivate(false); ++ break; ++ ++ case ReuseDecision::cachePositively: + entry->makePublic(); + break; + +- case 0: +- entry->makePrivate(); ++ case ReuseDecision::cacheNegatively: ++ entry->cacheNegatively(); + break; + +- case -1: +- +-#if USE_HTTP_VIOLATIONS +- if (Config.negativeTtl > 0) +- entry->cacheNegatively(); +- else +-#endif +- entry->makePrivate(); ++ case ReuseDecision::doNotCacheButShare: ++ entry->makePrivate(true); + break; + + default: + assert(0); + break; + } ++ debugs(11, 3, "decided: " << decision); + } + + if (!ignoreCacheControl) { +@@ -2429,3 +2417,29 @@ + mustStop(reason); + } + ++HttpStateData::ReuseDecision::ReuseDecision(const StoreEntry *e, const Http::StatusCode code) ++ : answer(HttpStateData::ReuseDecision::reuseNot), reason(nullptr), entry(e), statusCode(code) {} ++ ++HttpStateData::ReuseDecision::Answers ++HttpStateData::ReuseDecision::make(const HttpStateData::ReuseDecision::Answers ans, const char *why) ++{ ++ answer = ans; ++ reason = why; ++ return answer; ++} ++ ++std::ostream &operator <<(std::ostream &os, const HttpStateData::ReuseDecision &d) ++{ ++ static const char *ReuseMessages[] = { ++ "do not cache and do not share", // reuseNot ++ "cache positively and share", // cachePositively ++ "cache negatively and share", // cacheNegatively ++ "do not cache but share" // doNotCacheButShare ++ }; ++ ++ assert(d.answer >= HttpStateData::ReuseDecision::reuseNot && ++ d.answer <= HttpStateData::ReuseDecision::doNotCacheButShare); ++ return os << ReuseMessages[d.answer] << " because " << d.reason << ++ "; HTTP status " << d.statusCode << " " << *(d.entry); ++} ++ + +=== modified file 'src/http.h' +--- src/http.h 2017-01-01 00:16:45 +0000 ++++ src/http.h 2017-06-14 21:37:20 +0000 +@@ -22,6 +22,23 @@ + { + + public: ++ ++ /// assists in making and relaying entry caching/sharing decision ++ class ReuseDecision ++ { ++ public: ++ enum Answers { reuseNot = 0, cachePositively, cacheNegatively, doNotCacheButShare }; ++ ++ ReuseDecision(const StoreEntry *e, const Http::StatusCode code); ++ /// stores the corresponding decision ++ Answers make(const Answers ans, const char *why); ++ ++ Answers answer; ///< the decision id ++ const char *reason; ///< the decision reason ++ const StoreEntry *entry; ///< entry for debugging ++ const Http::StatusCode statusCode; ///< HTTP status for debugging ++ }; ++ + HttpStateData(FwdState *); + ~HttpStateData(); + +@@ -39,8 +56,8 @@ + void readReply(const CommIoCbParams &io); + virtual void maybeReadVirginBody(); // read response data from the network + +- // Determine whether the response is a cacheable representation +- int cacheableReply(); ++ // Checks whether the response is cacheable/shareable. ++ ReuseDecision::Answers reusableReply(ReuseDecision &decision); + + CachePeer *_peer; /* CachePeer request made to */ + int eof; /* reached end-of-object? */ +@@ -119,6 +136,8 @@ + CBDATA_CLASS2(HttpStateData); + }; + ++std::ostream &operator <<(std::ostream &os, const HttpStateData::ReuseDecision &d); ++ + int httpCachable(const HttpRequestMethod&); + void httpStart(FwdState *); + SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply); + +=== modified file 'src/store.cc' +--- src/store.cc 2017-01-01 00:16:45 +0000 ++++ src/store.cc 2017-06-14 21:37:20 +0000 +@@ -171,11 +171,18 @@ + } + + void +-StoreEntry::makePrivate() ++StoreEntry::makePrivate(const bool shareable) + { + /* This object should never be cached at all */ + expireNow(); +- releaseRequest(); /* delete object when not used */ ++ releaseRequest(shareable); /* delete object when not used */ ++} ++ ++void ++StoreEntry::clearPrivate() ++{ ++ EBIT_CLR(flags, KEY_PRIVATE); ++ shareableWhenPrivate = false; + } + + void +@@ -365,7 +372,8 @@ + ping_status(PING_NONE), + store_status(STORE_PENDING), + swap_status(SWAPOUT_NONE), +- lock_count(0) ++ lock_count(0), ++ shareableWhenPrivate(false) + { + debugs(20, 5, "StoreEntry constructed, this=" << this); + } +@@ -504,14 +512,14 @@ + } + + void +-StoreEntry::releaseRequest() ++StoreEntry::releaseRequest(const bool shareable) + { + if (EBIT_TEST(flags, RELEASE_REQUEST)) + return; + + setReleaseFlag(); // makes validToSend() false, preventing future hits + +- setPrivateKey(); ++ setPrivateKey(shareable); + } + + int +@@ -623,12 +631,16 @@ + * concept'. + */ + void +-StoreEntry::setPrivateKey() ++StoreEntry::setPrivateKey(const bool shareable) + { + const cache_key *newkey; + +- if (key && EBIT_TEST(flags, KEY_PRIVATE)) +- return; /* is already private */ ++ if (key && EBIT_TEST(flags, KEY_PRIVATE)) { ++ // The entry is already private, but it may be still shareable. ++ if (!shareable) ++ shareableWhenPrivate = false; ++ return; ++ } + + if (key) { + setReleaseFlag(); // will markForUnlink(); all caches/workers will know +@@ -649,6 +661,7 @@ + + assert(hash_lookup(store_table, newkey) == NULL); + EBIT_SET(flags, KEY_PRIVATE); ++ shareableWhenPrivate = shareable; + hashInsert(newkey); + } + +@@ -705,14 +718,17 @@ + if (StoreEntry *e2 = (StoreEntry *)hash_lookup(store_table, newkey)) { + assert(e2 != this); + debugs(20, 3, "Making old " << *e2 << " private."); +- e2->setPrivateKey(); +- e2->release(); ++ ++ // TODO: check whether there is any sense in keeping old entry ++ // shareable here. Leaving it non-shareable for now. ++ e2->setPrivateKey(false); ++ e2->release(false); + } + + if (key) + hashDelete(); + +- EBIT_CLR(flags, KEY_PRIVATE); ++ clearPrivate(); + + hashInsert(newkey); + +@@ -830,7 +846,7 @@ + e->lock("storeCreateEntry"); + + if (neighbors_do_private_keys || !flags.hierarchical) +- e->setPrivateKey(); ++ e->setPrivateKey(false); + else + e->setPublicKey(); + +@@ -1264,7 +1280,7 @@ + + /* release an object from a cache */ + void +-StoreEntry::release() ++StoreEntry::release(const bool shareable) + { + PROF_start(storeRelease); + debugs(20, 3, "releasing " << *this << ' ' << getMD5Text()); +@@ -1274,7 +1290,7 @@ + if (locked()) { + expireNow(); + debugs(20, 3, "storeRelease: Only setting RELEASE_REQUEST bit"); +- releaseRequest(); ++ releaseRequest(shareable); + PROF_stop(storeRelease); + return; + } +@@ -1282,7 +1298,7 @@ + Store::Root().memoryUnlink(*this); + + if (StoreController::store_dirs_rebuilding && swap_filen > -1) { +- setPrivateKey(); ++ setPrivateKey(shareable); + + if (swap_filen > -1) { + // lock the entry until rebuilding is done +@@ -2181,7 +2197,11 @@ + if (EBIT_TEST(e.flags, REFRESH_REQUEST)) os << 'F'; + if (EBIT_TEST(e.flags, ENTRY_REVALIDATE_STALE)) os << 'E'; + if (EBIT_TEST(e.flags, ENTRY_DISPATCHED)) os << 'D'; +- if (EBIT_TEST(e.flags, KEY_PRIVATE)) os << 'I'; ++ if (EBIT_TEST(e.flags, KEY_PRIVATE)) { ++ os << 'I'; ++ if (e.shareableWhenPrivate) ++ os << 'H'; ++ } + if (EBIT_TEST(e.flags, ENTRY_FWD_HDR_WAIT)) os << 'W'; + if (EBIT_TEST(e.flags, ENTRY_NEGCACHED)) os << 'N'; + if (EBIT_TEST(e.flags, ENTRY_VALIDATED)) os << 'V'; + +=== modified file 'src/tests/stub_store.cc' +--- src/tests/stub_store.cc 2017-01-01 00:16:45 +0000 ++++ src/tests/stub_store.cc 2017-06-14 21:37:20 +0000 +@@ -43,11 +43,11 @@ + void StoreEntry::abort() STUB + void StoreEntry::unlink() STUB + void StoreEntry::makePublic(const KeyScope keyScope) STUB +-void StoreEntry::makePrivate() STUB ++void StoreEntry::makePrivate(const bool shareable) STUB + void StoreEntry::setPublicKey(const KeyScope keyScope) STUB +-void StoreEntry::setPrivateKey() STUB ++void StoreEntry::setPrivateKey(const bool shareable) STUB + void StoreEntry::expireNow() STUB +-void StoreEntry::releaseRequest() STUB ++void StoreEntry::releaseRequest(const bool shareable) STUB + void StoreEntry::negativeCache() STUB + void StoreEntry::cacheNegatively() STUB + void StoreEntry::purgeMem() STUB +@@ -99,7 +99,7 @@ + int64_t StoreEntry::contentLen() const STUB_RETVAL(0) + void StoreEntry::lock(const char *) STUB + void StoreEntry::touch() STUB +-void StoreEntry::release() STUB ++void StoreEntry::release(const bool shareable) STUB + + NullStoreEntry *NullStoreEntry::getInstance() STUB_RETVAL(NULL) + const char *NullStoreEntry::getMD5Text() const STUB_RETVAL(NULL) + +=== modified file 'src/tests/testStoreController.cc' +--- src/tests/testStoreController.cc 2017-01-01 00:16:45 +0000 ++++ src/tests/testStoreController.cc 2017-06-14 21:37:20 +0000 +@@ -116,7 +116,7 @@ + e->lastModified(squid_curtime); + e->refcount = 1; + EBIT_CLR(e->flags, RELEASE_REQUEST); +- EBIT_CLR(e->flags, KEY_PRIVATE); ++ e->clearPrivate(); + e->ping_status = PING_NONE; + EBIT_CLR(e->flags, ENTRY_VALIDATED); + e->hashInsert((const cache_key *)name.termedBuf()); /* do it after we clear KEY_PRIVATE */ + +=== modified file 'src/tests/testStoreHashIndex.cc' +--- src/tests/testStoreHashIndex.cc 2017-01-01 00:16:45 +0000 ++++ src/tests/testStoreHashIndex.cc 2017-06-14 21:37:20 +0000 +@@ -97,7 +97,7 @@ + e->lastModified(squid_curtime); + e->refcount = 1; + EBIT_CLR(e->flags, RELEASE_REQUEST); +- EBIT_CLR(e->flags, KEY_PRIVATE); ++ e->clearPrivate(); + e->ping_status = PING_NONE; + EBIT_CLR(e->flags, ENTRY_VALIDATED); + e->hashInsert((const cache_key *)name.termedBuf()); /* do it after we clear KEY_PRIVATE */ + diff --git a/src/patches/squid/squid-3.5-14170.patch b/src/patches/squid/squid-3.5-14170.patch new file mode 100644 index 0000000..cea0f13 --- /dev/null +++ b/src/patches/squid/squid-3.5-14170.patch @@ -0,0 +1,85 @@ +------------------------------------------------------------ +revno: 14170 +revision-id: squid3@treenet.co.nz-20170614215906-ly36sobvlr2pt0u6 +parent: squid3@treenet.co.nz-20170614213720-3qmiohlx4zr2jnqq +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=2833 +author: Eduard Bagdasaryan eduard.bagdasaryan@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Thu 2017-06-15 09:59:06 +1200 +message: + Bug 2833 pt3: Do not respond with HTTP/304 to unconditional requests + + ... after internal revalidation. The original unconditional HttpRequest + was still marked (and processed) as conditional after internal + revalidation because the original (clear) Last-Modified and ETag values + were not restored (cleared) after the internal revalidation abused them. + + TODO: Isolate the code converting the request into conditional one _and_ + the code that undoes that conversion, to keep both actions in sync. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170614215906-ly36sobvlr2pt0u6 +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 0991e2d39b3bcebcf18cba3db0e3b57aabf23b8b +# timestamp: 2017-06-14 22:22:43 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170614213720-\ +# 3qmiohlx4zr2jnqq +# +# Begin patch +=== modified file 'src/client_side_reply.cc' +--- src/client_side_reply.cc 2017-06-14 21:37:20 +0000 ++++ src/client_side_reply.cc 2017-06-14 21:59:06 +0000 +@@ -72,8 +72,8 @@ + HTTPMSGUNLOCK(reply); + } + +-clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) : http (cbdataReference(clientContext)), old_entry (NULL), old_sc(NULL), deleting(false), +- collapsedRevalidation(crNone) ++clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) : http (cbdataReference(clientContext)), old_entry (NULL), ++ old_sc(NULL), old_lastmod(-1), deleting(false), collapsedRevalidation(crNone) + {} + + /** Create an error in the store awaiting the client side to read it. +@@ -185,6 +185,8 @@ + debugs(88, 3, "clientReplyContext::saveState: saving store context"); + old_entry = http->storeEntry(); + old_sc = sc; ++ old_lastmod = http->request->lastmod; ++ old_etag = http->request->etag; + old_reqsize = reqsize; + tempBuffer.offset = reqofs; + /* Prevent accessing the now saved entries */ +@@ -204,9 +206,13 @@ + sc = old_sc; + reqsize = old_reqsize; + reqofs = tempBuffer.offset; ++ http->request->lastmod = old_lastmod; ++ http->request->etag = old_etag; + /* Prevent accessed the old saved entries */ + old_entry = NULL; + old_sc = NULL; ++ old_lastmod = -1; ++ old_etag.clean(); + old_reqsize = 0; + tempBuffer.offset = 0; + } + +=== modified file 'src/client_side_reply.h' +--- src/client_side_reply.h 2017-01-01 00:16:45 +0000 ++++ src/client_side_reply.h 2017-06-14 21:59:06 +0000 +@@ -130,7 +130,11 @@ + void sendNotModifiedOrPreconditionFailedError(); + + StoreEntry *old_entry; +- store_client *old_sc; /* ... for entry to be validated */ ++ /* ... for entry to be validated */ ++ store_client *old_sc; ++ time_t old_lastmod; ++ String old_etag; ++ + bool deleting; + + typedef enum { + diff --git a/src/patches/squid/squid-3.5-14171.patch b/src/patches/squid/squid-3.5-14171.patch new file mode 100644 index 0000000..f357045 --- /dev/null +++ b/src/patches/squid/squid-3.5-14171.patch @@ -0,0 +1,45 @@ +------------------------------------------------------------ +revno: 14171 +revision-id: squidadm@squid-cache.org-20170615001633-wgrl5w8isv15o7gg +parent: squid3@treenet.co.nz-20170614215906-ly36sobvlr2pt0u6 +committer: Source Maintenance squidadm@squid-cache.org +branch nick: 3.5 +timestamp: Thu 2017-06-15 00:16:33 +0000 +message: + SourceFormat Enforcement +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squidadm@squid-cache.org-20170615001633-\ +# wgrl5w8isv15o7gg +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 237182ac5eed6aca7e9aca295a90057f3a8cf10b +# timestamp: 2017-06-15 00:51:05 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170614215906-\ +# ly36sobvlr2pt0u6 +# +# Begin patch +=== modified file 'src/http.cc' +--- src/http.cc 2017-06-14 21:37:20 +0000 ++++ src/http.cc 2017-06-15 00:16:33 +0000 +@@ -523,7 +523,7 @@ + case Http::scMisdirectedRequest: + statusAnswer = ReuseDecision::doNotCacheButShare; + statusReason = shareableError; +- // fall through to the actual decision making below ++ // fall through to the actual decision making below + + case Http::scBadRequest: // no sharing; perhaps the server did not like something specific to this request + +@@ -2438,8 +2438,8 @@ + }; + + assert(d.answer >= HttpStateData::ReuseDecision::reuseNot && +- d.answer <= HttpStateData::ReuseDecision::doNotCacheButShare); ++ d.answer <= HttpStateData::ReuseDecision::doNotCacheButShare); + return os << ReuseMessages[d.answer] << " because " << d.reason << +- "; HTTP status " << d.statusCode << " " << *(d.entry); ++ "; HTTP status " << d.statusCode << " " << *(d.entry); + } + + diff --git a/src/patches/squid/squid-3.5-14172.patch b/src/patches/squid/squid-3.5-14172.patch new file mode 100644 index 0000000..aa73327 --- /dev/null +++ b/src/patches/squid/squid-3.5-14172.patch @@ -0,0 +1,40 @@ +------------------------------------------------------------ +revno: 14172 +revision-id: squid3@treenet.co.nz-20170621195439-l63xfsad58ghhhfu +parent: squidadm@squid-cache.org-20170615001633-wgrl5w8isv15o7gg +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4671 +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Thu 2017-06-22 07:54:39 +1200 +message: + Bug 4671 pt2: GCC 7: raise FTP Gateway CTRL channel buffer to 16KB + + Fixes + error: %s directive output may be truncated writing up to 8191 bytes + into a region of size 1019 + note: snprintf output between 8 and 8199 bytes into a destination of + size 1024 +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170621195439-l63xfsad58ghhhfu +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: eeb32b45efe5504eebeaae89088d4a81d807807c +# timestamp: 2017-06-21 20:50:58 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squidadm@squid-cache.org-20170615001633-\ +# wgrl5w8isv15o7gg +# +# Begin patch +=== modified file 'src/clients/FtpGateway.cc' +--- src/clients/FtpGateway.cc 2017-05-29 04:37:41 +0000 ++++ src/clients/FtpGateway.cc 2017-06-21 19:54:39 +0000 +@@ -192,7 +192,7 @@ + + #define FTP_LOGIN_NOT_ESCAPED 0 + +-#define CTRL_BUFLEN 1024 ++#define CTRL_BUFLEN 16*1024 + static char cbuf[CTRL_BUFLEN]; + + /* + diff --git a/src/patches/squid/squid-3.5-14173.patch b/src/patches/squid/squid-3.5-14173.patch new file mode 100644 index 0000000..6841202 --- /dev/null +++ b/src/patches/squid/squid-3.5-14173.patch @@ -0,0 +1,254 @@ +------------------------------------------------------------ +revno: 14173 +revision-id: squid3@treenet.co.nz-20170621201248-ezpvykg0b307ix61 +parent: squid3@treenet.co.nz-20170621195439-l63xfsad58ghhhfu +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4671 +author: Alex Rousskov rousskov@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Thu 2017-06-22 08:12:48 +1200 +message: + Replace new/delete operators using modern C++ rules. + + This change was motivated by "Mismatched free()/delete/delete[]" errors + reported by valgrind and mused about in Squid source code. + + I speculate that the old new/delete replacement code was the result of + slow accumulation of working hacks to accomodate various environments, + as compiler support for the feature evolved. The cumulative result does + not actually work well (see the above paragraph), and the replacement + functions had the following visible coding problems according to [1,2]: + + a) Declared with non-standard profiles that included throw specifiers. + b) Declared inline. C++ says that the results of inline declarations + have unspecified effects. In Squid, they probably necessitated + complex compiler-specific "extern inline" workarounds. + c) Defined in the header file. C++ says that defining replacements "in + any source file" is enough and that multiple replacements per + program (which is what a header file definition produces) result in + "undefined behavior". + d) Declared inconsistently (only 2 out of 4 flavors). Declaring one base + flavor should be sufficient, but if we declare more, we should + declare all of them. + + [1] http://en.cppreference.com/w/cpp/memory/new/operator_new + [2] http://en.cppreference.com/w/cpp/memory/new/operator_delete + + The replacements were not provided to clang (trunk r13219), but there + was no explanation why. This patch does not change that exclusion. + + I have no idea whether any of the old hacks are still necessary in some + cases. However, I suspect that either we do not care much if the + replacements are not enabled on some poorly supported platforms OR we + can disable them (or make them work) using much simpler hacks for the + platforms we do care about. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170621201248-ezpvykg0b307ix61 +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 4f15c23326e4e4fe2ca2a6c7a13333e01677a0b0 +# timestamp: 2017-06-21 20:51:02 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170621195439-\ +# l63xfsad58ghhhfu +# +# Begin patch +=== modified file 'compat/os/macosx.h' +--- compat/os/macosx.h 2017-01-01 00:16:45 +0000 ++++ compat/os/macosx.h 2017-06-21 20:12:48 +0000 +@@ -28,11 +28,6 @@ + + #include "compat/cmsg.h" + +-// MacOS GCC 4.0.1 and 4.2.1 supply __GNUC_GNU_INLINE__ but do not actually define __attribute__((gnu_inline)) +-#if defined(__cplusplus) && !defined(_SQUID_EXTERNNEW_) +-#define _SQUID_EXTERNNEW_ extern inline +-#endif +- + #endif /* _SQUID_APPLE_ */ + #endif /* SQUID_OS_MACOSX_H */ + + +=== modified file 'compat/os/sgi.h' +--- compat/os/sgi.h 2017-01-01 00:16:45 +0000 ++++ compat/os/sgi.h 2017-06-21 20:12:48 +0000 +@@ -25,15 +25,6 @@ + #define _ABI_SOURCE + #endif /* USE_ASYNC_IO */ + +-#if defined(__cplusplus) && !defined(_SQUID_EXTERNNEW_) && !defined(_GNUC_) +-/* +- * The gcc compiler treats extern inline functions as being extern, +- * while the SGI MIPSpro compilers treat them as inline. To get equivalent +- * behavior, remove the inline keyword. +- */ +-#define _SQUID_EXTERNNEW_ extern +-#endif +- + #endif /* _SQUID_SGI_ */ + #endif /* SQUID_OS_SGI_H */ + + +=== modified file 'compat/os/solaris.h' +--- compat/os/solaris.h 2017-01-01 00:16:45 +0000 ++++ compat/os/solaris.h 2017-06-21 20:12:48 +0000 +@@ -59,13 +59,6 @@ + #endif + + /* +- * SunPro CC handles extern inline as inline, PLUS extern symbols. +- */ +-#if !defined(_SQUID_EXTERNNEW_) && defined(__SUNPRO_CC) +-#define _SQUID_EXTERNNEW_ extern +-#endif +- +-/* + * SunStudio CC does not define C++ portability API __FUNCTION__ + */ + #if defined(__SUNPRO_CC) && !defined(__FUNCTION__) + +=== removed file 'include/SquidNew.h' +--- include/SquidNew.h 2017-01-01 00:16:45 +0000 ++++ include/SquidNew.h 1970-01-01 00:00:00 +0000 +@@ -1,41 +0,0 @@ +-/* +- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors +- * +- * Squid software is distributed under GPLv2+ license and includes +- * contributions from numerous individuals and organizations. +- * Please see the COPYING and CONTRIBUTORS files for details. +- */ +- +-#ifndef SQUID_NEW_H +-#define SQUID_NEW_H +- +-#if !defined(__SUNPRO_CC) && !defined(__clang__) +-/* Any code using libstdc++ must have externally resolvable overloads +- * for void * operator new - which means in the .o for the binary, +- * or in a shared library. static libs don't propogate the symbol +- * so, look in the translation unit containing main() in squid +- * for the extern version in squid +- */ +-#include <new> +- +-_SQUID_EXTERNNEW_ void *operator new(size_t size) throw (std::bad_alloc) +-{ +- return xmalloc(size); +-} +-_SQUID_EXTERNNEW_ void operator delete (void *address) throw() +-{ +- xfree(address); +-} +-_SQUID_EXTERNNEW_ void *operator new[] (size_t size) throw (std::bad_alloc) +-{ +- return xmalloc(size); +-} +-_SQUID_EXTERNNEW_ void operator delete[] (void *address) throw() +-{ +- xfree(address); +-} +- +-#endif /* !__SUNPRO_CC && !__clang__*/ +- +-#endif /* SQUID_NEW_H */ +- + +=== modified file 'include/util.h' +--- include/util.h 2017-01-01 00:16:45 +0000 ++++ include/util.h 2017-06-21 20:12:48 +0000 +@@ -19,23 +19,6 @@ + SQUIDCEXTERN int tvSubUsec(struct timeval, struct timeval); + SQUIDCEXTERN double tvSubDsec(struct timeval, struct timeval); + SQUIDCEXTERN void Tolower(char *); +-#if defined(__cplusplus) +-/* +- * Any code using libstdc++ must have externally resolvable overloads +- * for void * operator new - which means in the .o for the binary, +- * or in a shared library. static libs don't propogate the symbol +- * so, look in the translation unit containing main() in squid +- * for the extern version in squid +- */ +-#if !defined(_SQUID_EXTERNNEW_) +-#if defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) +-#define _SQUID_EXTERNNEW_ extern inline __attribute__((gnu_inline)) +-#else +-#define _SQUID_EXTERNNEW_ extern inline +-#endif +-#endif +-#include "SquidNew.h" +-#endif + + SQUIDCEXTERN time_t parse_iso3307_time(const char *buf); + + +=== modified file 'src/SquidNew.cc' +--- src/SquidNew.cc 2017-01-01 00:16:45 +0000 ++++ src/SquidNew.cc 2017-06-21 20:12:48 +0000 +@@ -8,29 +8,45 @@ + + /* DEBUG: none Memory Allocation */ + +-#define _SQUID_EXTERNNEW_ +- + #include "squid.h" + +-#ifdef __SUNPRO_CC ++#if !defined(__clang__) + + #include <new> +-void *operator new(size_t size) throw (std::bad_alloc) +-{ +- return xmalloc(size); +-} +-void operator delete (void *address) throw() +-{ +- xfree (address); +-} +-void *operator new[] (size_t size) throw (std::bad_alloc) +-{ +- return xmalloc(size); +-} +-void operator delete[] (void *address) throw() +-{ +- xfree (address); +-} +- +-#endif /* __SUNPRO_CC */ ++ ++void *operator new(size_t size) ++{ ++ return xmalloc(size); ++} ++void operator delete(void *address) ++{ ++ xfree(address); ++} ++void *operator new[](size_t size) ++{ ++ return xmalloc(size); ++} ++void operator delete[](void *address) ++{ ++ xfree(address); ++} ++ ++void *operator new(size_t size, const std::nothrow_t &tag) ++{ ++ return xmalloc(size); ++} ++void operator delete(void *address, const std::nothrow_t &tag) ++{ ++ xfree(address); ++} ++void *operator new[](size_t size, const std::nothrow_t &tag) ++{ ++ return xmalloc(size); ++} ++void operator delete[](void *address, const std::nothrow_t &tag) ++{ ++ xfree(address); ++} ++ ++#endif /* !defined(__clang__) */ + + diff --git a/src/patches/squid/squid-3.5-14174.patch b/src/patches/squid/squid-3.5-14174.patch new file mode 100644 index 0000000..7427eb3 --- /dev/null +++ b/src/patches/squid/squid-3.5-14174.patch @@ -0,0 +1,274 @@ +------------------------------------------------------------ +revno: 14174 +revision-id: squid3@treenet.co.nz-20170622153146-nxo8vl6a9r8z03v4 +parent: squid3@treenet.co.nz-20170621201248-ezpvykg0b307ix61 +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4671 +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Fri 2017-06-23 03:31:46 +1200 +message: + Bug 4671 pt3: various GCC 7 compile errors + + Also, remove limit on FTP realm strings + + Convert ftpRealm() from generating char* to SBuf. This fixes issues identified + by GCC 7 where the realm string may be longer than the available buffer and + gets truncated. + The size of the buffer was making the occurance rather rare, but it is still + possible. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170622153146-nxo8vl6a9r8z03v4 +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: b54e1a339544443ed9b34a094717b2781c746c76 +# timestamp: 2017-06-22 15:50:59 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170621201248-\ +# ezpvykg0b307ix61 +# +# Begin patch +=== modified file 'src/DiskIO/DiskThreads/aiops.cc' +--- src/DiskIO/DiskThreads/aiops.cc 2017-01-01 00:16:45 +0000 ++++ src/DiskIO/DiskThreads/aiops.cc 2017-06-22 15:31:46 +0000 +@@ -290,7 +290,7 @@ + /* Create threads and get them to sit in their wait loop */ + squidaio_thread_pool = memPoolCreate("aio_thread", sizeof(squidaio_thread_t)); + +- assert(NUMTHREADS); ++ assert(NUMTHREADS != 0); + + for (i = 0; i < NUMTHREADS; ++i) { + threadp = (squidaio_thread_t *)squidaio_thread_pool->alloc(); + +=== modified file 'src/clients/FtpGateway.cc' +--- src/clients/FtpGateway.cc 2017-06-21 19:54:39 +0000 ++++ src/clients/FtpGateway.cc 2017-06-22 15:31:46 +0000 +@@ -153,8 +153,8 @@ + virtual void timeout(const CommTimeoutCbParams &io); + void ftpAcceptDataConnection(const CommAcceptCbParams &io); + +- static HttpReply *ftpAuthRequired(HttpRequest * request, const char *realm); +- const char *ftpRealm(void); ++ static HttpReply *ftpAuthRequired(HttpRequest * request, SBuf &realm); ++ SBuf ftpRealm(); + void loginFailed(void); + + virtual void haveParsedReplyHeaders(); +@@ -1189,7 +1189,8 @@ + { + if (!checkAuth(&request->header)) { + /* create appropriate reply */ +- HttpReply *reply = ftpAuthRequired(request, ftpRealm()); ++ SBuf realm(ftpRealm()); // local copy so SBuf wont disappear too early ++ HttpReply *reply = ftpAuthRequired(request, realm); + entry->replaceHttpReply(reply); + serverComplete(); + return; +@@ -1290,7 +1291,9 @@ + + #if HAVE_AUTH_MODULE_BASIC + /* add Authenticate header */ +- newrep->header.putAuth("Basic", ftpRealm()); ++ // XXX: performance regression. c_str() may reallocate ++ SBuf realm(ftpRealm()); // local copy so SBuf wont disappear too early ++ newrep->header.putAuth("Basic", realm.c_str()); + #endif + + // add it to the store entry for response.... +@@ -1298,18 +1301,19 @@ + serverComplete(); + } + +-const char * ++SBuf + Ftp::Gateway::ftpRealm() + { +- static char realm[8192]; ++ SBuf realm; + + /* This request is not fully authenticated */ +- if (!request) { +- snprintf(realm, 8192, "FTP %s unknown", user); +- } else if (request->port == 21) { +- snprintf(realm, 8192, "FTP %s %s", user, request->GetHost()); +- } else { +- snprintf(realm, 8192, "FTP %s %s port %d", user, request->GetHost(), request->port); ++ realm.appendf("FTP %s ", user); ++ if (!request) ++ realm.append("unknown", 7); ++ else { ++ realm.append(request->GetHost()); ++ if (request->port != 21) ++ realm.appendf(" port %d", request->port); + } + return realm; + } +@@ -2673,13 +2677,14 @@ + } + + HttpReply * +-Ftp::Gateway::ftpAuthRequired(HttpRequest * request, const char *realm) ++Ftp::Gateway::ftpAuthRequired(HttpRequest * request, SBuf &realm) + { + ErrorState err(ERR_CACHE_ACCESS_DENIED, Http::scUnauthorized, request); + HttpReply *newrep = err.BuildHttpReply(); + #if HAVE_AUTH_MODULE_BASIC + /* add Authenticate header */ +- newrep->header.putAuth("Basic", realm); ++ // XXX: performance regression. c_str() may reallocate ++ newrep->header.putAuth("Basic", realm.c_str()); + #endif + return newrep; + } + +=== modified file 'src/fde.cc' +--- src/fde.cc 2017-01-01 00:16:45 +0000 ++++ src/fde.cc 2017-06-22 15:31:46 +0000 +@@ -85,15 +85,15 @@ + char const * + fde::remoteAddr() const + { +- LOCAL_ARRAY(char, buf, MAX_IPSTRLEN ); ++ static char buf[MAX_IPSTRLEN+7]; // 7 = length of ':port' strings + + if (type != FD_SOCKET) + return null_string; + + if ( *ipaddr ) +- snprintf( buf, MAX_IPSTRLEN, "%s:%d", ipaddr, (int)remote_port); ++ snprintf(buf, sizeof(buf), "%s:%u", ipaddr, remote_port); + else +- local_addr.toUrl(buf,MAX_IPSTRLEN); // toHostStr does not include port. ++ local_addr.toUrl(buf, sizeof(buf)); // toHostStr does not include port. + + return buf; + } + +=== modified file 'src/fs/ufs/RebuildState.cc' +--- src/fs/ufs/RebuildState.cc 2017-01-01 00:16:45 +0000 ++++ src/fs/ufs/RebuildState.cc 2017-06-22 15:31:46 +0000 +@@ -444,7 +444,7 @@ + } + + if (0 == in_dir) { /* we need to read in a new directory */ +- snprintf(fullpath, MAXPATHLEN, "%s/%02X/%02X", ++ snprintf(fullpath, sizeof(fullpath), "%s/%02X/%02X", + sd->path, + curlvl1, curlvl2); + +@@ -489,7 +489,7 @@ + continue; + } + +- snprintf(fullfilename, MAXPATHLEN, "%s/%s", ++ snprintf(fullfilename, sizeof(fullfilename), "%s/%s", + fullpath, entry->d_name); + debugs(47, 3, HERE << "Opening " << fullfilename); + fd = file_open(fullfilename, O_RDONLY | O_BINARY); + +=== modified file 'src/fs/ufs/RebuildState.h' +--- src/fs/ufs/RebuildState.h 2017-01-01 00:16:45 +0000 ++++ src/fs/ufs/RebuildState.h 2017-06-22 15:31:46 +0000 +@@ -54,7 +54,7 @@ + dirent_t *entry; + DIR *td; + char fullpath[MAXPATHLEN]; +- char fullfilename[MAXPATHLEN]; ++ char fullfilename[MAXPATHLEN*2]; + + StoreRebuildData counts; + + +=== modified file 'src/gopher.cc' +--- src/gopher.cc 2017-01-01 00:16:45 +0000 ++++ src/gopher.cc 2017-06-22 15:31:46 +0000 +@@ -820,7 +820,7 @@ + * This will be called when request write is complete. Schedule read of reply. + */ + static void +-gopherSendComplete(const Comm::ConnectionPointer &conn, char *buf, size_t size, Comm::Flag errflag, int xerrno, void *data) ++gopherSendComplete(const Comm::ConnectionPointer &conn, char *, size_t size, Comm::Flag errflag, int xerrno, void *data) + { + GopherStateData *gopherState = (GopherStateData *) data; + StoreEntry *entry = gopherState->entry; +@@ -840,10 +840,6 @@ + err->url = xstrdup(entry->url()); + gopherState->fwd->fail(err); + gopherState->serverConn->close(); +- +- if (buf) +- memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */ +- + return; + } + +@@ -885,9 +881,6 @@ + AsyncCall::Pointer call = commCbCall(5,5, "gopherReadReply", + CommIoCbPtrFun(gopherReadReply, gopherState)); + entry->delayAwareRead(conn, gopherState->replybuf, BUFSIZ, call); +- +- if (buf) +- memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */ + } + + /** +@@ -898,32 +891,31 @@ + gopherSendRequest(int fd, void *data) + { + GopherStateData *gopherState = (GopherStateData *)data; +- char *buf = (char *)memAllocate(MEM_4K_BUF); ++ MemBuf mb; ++ mb.init(); + + if (gopherState->type_id == GOPHER_CSO) { + const char *t = strchr(gopherState->request, '?'); + +- if (t != NULL) ++ if (t) + ++t; /* skip the ? */ + else + t = ""; + +- snprintf(buf, 4096, "query %s\r\nquit\r\n", t); +- } else if (gopherState->type_id == GOPHER_INDEX) { +- char *t = strchr(gopherState->request, '?'); +- +- if (t != NULL) +- *t = '\t'; +- +- snprintf(buf, 4096, "%s\r\n", gopherState->request); ++ mb.Printf("query %s\r\nquit", t); + } else { +- snprintf(buf, 4096, "%s\r\n", gopherState->request); ++ if (gopherState->type_id == GOPHER_INDEX) { ++ if (char *t = strchr(gopherState->request, '?')) ++ *t = '\t'; ++ } ++ mb.append(gopherState->request, strlen(gopherState->request)); + } ++ mb.append("\r\n", 2); + +- debugs(10, 5, HERE << gopherState->serverConn); ++ debugs(10, 5, gopherState->serverConn); + AsyncCall::Pointer call = commCbCall(5,5, "gopherSendComplete", + CommIoCbPtrFun(gopherSendComplete, gopherState)); +- Comm::Write(gopherState->serverConn, buf, strlen(buf), call, NULL); ++ Comm::Write(gopherState->serverConn, &mb, call); + + gopherState->entry->makePublic(); + } + +=== modified file 'src/icmp/Makefile.am' +--- src/icmp/Makefile.am 2017-01-01 00:16:45 +0000 ++++ src/icmp/Makefile.am 2017-06-22 15:31:46 +0000 +@@ -59,7 +59,8 @@ + pinger_LDFLAGS = $(LIBADD_DL) + pinger_LDADD=\ + libicmp-core.la \ +- ../ip/libip.la \ ++ $(top_builddir)/src/ip/libip.la \ ++ $(top_builddir)/src/base/libbase.la \ + $(COMPAT_LIB) \ + $(XTRA_LIBS) + + diff --git a/src/patches/squid/squid-3.5-14175.patch b/src/patches/squid/squid-3.5-14175.patch new file mode 100644 index 0000000..a2a8a5d --- /dev/null +++ b/src/patches/squid/squid-3.5-14175.patch @@ -0,0 +1,34 @@ +------------------------------------------------------------ +revno: 14175 +revision-id: squid3@treenet.co.nz-20170629125627-socq6szqysvm9ifa +parent: squid3@treenet.co.nz-20170622153146-nxo8vl6a9r8z03v4 +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4112 +author: Sven Eisenberg sven.eisenberg@lairdtech.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Fri 2017-06-30 00:56:27 +1200 +message: + Bug 4112: ssl_engine does not accept cryptodev +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170629125627-socq6szqysvm9ifa +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: c74e6941e5b6df8e36d26dd5c02389ae2955bc21 +# timestamp: 2017-06-29 13:51:04 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170622153146-\ +# nxo8vl6a9r8z03v4 +# +# Begin patch +=== modified file 'src/ssl/support.cc' +--- src/ssl/support.cc 2017-01-27 16:14:19 +0000 ++++ src/ssl/support.cc 2017-06-29 12:56:27 +0000 +@@ -737,6 +737,7 @@ + + #if HAVE_OPENSSL_ENGINE_H + if (Config.SSL.ssl_engine) { ++ ENGINE_load_builtin_engines(); + ENGINE *e; + if (!(e = ENGINE_by_id(Config.SSL.ssl_engine))) + fatalf("Unable to find SSL engine '%s'\n", Config.SSL.ssl_engine); + diff --git a/src/patches/squid/squid-3.5-14176.patch b/src/patches/squid/squid-3.5-14176.patch new file mode 100644 index 0000000..63141e3 --- /dev/null +++ b/src/patches/squid/squid-3.5-14176.patch @@ -0,0 +1,42 @@ +------------------------------------------------------------ +revno: 14176 +revision-id: squid3@treenet.co.nz-20170701073514-uzowexcysowqostf +parent: squid3@treenet.co.nz-20170629125627-socq6szqysvm9ifa +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4687 +author: Lubos Uhliarik luhliari@redhat.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sat 2017-07-01 19:35:14 +1200 +message: + Bug 4687: Wrong names of components in man page, section SEE ALSO +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170701073514-uzowexcysowqostf +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: 9099c98de3cb8fc125dd9952373de42c079b0ccc +# timestamp: 2017-07-01 07:45:05 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170629125627-\ +# socq6szqysvm9ifa +# +# Begin patch +=== modified file 'src/squid.8.in' +--- src/squid.8.in 2017-01-01 00:16:45 +0000 ++++ src/squid.8.in 2017-07-01 07:35:14 +0000 +@@ -265,11 +265,11 @@ + .SH SEE ALSO + .if !'po4a'hide' .B cachemgr.cgi "(8), " + .if !'po4a'hide' .B squidclient "(1), " +-.if !'po4a'hide' .B pam_auth "(8), " +-.if !'po4a'hide' .B squid_ldap_auth "(8), " +-.if !'po4a'hide' .B squid_ldap_group "(8), " ++.if !'po4a'hide' .B basic_pam_auth "(8), " ++.if !'po4a'hide' .B basic_ldap_auth "(8), " ++.if !'po4a'hide' .B ext_ldap_group_acl "(8), " + .if !'po4a'hide' .B ext_session_acl "(8), " +-.if !'po4a'hide' .B squid_unix_group "(8), " ++.if !'po4a'hide' .B ext_unix_group_acl "(8), " + .br + The Squid FAQ wiki + .if !'po4a'hide' http://wiki.squid-cache.org/SquidFaq + diff --git a/src/patches/squid/squid-3.5-14177.patch b/src/patches/squid/squid-3.5-14177.patch new file mode 100644 index 0000000..c9920ad --- /dev/null +++ b/src/patches/squid/squid-3.5-14177.patch @@ -0,0 +1,52 @@ +------------------------------------------------------------ +revno: 14177 +revision-id: squid3@treenet.co.nz-20170701073754-4x1i6p5s1gzk73co +parent: squid3@treenet.co.nz-20170701073514-uzowexcysowqostf +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sat 2017-07-01 19:37:54 +1200 +message: + basic_ncsa_auth: fix hash listing wrap in man(8) page + + '*' list bullet points must be indented with whitespace. + If they are not the list is treated as a single wrapped paragraph. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170701073754-4x1i6p5s1gzk73co +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: ffd783ab19a438c56affcdc6c1d106fa00403f4f +# timestamp: 2017-07-01 07:45:09 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170701073514-\ +# uzowexcysowqostf +# +# Begin patch +=== modified file 'helpers/basic_auth/NCSA/basic_ncsa_auth.8' +--- helpers/basic_auth/NCSA/basic_ncsa_auth.8 2017-01-01 00:16:45 +0000 ++++ helpers/basic_auth/NCSA/basic_ncsa_auth.8 2017-07-01 07:37:54 +0000 +@@ -18,15 +18,15 @@ + .PP + This authenticator accepts: + .BR +-* Blowfish - for passwords 72 characters or less in length +-.BR +-* SHA256 - with salting and magic strings +-.BR +-* SHA512 - with salting and magic strings +-.BR +-* MD5 - with optional salt and magic strings +-.BR +-* DES - for passwords 8 characters or less in length ++ * Blowfish - for passwords 72 characters or less in length. ++.BR ++ * SHA256 - with salting and magic strings. ++.BR ++ * SHA512 - with salting and magic strings. ++.BR ++ * MD5 - with optional salt and magic strings. ++.BR ++ * DES - for passwords 8 characters or less in length. + . + NOTE: Blowfish and SHA algorithms require system-specific support. + . + diff --git a/src/patches/squid/squid-3.5-14178.patch b/src/patches/squid/squid-3.5-14178.patch new file mode 100644 index 0000000..1a95150 --- /dev/null +++ b/src/patches/squid/squid-3.5-14178.patch @@ -0,0 +1,36 @@ +------------------------------------------------------------ +revno: 14178 +revision-id: squid3@treenet.co.nz-20170701081116-xekwolj1wdkeaxqv +parent: squid3@treenet.co.nz-20170701073754-4x1i6p5s1gzk73co +author: Alex Rousskov rousskov@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sat 2017-07-01 20:11:16 +1200 +message: + Fix message packing error handling in mgr and snmp SMP Forwarders. + + A missing "return" resulted in Forwarders sending garbage (or worse) to + Coordinator. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170701081116-xekwolj1wdkeaxqv +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: a593abc992a79d4539dede76b4f63e013f96d33a +# timestamp: 2017-07-01 08:51:30 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170701073754-\ +# 4x1i6p5s1gzk73co +# +# Begin patch +=== modified file 'src/ipc/Forwarder.cc' +--- src/ipc/Forwarder.cc 2017-01-01 00:16:45 +0000 ++++ src/ipc/Forwarder.cc 2017-07-01 08:11:16 +0000 +@@ -62,6 +62,7 @@ + // assume the pack() call failed because the message did not fit + // TODO: add a more specific exception? + handleError(); ++ return; + } + + SendMessage(Ipc::Port::CoordinatorAddr(), message); + diff --git a/src/patches/squid/squid-3.5-14179.patch b/src/patches/squid/squid-3.5-14179.patch new file mode 100644 index 0000000..112bdb0 --- /dev/null +++ b/src/patches/squid/squid-3.5-14179.patch @@ -0,0 +1,105 @@ +------------------------------------------------------------ +revno: 14179 +revision-id: squid3@treenet.co.nz-20170701095916-wknqmneq2w0mxt6a +parent: squid3@treenet.co.nz-20170701081116-xekwolj1wdkeaxqv +author: Alex Rousskov rousskov@measurement-factory.com +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sat 2017-07-01 21:59:16 +1200 +message: + Fix mgr query handoff from the original recipient to Coordinator. + + This bug has already been fixed once, in trunk r11164.1.61, but that fix + was accidentally undone shortly after, during significant cross-branch + merging activity combined with the Forwarder class split. The final + merge importing the associated code (trunk r11730) was buggy. + + The bug (explained in r11164.1.61) leads to a race condition between + + * Store notifying Server classes about the entry completion (which might + trigger a bogus error message sent to the cache manager client while + Coordinator sends its own valid response on the same connection!) and + + * post-cleanup() connection closure handlers of Server classes silently + closing everything (and leaving Coordinator the only responding + process on that shared connection). + + The bug probably was not noticed for so long because, evidently, the + latter actions tend to win in the current code. +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170701095916-wknqmneq2w0mxt6a +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: c7e89c80468c7f388f7e09ad2d68a245789db50d +# timestamp: 2017-07-01 10:51:12 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170701081116-\ +# xekwolj1wdkeaxqv +# +# Begin patch +=== modified file 'src/ipc/Forwarder.h' +--- src/ipc/Forwarder.h 2017-01-01 00:16:45 +0000 ++++ src/ipc/Forwarder.h 2017-07-01 09:59:16 +0000 +@@ -47,12 +47,14 @@ + virtual void handleError(); + virtual void handleTimeout(); + virtual void handleException(const std::exception& e); +- virtual void handleRemoteAck(); + + private: + static void RequestTimedOut(void* param); + void requestTimedOut(); + void removeTimeoutEvent(); ++ ++ void handleRemoteAck(); ++ + static AsyncCall::Pointer DequeueRequest(unsigned int requestId); + + protected: + +=== modified file 'src/mgr/Forwarder.cc' +--- src/mgr/Forwarder.cc 2017-01-01 00:16:45 +0000 ++++ src/mgr/Forwarder.cc 2017-07-01 09:59:16 +0000 +@@ -102,17 +102,6 @@ + mustStop("commClosed"); + } + +-/// called when Coordinator starts processing the request +-void +-Mgr::Forwarder::handleRemoteAck() +-{ +- Ipc::Forwarder::handleRemoteAck(); +- +- Must(entry != NULL); +- EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); +- entry->complete(); +-} +- + /// send error page + void + Mgr::Forwarder::sendError(ErrorState *error) + +=== modified file 'src/mgr/Forwarder.h' +--- src/mgr/Forwarder.h 2017-01-01 00:16:45 +0000 ++++ src/mgr/Forwarder.h 2017-07-01 09:59:16 +0000 +@@ -40,7 +40,6 @@ + virtual void handleError(); + virtual void handleTimeout(); + virtual void handleException(const std::exception& e); +- virtual void handleRemoteAck(); + + private: + void noteCommClosed(const CommCloseCbParams& params); + +=== modified file 'src/tests/stub_libmgr.cc' +--- src/tests/stub_libmgr.cc 2017-01-01 00:16:45 +0000 ++++ src/tests/stub_libmgr.cc 2017-07-01 09:59:16 +0000 +@@ -100,7 +100,6 @@ + void Mgr::Forwarder::handleError() STUB + void Mgr::Forwarder::handleTimeout() STUB + void Mgr::Forwarder::handleException(const std::exception& e) STUB +-void Mgr::Forwarder::handleRemoteAck() STUB + + #include "mgr/FunAction.h" + Mgr::Action::Pointer Mgr::FunAction::Create(const CommandPointer &cmd, OBJH *aHandler) STUB_RETVAL(dummyAction) + diff --git a/src/patches/squid/squid-3.5-14180.patch b/src/patches/squid/squid-3.5-14180.patch new file mode 100644 index 0000000..01d11cd --- /dev/null +++ b/src/patches/squid/squid-3.5-14180.patch @@ -0,0 +1,448 @@ +------------------------------------------------------------ +revno: 14180 +revision-id: squid3@treenet.co.nz-20170701120848-q2xznzfvxb4kwvb6 +parent: squid3@treenet.co.nz-20170701095916-wknqmneq2w0mxt6a +fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4464 +author: Christos Tsantilas chtsanti@users.sourceforge.net +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sun 2017-07-02 00:08:48 +1200 +message: + Bug 4464: Reduce "!Comm::MonitorsRead(serverConnection->fd)" assertions. + + * Protect Squid Client classes from new requests that compete with + ongoing pinned connection use and + * resume dealing with new requests when those Client classes are done + using the pinned connection. + + Replaced primary ConnStateData::pinConnection() calls with a pair of + pinBusyConnection() and notePinnedConnectionBecameIdle() calls, + depending on the pinned connection state ("busy" or "idle"). + + Removed pinConnection() parameters that were not longer used or could be computed from the remaining parameters. + + Removed ConnStateData::httpsPeeked() code "hiding" the originating + request and connection peer details while entering the first "idle" + state. The old (trunk r11880.1.6) bump-server-first code used a pair of + NULLs because "Intercepted connections do not have requests at the + connection pinning stage", but that limitation no longer applicable + because Squid always fakes (when intercepting) or parses (a CONNECT) + request now, even during SslBump step1. + + The added XXX and TODOs are not directly related to this fix. They + were added to document problems discovered while working on this fix. + + In v3.5 code, the same problems manifest as Read.cc + "fd_table[conn->fd].halfClosedReader != NULL" assertions. + + This is a Measurement Factory project +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170701120848-q2xznzfvxb4kwvb6 +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: e4f432eed8a845431d4bbbf023de04d682adeaff +# timestamp: 2017-07-01 12:32:26 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170701095916-\ +# wknqmneq2w0mxt6a +# +# Begin patch +=== modified file 'src/FwdState.cc' +--- src/FwdState.cc 2017-01-01 00:16:45 +0000 ++++ src/FwdState.cc 2017-07-01 12:08:48 +0000 +@@ -246,7 +246,7 @@ + #if USE_OPENSSL + if (request->flags.sslPeek && request->clientConnectionManager.valid()) { + CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, +- ConnStateData::httpsPeeked, Comm::ConnectionPointer(NULL)); ++ ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(Comm::ConnectionPointer(nullptr), request)); + } + #endif + } else { +@@ -952,7 +952,7 @@ + #if USE_OPENSSL + if (request->flags.sslPeek) { + CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, +- ConnStateData::httpsPeeked, serverConnection()); ++ ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(serverConnection(), request)); + unregister(serverConn); // async call owns it now + complete(); // destroys us + return; + +=== modified file 'src/base/RefCount.h' +--- src/base/RefCount.h 2017-01-01 00:16:45 +0000 ++++ src/base/RefCount.h 2017-07-01 12:08:48 +0000 +@@ -54,9 +54,7 @@ + + C & operator * () const {return *const_cast<C *>(p_); } + +- C const * getRaw() const {return p_; } +- +- C * getRaw() {return const_cast<C *>(p_); } ++ C * getRaw() const { return const_cast<C *>(p_); } + + bool operator == (const RefCount& p) const { + return p.p_ == p_; + +=== modified file 'src/client_side.cc' +--- src/client_side.cc 2017-05-29 13:15:55 +0000 ++++ src/client_side.cc 2017-07-01 12:08:48 +0000 +@@ -836,6 +836,7 @@ + assert(areAllContextsForThisConnection()); + freeAllContexts(); + ++ // XXX: Closing pinned conn is too harsh: The Client may want to continue! + unpinConnection(true); + + if (Comm::IsConnOpen(clientConnection)) +@@ -1559,6 +1560,13 @@ + + debugs(33, 3, HERE << "ConnnStateData(" << conn->clientConnection << "), Context(" << clientConnection << ")"); + connIsFinished(); ++ conn->kick(); ++} ++ ++void ++ConnStateData::kick() ++{ ++ ConnStateData * conn = this; // XXX: Remove this diff minimization hack + + if (conn->pinning.pinned && !Comm::IsConnOpen(conn->pinning.serverConnection)) { + debugs(33, 2, HERE << conn->clientConnection << " Connection was pinned but server side gone. Terminating client connection"); +@@ -3240,6 +3248,13 @@ + if (in.buf.isEmpty()) + break; + ++ // Prohibit concurrent requests when using a pinned to-server connection ++ // because our Client classes do not support request pipelining. ++ if (pinning.pinned && !pinning.readHandler) { ++ debugs(33, 3, clientConnection << " waits for busy " << pinning.serverConnection); ++ break; ++ } ++ + /* Limit the number of concurrent requests */ + if (concurrentRequestQueueFilled()) + break; +@@ -4434,22 +4449,19 @@ + } + + void +-ConnStateData::httpsPeeked(Comm::ConnectionPointer serverConnection) ++ConnStateData::httpsPeeked(PinnedIdleContext pic) + { + Must(sslServerBump != NULL); ++ Must(sslServerBump->request == pic.request); ++ Must(currentobject == NULL || currentobject->http == NULL || currentobject->http->request == pic.request.getRaw()); + +- if (Comm::IsConnOpen(serverConnection)) { +- pinConnection(serverConnection, NULL, NULL, false); ++ if (Comm::IsConnOpen(pic.connection)) { ++ notePinnedConnectionBecameIdle(pic); + + debugs(33, 5, HERE << "bumped HTTPS server: " << sslConnectHostOrIp); +- } else { ++ } else + debugs(33, 5, HERE << "Error while bumping: " << sslConnectHostOrIp); + +- // copy error detail from bump-server-first request to CONNECT request +- if (currentobject != NULL && currentobject->http != NULL && currentobject->http->request) +- currentobject->http->request->detailError(sslServerBump->request->errType, sslServerBump->request->errDetail); +- } +- + getSslContextStart(); + } + +@@ -4952,19 +4964,35 @@ + } + + void +-ConnStateData::pinConnection(const Comm::ConnectionPointer &pinServer, HttpRequest *request, CachePeer *aPeer, bool auth, bool monitor) +-{ +- if (!Comm::IsConnOpen(pinning.serverConnection) || +- pinning.serverConnection->fd != pinServer->fd) +- pinNewConnection(pinServer, request, aPeer, auth); +- +- if (monitor) +- startPinnedConnectionMonitoring(); +-} +- +-void +-ConnStateData::pinNewConnection(const Comm::ConnectionPointer &pinServer, HttpRequest *request, CachePeer *aPeer, bool auth) +-{ ++ConnStateData::pinBusyConnection(const Comm::ConnectionPointer &pinServer, const HttpRequest::Pointer &request) ++{ ++ pinConnection(pinServer, request); ++} ++ ++void ++ConnStateData::notePinnedConnectionBecameIdle(PinnedIdleContext pic) ++{ ++ Must(pic.connection != NULL); ++ Must(pic.request != NULL); ++ pinConnection(pic.connection, pic.request); ++ ++ // monitor pinned server connection for remote-end closures. ++ startPinnedConnectionMonitoring(); ++ ++ if (!currentobject) ++ kick(); // in case clientParseRequests() was blocked by a busy pic.connection ++} ++ ++/// Forward future client requests using the given server connection. ++void ++ConnStateData::pinConnection(const Comm::ConnectionPointer &pinServer, const HttpRequest::Pointer &request) ++{ ++ if (Comm::IsConnOpen(pinning.serverConnection) && ++ pinning.serverConnection->fd == pinServer->fd) { ++ debugs(33, 3, "already pinned" << pinServer); ++ return; ++ } ++ + unpinConnection(true); // closes pinned connection, if any, and resets fields + + pinning.serverConnection = pinServer; +@@ -4973,23 +5001,21 @@ + + Must(pinning.serverConnection != NULL); + +- // when pinning an SSL bumped connection, the request may be NULL + const char *pinnedHost = "[unknown]"; +- if (request) { ++ if (request != NULL) { + pinning.host = xstrdup(request->GetHost()); + pinning.port = request->port; + pinnedHost = pinning.host; ++ pinning.auth = request->flags.connectionAuth; + } else { + pinning.port = pinServer->remote.port(); + } + pinning.pinned = true; +- if (aPeer) +- pinning.peer = cbdataReference(aPeer); +- pinning.auth = auth; ++ pinning.peer = cbdataReference(pinServer->getPeer()); + char stmp[MAX_IPSTRLEN]; + char desc[FD_DESC_SZ]; + snprintf(desc, FD_DESC_SZ, "%s pinned connection for %s (%d)", +- (auth || !aPeer) ? pinnedHost : aPeer->name, ++ (pinning.auth || !pinning.peer) ? pinnedHost : pinning.peer->name, + clientConnection->remote.toUrl(stmp,MAX_IPSTRLEN), + clientConnection->fd); + fd_note(pinning.serverConnection->fd, desc); +@@ -5164,3 +5190,8 @@ + * connection has gone away */ + } + ++std::ostream & ++operator <<(std::ostream &os, const ConnStateData::PinnedIdleContext &pic) ++{ ++ return os << pic.connection << ", request=" << pic.request; ++} + +=== modified file 'src/client_side.h' +--- src/client_side.h 2017-01-01 00:16:45 +0000 ++++ src/client_side.h 2017-07-01 12:08:48 +0000 +@@ -26,6 +26,8 @@ + #include "ssl/support.h" + #endif + ++#include <iosfwd> ++ + class ConnStateData; + class ClientHttpRequest; + class clientStreamNode; +@@ -188,6 +190,11 @@ + /// Traffic parsing + bool clientParseRequests(); + void readNextRequest(); ++ ++ // In v3.5, usually called via ClientSocketContext::keepaliveNextRequest(). ++ /// try to make progress on a transaction or read more I/O ++ void kick(); ++ + ClientSocketContext::Pointer getCurrentContext() const; + void addContextToQueue(ClientSocketContext * context); + int getConcurrentRequestCount() const; +@@ -287,9 +294,21 @@ + bool handleReadData(); + bool handleRequestBodyData(); + +- /// Forward future client requests using the given server connection. +- /// Optionally, monitor pinned server connection for remote-end closures. +- void pinConnection(const Comm::ConnectionPointer &pinServerConn, HttpRequest *request, CachePeer *peer, bool auth, bool monitor = true); ++ /// parameters for the async notePinnedConnectionBecameIdle() call ++ class PinnedIdleContext ++ { ++ public: ++ PinnedIdleContext(const Comm::ConnectionPointer &conn, const HttpRequest::Pointer &req): connection(conn), request(req) {} ++ ++ Comm::ConnectionPointer connection; ///< to-server connection to be pinned ++ HttpRequest::Pointer request; ///< to-server request that initiated serverConnection ++ }; ++ ++ /// Called when a pinned connection becomes available for forwarding the next request. ++ void notePinnedConnectionBecameIdle(PinnedIdleContext pic); ++ /// Forward future client requests using the given to-server connection. ++ /// The connection is still being used by the current client request. ++ void pinBusyConnection(const Comm::ConnectionPointer &pinServerConn, const HttpRequest::Pointer &request); + /// Undo pinConnection() and, optionally, close the pinned connection. + void unpinConnection(const bool andClose); + /// Returns validated pinnned server connection (and stops its monitoring). +@@ -345,7 +364,7 @@ + /// generated + void doPeekAndSpliceStep(); + /// called by FwdState when it is done bumping the server +- void httpsPeeked(Comm::ConnectionPointer serverConnection); ++ void httpsPeeked(PinnedIdleContext pic); + + /// Start to create dynamic SSL_CTX for host or uses static port SSL context. + void getSslContextStart(); +@@ -449,7 +468,7 @@ + void clientAfterReadingRequests(); + bool concurrentRequestQueueFilled() const; + +- void pinNewConnection(const Comm::ConnectionPointer &pinServer, HttpRequest *request, CachePeer *aPeer, bool auth); ++ void pinConnection(const Comm::ConnectionPointer &pinServerConn, const HttpRequest::Pointer &request); + + /* PROXY protocol functionality */ + bool proxyProtocolValidateClient(); +@@ -516,5 +535,7 @@ + void clientProcessRequest(ConnStateData *conn, HttpParser *hp, ClientSocketContext *context, const HttpRequestMethod& method, Http::ProtocolVersion http_ver); + void clientPostHttpsAccept(ConnStateData *connState); + ++std::ostream &operator <<(std::ostream &os, const ConnStateData::PinnedIdleContext &pic); ++ + #endif /* SQUID_CLIENTSIDE_H */ + + +=== modified file 'src/clients/FtpRelay.cc' +--- src/clients/FtpRelay.cc 2017-01-01 00:16:45 +0000 ++++ src/clients/FtpRelay.cc 2017-07-01 12:08:48 +0000 +@@ -210,9 +210,10 @@ + mgr->unpinConnection(false); + ctrl.close(); + } else { +- mgr->pinConnection(ctrl.conn, fwd->request, +- ctrl.conn->getPeer(), +- fwd->request->flags.connectionAuth); ++ CallJobHere1(9, 4, mgr, ++ ConnStateData, ++ notePinnedConnectionBecameIdle, ++ ConnStateData::PinnedIdleContext(ctrl.conn, fwd->request)); + ctrl.forget(); + } + } + +=== modified file 'src/http.cc' +--- src/http.cc 2017-06-15 00:16:33 +0000 ++++ src/http.cc 2017-07-01 12:08:48 +0000 +@@ -1383,9 +1383,6 @@ + void + HttpStateData::processReplyBody() + { +- Ip::Address client_addr; +- bool ispinned = false; +- + if (!flags.headers_parsed) { + flags.do_next_read = true; + maybeReadVirginBody(); +@@ -1435,35 +1432,49 @@ + } + break; + +- case COMPLETE_PERSISTENT_MSG: ++ case COMPLETE_PERSISTENT_MSG: { + debugs(11, 5, "processReplyBody: COMPLETE_PERSISTENT_MSG from " << serverConnection); +- /* yes we have to clear all these! */ ++ ++ // TODO: Remove serverConnectionSaved but preserve exception safety. ++ + commUnsetConnTimeout(serverConnection); + flags.do_next_read = false; + + comm_remove_close_handler(serverConnection->fd, closeHandler); + closeHandler = NULL; +- fwd->unregister(serverConnection); + ++ Ip::Address client_addr; // XXX: Remove as unused. Why was it added? + if (request->flags.spoofClientIp) + client_addr = request->client_addr; + ++ Comm::ConnectionPointer serverConnectionSaved = serverConnection; ++ fwd->unregister(serverConnection); ++ serverConnection = nullptr; ++ ++ bool ispinned = false; // TODO: Rename to isOrShouldBePinned + if (request->flags.pinned) { + ispinned = true; + } else if (request->flags.connectionAuth && request->flags.authSent) { + ispinned = true; + } + +- if (ispinned && request->clientConnectionManager.valid()) { +- request->clientConnectionManager->pinConnection(serverConnection, request, _peer, +- (request->flags.connectionAuth)); ++ if (ispinned) { ++ if (request->clientConnectionManager.valid()) { ++ CallJobHere1(11, 4, request->clientConnectionManager, ++ ConnStateData, ++ notePinnedConnectionBecameIdle, ++ ConnStateData::PinnedIdleContext(serverConnectionSaved, request)); ++ } else { ++ // must not pool/share ispinned connections, even orphaned ones ++ serverConnectionSaved->close(); ++ } + } else { +- fwd->pconnPush(serverConnection, request->GetHost()); ++ fwd->pconnPush(serverConnectionSaved, request->GetHost()); + } + +- serverConnection = NULL; + serverComplete(); + return; ++ } + + case COMPLETE_NONPERSISTENT_MSG: + debugs(11, 5, "processReplyBody: COMPLETE_NONPERSISTENT_MSG from " << serverConnection); + +=== modified file 'src/servers/FtpServer.cc' +--- src/servers/FtpServer.cc 2017-02-26 11:09:42 +0000 ++++ src/servers/FtpServer.cc 2017-07-01 12:08:48 +0000 +@@ -301,12 +301,8 @@ + Must(http != NULL); + HttpRequest *const request = http->request; + Must(request != NULL); +- +- // this is not an idle connection, so we do not want I/O monitoring +- const bool monitor = false; +- + // make FTP peer connection exclusive to our request +- pinConnection(conn, request, conn->getPeer(), false, monitor); ++ pinBusyConnection(conn, request); + } + + void + +=== modified file 'src/tests/stub_client_side.cc' +--- src/tests/stub_client_side.cc 2017-01-01 00:16:45 +0000 ++++ src/tests/stub_client_side.cc 2017-07-01 12:08:48 +0000 +@@ -60,7 +60,8 @@ + void ConnStateData::noteBodyConsumerAborted(BodyPipe::Pointer) STUB + bool ConnStateData::handleReadData() STUB_RETVAL(false) + bool ConnStateData::handleRequestBodyData() STUB_RETVAL(false) +-void ConnStateData::pinConnection(const Comm::ConnectionPointer &pinServerConn, HttpRequest *request, CachePeer *peer, bool auth, bool monitor) STUB ++void ConnStateData::pinBusyConnection(const Comm::ConnectionPointer &, const HttpRequest::Pointer &) STUB ++void ConnStateData::notePinnedConnectionBecameIdle(PinnedIdleContext) STUB + void ConnStateData::unpinConnection(const bool andClose) STUB + const Comm::ConnectionPointer ConnStateData::validatePinnedConnection(HttpRequest *request, const CachePeer *peer) STUB_RETVAL(NULL) + void ConnStateData::clientPinnedConnectionClosed(const CommCloseCbParams &io) STUB +@@ -70,7 +71,7 @@ + void ConnStateData::swanSong() STUB + void ConnStateData::quitAfterError(HttpRequest *request) STUB + #if USE_OPENSSL +-void ConnStateData::httpsPeeked(Comm::ConnectionPointer serverConnection) STUB ++void ConnStateData::httpsPeeked(PinnedIdleContext) STUB + void ConnStateData::getSslContextStart() STUB + void ConnStateData::getSslContextDone(SSL_CTX * sslContext, bool isNew) STUB + void ConnStateData::sslCrtdHandleReplyWrapper(void *data, const Helper::Reply &reply) STUB + diff --git a/src/patches/squid/squid-3.5-14181.patch b/src/patches/squid/squid-3.5-14181.patch new file mode 100644 index 0000000..4516d60 --- /dev/null +++ b/src/patches/squid/squid-3.5-14181.patch @@ -0,0 +1,30 @@ +------------------------------------------------------------ +revno: 14181 +revision-id: squidadm@squid-cache.org-20170701121615-ktx76udds2mzmc6c +parent: squid3@treenet.co.nz-20170701120848-q2xznzfvxb4kwvb6 +committer: Source Maintenance squidadm@squid-cache.org +branch nick: 3.5 +timestamp: Sat 2017-07-01 12:16:15 +0000 +message: + SourceFormat Enforcement +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squidadm@squid-cache.org-20170701121615-\ +# ktx76udds2mzmc6c +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: d7942d1260def31f62ccc820a44bb769381beae2 +# timestamp: 2017-07-01 12:32:29 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squid3@treenet.co.nz-20170701120848-\ +# q2xznzfvxb4kwvb6 +# +# Begin patch +=== modified file 'src/client_side.cc' +--- src/client_side.cc 2017-07-01 12:08:48 +0000 ++++ src/client_side.cc 2017-07-01 12:16:15 +0000 +@@ -5195,3 +5195,4 @@ + { + return os << pic.connection << ", request=" << pic.request; + } ++ + diff --git a/src/patches/squid/squid-3.5-14182.patch b/src/patches/squid/squid-3.5-14182.patch new file mode 100644 index 0000000..3354881 --- /dev/null +++ b/src/patches/squid/squid-3.5-14182.patch @@ -0,0 +1,35 @@ +------------------------------------------------------------ +revno: 14182 +revision-id: squid3@treenet.co.nz-20170701232253-3beaysa03xf5c67p +parent: squidadm@squid-cache.org-20170701121615-ktx76udds2mzmc6c +committer: Amos Jeffries squid3@treenet.co.nz +branch nick: 3.5 +timestamp: Sun 2017-07-02 11:22:53 +1200 +message: + Fix build on FreeBSD after rev.14180 + + RefCount<> does not support assignment from nullptr with C++03 +------------------------------------------------------------ +# Bazaar merge directive format 2 (Bazaar 0.90) +# revision_id: squid3@treenet.co.nz-20170701232253-3beaysa03xf5c67p +# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# testament_sha1: d5ecf68c60c022783f69311e9049e546be8fa1a0 +# timestamp: 2017-07-01 23:50:58 +0000 +# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5 +# base_revision_id: squidadm@squid-cache.org-20170701121615-\ +# ktx76udds2mzmc6c +# +# Begin patch +=== modified file 'src/http.cc' +--- src/http.cc 2017-07-01 12:08:48 +0000 ++++ src/http.cc 2017-07-01 23:22:53 +0000 +@@ -1449,7 +1449,7 @@ + + Comm::ConnectionPointer serverConnectionSaved = serverConnection; + fwd->unregister(serverConnection); +- serverConnection = nullptr; ++ serverConnection = NULL; + + bool ispinned = false; // TODO: Rename to isOrShouldBePinned + if (request->flags.pinned) { + diff --git a/src/patches/unbound-allow-setting-validator-permissive-mode-at-runtime.patch b/src/patches/unbound-allow-setting-validator-permissive-mode-at-runtime.patch deleted file mode 100644 index f476d08..0000000 --- a/src/patches/unbound-allow-setting-validator-permissive-mode-at-runtime.patch +++ /dev/null @@ -1,43 +0,0 @@ -diff --git a/validator/validator.c b/validator/validator.c -index 676dcdf..7c19f3d 100644 ---- a/validator/validator.c -+++ b/validator/validator.c -@@ -113,7 +113,7 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env, - int c; - val_env->bogus_ttl = (uint32_t)cfg->bogus_ttl; - val_env->clean_additional = cfg->val_clean_additional; -- val_env->permissive_mode = cfg->val_permissive_mode; -+ val_env->permissive_mode = &cfg->val_permissive_mode; - if(!env->anchors) - env->anchors = anchors_create(); - if(!env->anchors) { -@@ -170,7 +170,6 @@ val_init(struct module_env* env, int id) - } - env->modinfo[id] = (void*)val_env; - env->need_to_validate = 1; -- val_env->permissive_mode = 0; - lock_basic_init(&val_env->bogus_lock); - lock_protect(&val_env->bogus_lock, &val_env->num_rrset_bogus, - sizeof(val_env->num_rrset_bogus)); -@@ -2084,7 +2083,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, - } - } - /* If we are in permissive mode, bogus gets indeterminate */ -- if(ve->permissive_mode) -+ if(*ve->permissive_mode) - vq->orig_msg->rep->security = sec_status_indeterminate; - } - -diff --git a/validator/validator.h b/validator/validator.h -index 23d3072..f8464b8 100644 ---- a/validator/validator.h -+++ b/validator/validator.h -@@ -104,7 +104,7 @@ struct val_env { - * This allows an operator to run validation 'shadow' without - * hurting responses to clients. - */ -- int permissive_mode; -+ int* permissive_mode; - - /** - * Number of entries in the NSEC3 maximum iteration count table. diff --git a/src/wio/EX-wio.menu b/src/wio/EX-wio.menu new file mode 100644 index 0000000..33a785e --- /dev/null +++ b/src/wio/EX-wio.menu @@ -0,0 +1,6 @@ + $substatus->{'55.wio'} = { + 'caption' => "$Lang::tr{'wio'}", + 'uri' => '/cgi-bin/wio.cgi', + 'title' => "$Lang::tr{'wio'}", + 'enabled' => 1, + }; diff --git a/src/wio/config/backup/includes/wio b/src/wio/config/backup/includes/wio new file mode 100644 index 0000000..688b819 --- /dev/null +++ b/src/wio/config/backup/includes/wio @@ -0,0 +1,2 @@ +/var/ipfire/wio/wio.conf +/var/log/wio diff --git a/src/wio/images/add.png b/src/wio/images/add.png new file mode 100644 index 0000000..d894689 Binary files /dev/null and b/src/wio/images/add.png differ diff --git a/src/wio/images/back.png b/src/wio/images/back.png new file mode 100644 index 0000000..66921af Binary files /dev/null and b/src/wio/images/back.png differ diff --git a/src/wio/images/blue.png b/src/wio/images/blue.png new file mode 100644 index 0000000..84d570e Binary files /dev/null and b/src/wio/images/blue.png differ diff --git a/src/wio/images/fqdn.png b/src/wio/images/fqdn.png new file mode 100644 index 0000000..2db5ff7 Binary files /dev/null and b/src/wio/images/fqdn.png differ diff --git a/src/wio/images/graph.png b/src/wio/images/graph.png new file mode 100644 index 0000000..ac86b8c Binary files /dev/null and b/src/wio/images/graph.png differ diff --git a/src/wio/images/green.png b/src/wio/images/green.png new file mode 100644 index 0000000..44838ec Binary files /dev/null and b/src/wio/images/green.png differ diff --git a/src/wio/images/http.png b/src/wio/images/http.png new file mode 100644 index 0000000..851e400 Binary files /dev/null and b/src/wio/images/http.png differ diff --git a/src/wio/images/https.png b/src/wio/images/https.png new file mode 100644 index 0000000..823126a Binary files /dev/null and b/src/wio/images/https.png differ diff --git a/src/wio/images/ip.png b/src/wio/images/ip.png new file mode 100644 index 0000000..da0e8a2 Binary files /dev/null and b/src/wio/images/ip.png differ diff --git a/src/wio/images/mailgreenoff.png b/src/wio/images/mailgreenoff.png new file mode 100644 index 0000000..041c9e7 Binary files /dev/null and b/src/wio/images/mailgreenoff.png differ diff --git a/src/wio/images/mailgreenon.png b/src/wio/images/mailgreenon.png new file mode 100644 index 0000000..9acc358 Binary files /dev/null and b/src/wio/images/mailgreenon.png differ diff --git a/src/wio/images/mailredoff.png b/src/wio/images/mailredoff.png new file mode 100644 index 0000000..0dbf075 Binary files /dev/null and b/src/wio/images/mailredoff.png differ diff --git a/src/wio/images/mailredon.png b/src/wio/images/mailredon.png new file mode 100644 index 0000000..668ba7d Binary files /dev/null and b/src/wio/images/mailredon.png differ diff --git a/src/wio/images/no_graph.png b/src/wio/images/no_graph.png new file mode 100644 index 0000000..073ccc5 Binary files /dev/null and b/src/wio/images/no_graph.png differ diff --git a/src/wio/images/none.png b/src/wio/images/none.png new file mode 100644 index 0000000..fa0c3f3 Binary files /dev/null and b/src/wio/images/none.png differ diff --git a/src/wio/images/orange.png b/src/wio/images/orange.png new file mode 100644 index 0000000..9504469 Binary files /dev/null and b/src/wio/images/orange.png differ diff --git a/src/wio/images/ovpn.png b/src/wio/images/ovpn.png new file mode 100644 index 0000000..407a868 Binary files /dev/null and b/src/wio/images/ovpn.png differ diff --git a/src/wio/images/ovpnn2n.png b/src/wio/images/ovpnn2n.png new file mode 100644 index 0000000..038d6ed Binary files /dev/null and b/src/wio/images/ovpnn2n.png differ diff --git a/src/wio/images/ovpnrw.png b/src/wio/images/ovpnrw.png new file mode 100644 index 0000000..a17a622 Binary files /dev/null and b/src/wio/images/ovpnrw.png differ diff --git a/src/wio/images/red.png b/src/wio/images/red.png new file mode 100644 index 0000000..e15dfb1 Binary files /dev/null and b/src/wio/images/red.png differ diff --git a/src/wio/images/refresh.png b/src/wio/images/refresh.png new file mode 100644 index 0000000..60a5ddd Binary files /dev/null and b/src/wio/images/refresh.png differ diff --git a/src/wio/images/vpn.png b/src/wio/images/vpn.png new file mode 100644 index 0000000..d68f08e Binary files /dev/null and b/src/wio/images/vpn.png differ diff --git a/src/wio/images/vpnn2n.png b/src/wio/images/vpnn2n.png new file mode 100644 index 0000000..2aa96df Binary files /dev/null and b/src/wio/images/vpnn2n.png differ diff --git a/src/wio/images/vpnrw.png b/src/wio/images/vpnrw.png new file mode 100644 index 0000000..ca99367 Binary files /dev/null and b/src/wio/images/vpnrw.png differ diff --git a/src/wio/images/white.png b/src/wio/images/white.png new file mode 100644 index 0000000..20546bc Binary files /dev/null and b/src/wio/images/white.png differ diff --git a/src/wio/lang/wio.de.pl b/src/wio/lang/wio.de.pl new file mode 100644 index 0000000..430284e --- /dev/null +++ b/src/wio/lang/wio.de.pl @@ -0,0 +1,156 @@ +%tr = (%tr, +'wio' => 'Who Is Online?', +'wio stat' => 'Status:', +'wio checked' => 'zuletzt überprüft', +'wio name' => 'Hostname / FQDN', +'wio ipadress' => 'IP-Adresse', +'wio image' => 'Zustand', +'wio up' => 'AKTIV', +'wio down' => 'INAKTIV', +'wio err' => 'Fehler', +'wio warn' => 'Warnung', +'wio_import_csv' => 'CSV Datei', +'wio_import_hosts' => 'Hosts Datei (var/ipfire/main/hosts)', +'wio_import_data' => 'Einstellungen für ', +'wio_import_data1' => ' bearbeiten:', +'wio_import_data2' => ' importieren:', +'wio_import' => 'Importieren', +'wio_import_info' => 'Mitteilung:', +'wio_import_file' => 'Client(s) importieren aus:', +'wio_import_info_csv' => 'Es gibt keine neuen Einstellungen zu importieren!', +'wio settings' => 'Konfiguration:', +'wio enabled' => 'aktivieren?', +'wio min' => 'Minute(n)', +'wio cron' => 'Zeitintervall für die Überprüfung:', +'wio_ovpn_cron' => 'Zeitintervall für die Überprüfung des OpenVPN RW und IPSec Status:', +'wio_save' => 'speichern', +'wio_error' => 'Fehlermeldung:', +'wio_info' => 'Meldung:', +'wio_back' => 'zurück', +'wio_use' => 'Diese Einstellungen importieren?', +'wio_ip_error' => 'Ungültige IP-Adresse!', +'wio_host_error' => 'Ungültiger Hostname!', +'wio_host_exists' => 'Hostname wird schon benutzt!', +'wio_host_empty' => 'Es wurde kein Hostname eingetragen!', +'wio_ip_exists' => 'IP-Adresse wird schon benutzt!', +'wio_ip_empty' => 'Es wurde keine IP-Adresse eingetragen!', +'wio_import_fixleases' => 'DHCP Datei (var/ipfire/dhcp/fixleases)', +'wio_import_leases' => 'Einstellungen importieren:', +'wio network' => 'Netzwerk', +'wio_refresh' => 'alle Clients aktualisieren', +'wio_fqdn_error' => 'Ungültiger Fully Qualified Domain Name (FQDN)! Bitte keine Sonderzeichen, Umlaute oder Leerzeichen beim FQDN verwenden.', +'wio_edit' => 'Einstellungen bearbeiten:', +'wio_dyndns' => 'DynDNS', +'wio_dyndns_hosts' => 'DynDNS Name(n)', +'wio_dyndns_refresh' => 'DynDNS IP aktualisieren', +'wio_dyndns_on' => 'DynDNS Host aktiviert (klicken, um zu deaktivieren)', +'wio_dyndns_off' => 'DynDNS Host deaktiviert (klicken, um zu aktivieren)', +'wio_dyndns_info' => 'Keine IP eingetragen, da scheinbar keine Verbindung ins Internet besteht. Bei der nächsten Verbindung ins Internet wird eine Aktualisierung der IP des DynDNS Hostes durchgeführt.', +'wio_no_csv' => 'Die Datei hat nicht die Erweiterung .csv', +'wio_no_csv_error' => 'Bitte keine Sonderzeichen, Umlaute oder Leerzeichen im Dateinamen verwenden.', +'wio_no_file_selected' => 'Es wurde keine Datei ausgewählt!', +'wio_import_infos' => 'Einstellungen importieren:', +'wio_import_infos_csv' => 'ACHTUNG: Es werden nur die Datensätze importiert, bei denen die Option "Diese Einstellungen importieren?" aktiviert ist! Sollten Datensätze mit doppelten IP-Adressen oder Hostnamen vorkommen, wird der zu erst aufgeführte Datensatz importiert und die anderen Datensätze (mit den doppelten IP-Adressen oder Hostnamen) werden nicht berücksichtigt!', +'enable disable dyndns' => 'DynDNS Host aktivieren oder deaktivieren', +'wio_msg' => 'Zustand (aktiv/inaktiv) des Clients / der Clients wird aktualisiert ...', +'wio_lanname' => 'LAN Hostname', +'wio_wanname' => 'WAN Hostname', +'wio_wancheck' => 'verbunden seit', +'wio_sc_refresh' => 'Client aktualisieren', +'wio_edit_settings' => 'Client hinzufügen:', +'wio_edit_client' => 'Client bearbeiten:', +'wio_graphs' => 'Graphen anzeigen', +'wio_no_graphs' => 'keine Graphen vorhanden', +'wio_graphs_stat' => 'Diagramme für', +'wio_vpn_con' => 'VPN - Verbindung(en):', +'wio_wan_con' => 'WAN - Verbindung:', +'wio_clients' => 'Clients:', +'wio click to disable' => 'Aktiviert', +'wio click to enable' => 'Deaktiviert', +'wio_net_scan' => 'Netzwerk(e) durchsuchen:', +'wio_net_scan_vl' => '', +'wio_net_scan_l' => 'Netzwerk an', +'wio_net_scan_r' => 'durchsuchen:', +'wio_net_scan_green' => 'grünes', +'wio_net_scan_blue' => 'blaues', +'wio_net_scan_orange' => 'oranges', +'wio_net_scan_run' => 'starten', +'wio_sort_host' => 'nach Hostnamen (FQDN) sortieren', +'wio_sort_ip' => 'nach IP Adressen sortieren', +'wio_logging' => 'Logging (/var/log/messages) aktivieren?', +'wio_no_image' => 'KEIN STATUS', +'wio_ovpn_con' => 'OpenVPN - Verbindung(en):', +'wio_ovpn_connected' => 'verbunden seit', +'wio_wan_up' => 'VERBUNDEN', +'wio_wan_down' => 'GETRENNT', +'wio_n2n' => 'Netz-zu-Netz Verbindung', +'wio_rw' => 'Host-zu-Netz Verbindung', +'wio_mailremark_enabled' => 'Anmerkung des Clients mit in Mailtext übernehmen?', +'wio_mail_online_on' => 'Online-E-Mail aktiviert (klicken, um zu deaktivieren)', +'wio_mail_online_off' => 'Online-E-Mail deaktiviert (klicken, um zu aktivieren)', +'wio_mail_offline_on' => 'Offline-E-Mail aktiviert (klicken, um zu deaktivieren)', +'wio_mail_offline_off' => 'Offline-E-Mail deaktiviert (klicken, um zu aktivieren)', +'wio_mail_online' => 'Online E-Mail aktivieren oder deaktivieren', +'wio_mail_offline' => 'Offline E-Mail aktivieren oder deaktivieren', +'wio_sendemail' => 'E-Mail senden wenn', +'wio_hwaddress' => 'HW-Adresse', +'wio_iface' => 'Schnittstelle', +'wio_client_enable' => 'Client aktivieren?', +'wio_ping_send' => 'überprüfen per', +'enable disable client' => 'Client aktivieren oder deaktivieren', +'wio_client_on' => 'Überwachung aktiviert (klicken, um zu deaktivieren)', +'wio_client_off' => 'Überwachung deaktiviert (klicken, um zu aktivieren)', +'wio_webinterface' => 'LINK', +'wio_webinterface_link' => 'Link öffnen', +'wio_ip' => 'überprüfen per IP aktiviert', +'wio_fqdn' => 'überprüfen per FQDN aktiviert', +'wio_ip_on' => 'überprüfen per IP aktiviert (klicken, um per FQDN zu aktivieren)', +'wio_fqdn_on' => 'überprüfen per FQDN aktiviert (klicken, um per IP zu aktivieren)', +'wio_client_add' => 'Eingaben anwenden', +'wio_config' => 'Client(s) konfigurieren:', +'wio_settings_msg' => 'Einstellungen bearbeiten:', +'wio_settings_msg_hint' => 'Um Who Is Online? benutzen zu können, müssen hier grundsätzliche Einstellungen vorgenommen werden.', +'wio_sub' => 'WIO Client-Status-Mail', +'wio timeout' => 'Ping Timeout:', +'wio sec' => 'Sekunde(n)', +'wio_add' => 'Client hinzufügen:', +'wio_no_add' => 'Client ist vorhanden', +'wio_id' => '#', +'wio_online' => 'online', +'wio_offline' => 'offline', +'wio_status' => 'WIO Client-Status', +'wio_mail_style' => 'WIO Client Statusmails versenden als', +'wio_mail_smail' => 'Sammelmail', +'wio_mail_email' => 'Einzelmails', +'wio_mail_ovpnrw' => 'OpenVPN RW und IPSec Statusmails aktivieren?', +'wio_edit_set' => 'Konfiguration', +'wio_service' => 'Service:', +'wio_dyndns_success' => 'DynDNS IP ermittelt und eingetragen!', +'wio_remove_all' => 'alle Clients löschen', +'wio_remove_all_hint' => 'Möchten Sie wirklich alle Clients löschen?', +'wio_remove_client' => 'Client löschen', +'wio_remove_client_hint' => 'Möchten Sie den Client wirklich löschen?', +'wio_arp_table_entries' => 'Client aus der ARP-Tabelle hinzufügen:', +'wio_activ' => 'aktiv', +'wio_check' => 'prüfen', +'wio_common_name' => 'Remote Host / IP', +'wio_msg_left' => 'Das', +'wio_msg_green' => 'grüne', +'wio_msg_blue' => 'blaue', +'wio_msg_orange' => 'orange', +'wio_msg_center' => 'Netzwerk an', +'wio_msg_right' => 'wird durchsucht.', +'wio_msg_hint' => 'Einen Moment bitte ...', +'wio_last_update' => 'zuletzt aktualisiert', +'wio_disable_hint' => 'Achtung! Es werden alle Einstellungen incl. der zu überprüfenden Clients zurückgesetzt!', +'wio_clientremark' => 'Anmerkung anzeigen?', +'wio_already_running' => 'Die Prüfung wird bereits durchgeführt!', +'wio_error_function' => 'Diese Funktion kann im Moment nicht ausgeführt werden, da im Hintergrund gerade der Zustand (aktiv/inaktiv) der Clients aktualisiert wird.', +'wio_shutdown' => 'Herunterfahren, wenn alle Clients "offline" sind?', +'wio_unknown_lan' => 'UNBEKANNT', +'wio_red_lan' => 'ROT', +'wio_search' => 'Suche im lokalen Netzwerk nach aktiven Hosts ...', +'wio_answer' => 'Antwort', +'wio_answer_time' => 'Antwortzeit', +'wio_scriptruntime' => 'Scriptlaufzeit', +); diff --git a/src/wio/lang/wio.en.pl b/src/wio/lang/wio.en.pl new file mode 100644 index 0000000..17312a7 --- /dev/null +++ b/src/wio/lang/wio.en.pl @@ -0,0 +1,156 @@ +%tr = (%tr, +'wio' => 'Who Is Online?', +'wio stat' => 'Current condition(s):', +'wio checked' => 'Last checked', +'wio name' => 'Hostname or FQDN', +'wio ipadress' => 'IP-Address', +'wio image' => 'Condition', +'wio up' => 'Active', +'wio down' => 'Inactive', +'wio err' => 'Error', +'wio warn' => 'Warning', +'wio_import_csv' => 'CSV file:', +'wio_import_hosts' => 'hosts configuration (var/ipfire/main/hosts) ?', +'wio_import_data' => 'import settings for ', +'wio_import_data1' => ' correct:', +'wio_import_data2' => ' import:', +'wio_import' => 'Importing', +'wio_import_info' => 'message:', +'wio_import_file' => 'Import settings from:', +'wio_import_info_csv' => 'There are no new settings to import!', +'wio settings' => 'configuration:', +'wio enabled' => 'enable ?', +'wio min' => 'Minute(s)', +'wio cron' => 'Time interval for checking:', +'wio_ovpn_cron' => 'Time interval for checking the OpenVPN RW and IPSec Status:', +'wio_save' => 'save', +'wio_error' => 'errormessage:', +'wio_info' => 'message:', +'wio_back' => 'back', +'wio_use' => 'Import these settings ?', +'wio_ip_error' => 'Invalid IP Address.', +'wio_host_error' => 'Invalid Hostname.', +'wio_host_exists' => 'Hostname is already used.', +'wio_host_empty' => 'No Hostname was registered!', +'wio_ip_exists' => 'IP Address is already used.', +'wio_ip_empty' => 'No IP Address was registered!', +'wio_import_fixleases' => 'DHCP configuration (var/ipfire/dhcp/fixleases) ?', +'wio_import_leases' => 'Import settings:', +'wio network' => 'Network', +'wio_refresh' => 'update all clients now', +'wio_fqdn_error' => 'Invalid Fully Qualified Domain Name (FQDN)! Please do not use special characters or blanks in the FQDN.', +'wio_edit' => 'change settings:', +'wio_dyndns' => 'DynDNS', +'wio_dyndns_hosts' => 'DynDNS Name(s)', +'wio_dyndns_refresh' => 'DynDNS Host IP update', +'wio_dyndns_on' => 'DynDNS Host enabled (click to disable)', +'wio_dyndns_off' => 'DynDNS Host disabled (click to enable)', +'wio_dyndns_info' => 'None IP registered, since apparently no connection exists in Internet. With the next connection in Internet is accomplished an actualization of the IP of the DynDNS Hostes.', +'wio_no_csv' => 'File has not the extension .csv', +'wio_no_csv_error' => 'Please do not use special characters or blanks in the filename.', +'wio_no_file_selected' => 'No File selected!', +'wio_import_infos' => 'Import settings:', +'wio_import_infos_csv' => 'NOTE: Only Data records with marked "Import these settings ?" are considered by importing! If data records with double IP-Addresses or Hostnames should occur, only the first data record will be imported and the other data records (with the double IP-Addresses or Hostnames) will not be considered!', +'enable disable dyndns' => 'enable or disable DynDNS Host', +'wio_msg' => 'Condition of the examining Client(s) are updated ...', +'wio_lanname' => 'LAN Hostname', +'wio_wanname' => 'WAN Hostname', +'wio_wancheck' => 'connected since', +'wio_sc_refresh' => 'update client now', +'wio_edit_settings' => 'add client:', +'wio_edit_client' => 'edit client:', +'wio_graphs' => 'show graphs', +'wio_no_graphs' => 'no graphs available', +'wio_graphs_stat' => 'Diagramm for', +'wio_vpn_con' => 'VPN - Connection(s):', +'wio_wan_con' => 'WAN - Connection:', +'wio_clients' => 'clients:', +'wio click to disable' => 'Activated', +'wio click to enable' => 'Deactivated', +'wio_net_scan' => 'Scan Network(s):', +'wio_net_scan_vl' => 'scan', +'wio_net_scan_l' => 'Network on', +'wio_net_scan_r' => '', +'wio_net_scan_green' => 'green', +'wio_net_scan_blue' => 'blue', +'wio_net_scan_orange' => 'orange', +'wio_net_scan_run' => 'start', +'wio_sort_host' => 'sort Hostnames (FQDN)', +'wio_sort_ip' => 'sort IP-Adresses', +'wio_logging' => 'activate Logging (/var/log/messages) ?', +'wio_no_image' => 'NO STATUS', +'wio_ovpn_con' => 'OpenVPN - Connection(s):', +'wio_ovpn_connected' => 'connected since', +'wio_wan_up' => 'CONNECTED', +'wio_wan_down' => 'NOT CONNECTED', +'wio_n2n' => 'Net-to-Net Connection', +'wio_rw' => 'Host-to-Net Connection', +'wio_mailremark_enabled' => 'Add Remark from client to mailbody ?', +'wio_mail_online_on' => 'online email enabled (click to disable)', +'wio_mail_online_off' => 'online email disabled (click to enable)', +'wio_mail_offline_on' => 'offline email enabled (click to disable)', +'wio_mail_offline_off' => 'offline emaildisabled (click to enable)', +'wio_mail_online' => 'enable or disable online email', +'wio_mail_offline' => 'enable or disable offline email', +'wio_sendemail' => 'send email', +'wio_hwaddress' => 'HW-Adresse', +'wio_iface' => 'Interface', +'wio_client_enable' => 'enable Host ?', +'wio_ping_send' => 'send ping to', +'enable disable client' => 'enable or disable client', +'wio_client_on' => 'Client enabled (click to disable)', +'wio_client_off' => 'Client disabled (click to enable)', +'wio_webinterface' => 'LINK', +'wio_webinterface_link' => 'follow link', +'wio_ip' => 'send ping to IP enabled', +'wio_fqdn' => 'send ping to FQDN enabled', +'wio_ip_on' => 'send ping to IP enabled (click to enable FQDN)', +'wio_fqdn_on' => 'send ping to FQDN enabled (click to enable IP)', +'wio_client_add' => 'use settings', +'wio_config' => 'configurate Client(s):', +'wio_settings_msg' => 'configurate settings:', +'wio_settings_msg_hint' => 'Here you have to set some values to get the addon started.', +'wio_sub' => 'WIO Client-Status-Mail', +'wio timeout' => 'Ping Timeout:', +'wio sec' => 'Second(s)', +'wio_add' => 'add Client:', +'wio_no_add' => 'Client is available', +'wio_id' => '#', +'wio_online' => 'online', +'wio_offline' => 'offline', +'wio_status' => 'WIO Client-Status', +'wio_mail_style' => 'send WIO Client Statusmails as', +'wio_mail_smail' => 'collected mail', +'wio_mail_email' => 'single mails', +'wio_mail_ovpnrw' => 'enable OpenVPN RW and IPSec Statusmails ?', +'wio_edit_set' => 'Configuration', +'wio_service' => 'Service:', +'wio_dyndns_success' => 'DynDNS IP identified and registered!', +'wio_remove_all' => 'remove all clients', +'wio_remove_all_hint' => 'Are you sure to delete all the clients?', +'wio_remove_client' => 'remove client', +'wio_remove_client_hint' => 'Are you sure to delete the client?', +'wio_arp_table_entries' => 'add client from ARP-Table:', +'wio_activ' => 'activ', +'wio_check' => 'check', +'wio_common_name' => 'Remote Host/IP', +'wio_msg_left' => 'Searching on the', +'wio_msg_green' => 'green', +'wio_msg_blue' => 'blue', +'wio_msg_orange' => 'orange', +'wio_msg_center' => 'Interface on', +'wio_msg_right' => 'is being examined.', +'wio_msg_hint' => 'One moment please ...', +'wio_last_update' => 'last update', +'wio_disable_hint' => 'Attention! It will reset all settings including the client to be checked!', +'wio_clientremark' => 'show remark?', +'wio_already_running' => 'This check is already running!', +'wio_error_function' => 'This function is temporarily unavailable, because in the background client states are being updated (active/inactive).', +'wio_shutdown' => 'Shutdown when all clients are "offline"?', +'wio_unknown_lan' => 'UNKNOWN', +'wio_red_lan' => 'RED', +'wio_search' => 'Searching for active hosts in the local network ...', +'wio_answer' => 'Answer', +'wio_answer_time' => 'Response Time', +'wio_scriptruntime' => 'Script Execution Time', +); diff --git a/src/wio/main/wio.conf b/src/wio/main/wio.conf new file mode 100644 index 0000000..e69de29 diff --git a/src/wio/main/wio.pl b/src/wio/main/wio.pl new file mode 100644 index 0000000..985900d --- /dev/null +++ b/src/wio/main/wio.pl @@ -0,0 +1,385 @@ +#!/usr/bin/perl +# +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 Stephan Feddersen addons@h-loit.de # +# All Rights Reserved. # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### +# +# id: wio.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen +# +# This wio.pl is based on the Code from the IPCop WIO Addon +# and is extremly adapted to work with IPFire. +# +# Autor: Stephan Feddersen +# Co-Autor: Alexander Marx +# Co-Autor: Frank Mainz +# + +# enable only the following on debugging purpose +#use warnings; + +use strict; +use POSIX qw(strftime); +use Time::HiRes qw(gettimeofday tv_interval); +use Net::Ping; +use RRDs; +use Fatal qw/ open /; + +require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/lang.pl'; +require '/usr/lib/wio/wio-lib.pl'; + +my ( $debug, $i, $t, $ib, $tb, $ivpn, $tvpn ) = ''; +my $logdir = "/var/log/wio"; +my $owner = getpwnam "nobody"; +my $group = getgrnam "nobody"; +my $ipadrfile = "$logdir/wioips"; + +unless ( -e $ipadrfile ) { print ( "The file $ipadrfile doesn't exist!\n" ); exit; } + +foreach (@ARGV) { + if ( $_ eq '-d' || $_ eq '--debug') { $debug = 1; } + if ( $_ eq '-h' || $_ eq '--help' ) { die help(); } +} + +my ( %wiosettings, %mainsettings, %mailsettings, %netsettings ) = (); + +&General::readhash('/var/ipfire/main/settings', %mainsettings); +&General::readhash('/var/ipfire/ethernet/settings', %netsettings); +&General::readhash('/var/ipfire/dma/mail.conf', %mailsettings); +&General::readhash("/var/ipfire/wio/wio.conf", %wiosettings); + +my $now = strftime "%a, %d.%m.%Y %H:%M:%S", localtime; +my $logging = $wiosettings{'LOGGING'}; +my $mailstyle = $wiosettings{'MAILSTYLE'}; +my $mailremark = $wiosettings{'MAILREMARK'}; +my $timeout = $wiosettings{'TIMEOUT'}; +my $shutdown = $wiosettings{'SHUTDOWN'}; +my $rrddir = "/var/log/rrd/wio"; +my $onoffip = "$logdir/wioscip"; +my $hostname = "$mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'}"; +my $redactive = "/var/ipfire/red/active"; +my $rediface = "/var/ipfire/red/iface"; +my $reddev = ''; + +if ( -e $rediface ) { + $reddev = &General::get_red_interface; +} + +my $redip = $hostname; +my $vpnpid = ( -e "/var/run/charon.pid" ? `awk '{print $1}' /var/run/charon.pid`: ''); +my $ovpnpid = ( -e "/var/run/openvpn.pid" ? `awk '{print $1}' /var/run/openvpn.pid`: ''); + +my $steptime = $wiosettings{'CRON'} *= 60; +my $i_ping = 'icmp'; +my $t_ping = 'tcp'; + +my $nr = 1; +my $poweroff = 0; + +my ( $togglestat, $arp, $time, $start, $timestamp ) = 0; +my ( $id, $ipadr, $ipadrnew, $host, $hostnew, $enable, $remark, $dyndns, $dyndnsip ) = ''; +my ( $mail, $mailon, $mailoff, $ping, $on, $httphost, $mailen ) = ''; +my ( $msg, $logmsg, $mailmsg, $smailtxt, $infomsg, $client, $mode, $onbak, $arpclient ) = ''; +my ( $ping_i, $ping_t, $ping_ib, $ping_tb, $ping_iv, $ping_tv, $pingmode ) = ''; +my ( @tmp, @arptmp, @myarray, @status, @arpclients ) = ''; +my @ifaces = ('GREEN','BLUE','ORANGE'); + + +if ( $mailsettings{'USEMAIL'} eq 'on' ) { $mailen = 'on'; } +else { $mailen = 'off'; } + +if ( -e $redactive ) { + open(IPADDR, "/var/ipfire/red/local-ipaddress"); + $redip = <IPADDR>; + close IPADDR; + chomp($redip); +} + +if ($debug) { + $start = [gettimeofday]; + startdebug(); +} + +foreach (@ifaces) { + if ( $netsettings{"${_}_DEV"} ne '' && $netsettings{"${_}_DEV"} ne 'disabled' ) { + my $output = `ifconfig $netsettings{"${_}_DEV"}`; + + if ( grep (/RX bytes:0/, $output) ) { next; } + else { + @arptmp = `/usr/local/bin/wioscan -s $netsettings{"${_}_DEV"}`; + + foreach $arpclient (@arptmp) { + push (@arpclients, (split (/,/,$arpclient))[1]); + } + } + $output = ''; + undef(@arptmp); + } +} + +if ( -e "$onoffip" ) { open( FILE, "< $onoffip" ); } +else { open( FILE, "< $ipadrfile" ); } +@myarray = <FILE>; +close(FILE); + +# ping all clients + +foreach (@myarray) { + chomp; + @tmp = split( /,/, $_ ); + + ($id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost) = @tmp; + + $timestamp = strftime "%d.%m.%Y - %H:%M:%S", localtime; + + if ( $enable ne 'on' ) { + push (@status, "$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost\n"); + next; + } + + if ( defined($dyndns) && ( $dyndns =~ 'on' ) ) { + ($dyndnsip, $infomsg) = &WIO::getdyndnsip($host, @myarray); + if ($dyndnsip ne $ipadr) { $ipadr = $dyndnsip; } + } + + $ping_i = $ping_t = $ping_ib = $ping_tb = $ping_iv = $ping_tv = $pingmode = $arp = 0; + + foreach (@arpclients) { + chomp; + unless ( $ipadr eq $_ ) + { + $i = Net::Ping->new( $i_ping, $timeout ); + unless ( defined $i ) { die "Can't create Net::Ping object $!"; } + + $t = Net::Ping->new( $t_ping, $timeout ); + unless ( defined $t ) { die "Can't create Net::Ping object $!"; } + + $ib = Net::Ping->new( $i_ping, $timeout ); + unless ( defined $ib ) { die "Can't create Net::Ping object $!"; } + $ib->bind($redip); + + $tb = Net::Ping->new( $t_ping, $timeout ); + unless ( defined $tb ) { die "Can't create Net::Ping object $!"; } + $tb->bind($redip); + + if ($ovpnpid || $vpnpid) + { + $ivpn = Net::Ping->new( $i_ping, $timeout ); + unless ( defined $ivpn ) { die "Can't create Net::Ping object $!"; } + $ivpn->bind($hostname); + + $tvpn = Net::Ping->new( $t_ping, $timeout ); + unless ( defined $tvpn ) { die "Can't create Net::Ping object $!"; } + $tvpn->bind($hostname); + } + } + else { $arp = 1 } + } + + $client = ( ( $dyndns eq 'on' || $ping eq 'fqdn' ) ? $host : $ipadr ); + + if ($debug) { + printf "%2s %15s", $nr++, ($client ne $ipadr ? $ipadr : $client ); + $time = [gettimeofday]; + } + + if ( $arp == 1 + || ($ping_i = $i->ping($client)) + || ($ping_t = $t->ping($client)) + || ($ping_ib = $ib->ping($client)) + || ($ping_tb = $tb->ping($client)) + || ($ovpnpid?($ping_iv = $ivpn->ping($client)) : 0) + || ($vpnpid?($ping_tv = $tvpn->ping($client)) : 0) ) + { + $mode = 100; + $msg = "$Lang::tr{'wio up'}"; + $onbak = $on; + $togglestat = ( $on ne 'on' ) ? 1 : 0; + $on = 'on'; + } + else { + $mode = 0; + $msg = "$Lang::tr{'wio down'}"; + $onbak = $on; + $togglestat = ( $on ne 'off' ) ? 1 : 0; + $on = 'off'; + } + + push (@status, "$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost\n"); + + if ($debug) { + $mail = '----'; + if ( $mailon eq 'on' && $togglestat == 1 && $mode == 100 ) { $mail = 'Online'; } + if ( $mailoff eq 'on' && $togglestat == 1 && $mode == 0 ) { $mail = 'Offline'; } + if ( $dyndns ne 'on' ) { $dyndns = 'off'; } + + $pingmode = $arp ? 'ARPSCAN' : $ping_i ? 'ICMP' : $ping_t ? 'TCP' : $ping_ib ? 'ICMP+BIND' : $ping_tb ? 'TCP+BIND' : $ping_iv ? 'VPN ICMP' : $ping_tv ? 'VPN TCP' : 'NO ECHO'; + printf "%7s%8s%9s%10s %.4f sek%12s\n", $ping, $dyndns, $msg, $mail, tv_interval($time), $pingmode; + } + + if ( $host eq '' ) { $hostnew = 'n/a'; } else { $hostnew = $host; } + if ( $ipadr eq '' ) { $ipadrnew = 'n/a'; } else { $ipadrnew = $ipadr; } + + if ( $logging eq 'on' ) { + $logmsg = "Client: $hostnew - IP: $ipadrnew - Status: $msg"; + &General::log("wio","$logmsg"); + } + + if ( $mailen eq 'on' && $togglestat == 1 && ($mailon eq 'on' || $mailoff eq 'on')) { + + if ( $mailstyle eq 'email' || ($mailstyle eq 'smail' && $smailtxt eq '') ) { $mailmsg .= "Date\t : $now\n\n"; } + + $mailmsg .= "Client\t : $hostnew\nIP\t : $ipadrnew\nStatus\t : $msg\n"; + + if ( $mailremark eq 'on' && $remark ne '' ) { + $mailmsg .= "Remark : $remark\n\n"; + } + + if ( $mailstyle eq 'email' ) { + &WIO::mailsender("WIO - $host - $msg", $mailmsg); + undef ($mailmsg); + } + elsif ( $mailstyle eq 'smail' ) { + $smailtxt .= $mailmsg."\n"; + undef ($mailmsg); + } + } + + if ( $ping ne 'fqdn' ) { $client = $host; } + if ( $host eq '' ) { $client = $ipadr; } + + updatewiodata("$id"); + + if ( $arp == 0 ) { + $i->close(); + $t->close(); + $ib->close(); + $tb->close(); + } + + if ( ( -e $ovpnpid || -e $vpnpid ) && $arp == 0 ) { + $ivpn->close(); + $tvpn->close(); + } +} + +# write adressfile new + +if ( !-e $onoffip ) { + open( FILE, "> $ipadrfile" ); + print FILE @status; + close(FILE); +} +else { + system("/bin/sed -i 's#$tmp[0],$tmp[1],$tmp[2],$tmp[3],$tmp[4],$tmp[5],$tmp[6],$tmp[7],$tmp[8],$tmp[9],$tmp[10],$tmp[11]#$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost#g' $ipadrfile"); + chmod ( 0644, $ipadrfile ); + chown ( $owner, $group, $ipadrfile ); +} + +if ($debug) { + printf ("\n$Lang::tr{'wio_scriptruntime'}: %.4f $Lang::tr{'age ssecond'}\n\n", tv_interval($start)); +} + +if ( $smailtxt ne '' ) { &WIO::mailsender($Lang::tr{'wio_sub'}, $smailtxt); } + +if ($shutdown eq 'on') { + foreach (@status) { + chomp; + @tmp = split( /,/, $_ ); + + ($id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost) = @tmp; + + if ( $on eq 'on' ) { + $poweroff = 0; + last; + } + else { + $poweroff = 1; + next; + } + } + + if ($poweroff == 1) { + if ($debug) { + printf "$Lang::tr{'shutting down ipfire'}!\n\n"; + } + + &General::log("wio","$Lang::tr{'shutting down ipfire'}!"); + system '/usr/local/bin/ipfirereboot down'; + } +} + +undef (@tmp); +undef (@myarray); +undef (@status); +undef (@arptmp); +undef (@arpclients); + +if ( -e $onoffip ) { unlink($onoffip); } + +sub updatewiodata { + my $id = $_[0]; + + if ( !-e "$rrddir/$id.rrd" ) { + RRDs::create( + "$rrddir/$id.rrd", "--step=$steptime", + "DS:mode:GAUGE:3600:0:100", "RRA:AVERAGE:0.5:1:576", + "RRA:AVERAGE:0.5:6:672", "RRA:AVERAGE:0.5:24:732", + "RRA:AVERAGE:0.5:144:1460" + ); + my $ERROR = RRDs::error; + print "Error in RRD::create for Who Is Online: $ERROR\n" if $ERROR; + } + + RRDs::update( "$rrddir/$id.rrd", "-t", "mode", "N:$mode" ); + + my $error = RRDs::error; + + if ($error) { &General::log("wio","$error"); } +} + +sub startdebug { + +printf " +HOSTNAME : $hostname +TIMEOUT : $timeout $Lang::tr{'age ssecond'} +MAILSTYLE : $mailstyle +RED TYPE : $netsettings{'RED_TYPE'} +RED DEVICE : $reddev +RED ADDRESS : $redip +SHUTDOWN : $shutdown +"; + if ($ovpnpid) {printf "OVPN PID : $ovpnpid"} + if ($vpnpid) {printf "VPN PID : $vpnpid"} +printf " +$Lang::tr{'wio_search'} + +%3s%17s%7s%8s%9s%10s%15s%12s +--------------------------------------------------------------------------------- +","ID ", "$Lang::tr{'wio ipadress'}", "Ping", "DynDNS", "Status", "Mail", "$Lang::tr{'wio_answer_time'}", "$Lang::tr{'wio_answer'}"; +} + +sub help { + return " +Who Is Online? for IPFire + +use option -d for debugging +use option -h for help\n\n"; +} diff --git a/src/wio/main/wiovpn.pl b/src/wio/main/wiovpn.pl new file mode 100644 index 0000000..f22bd7a --- /dev/null +++ b/src/wio/main/wiovpn.pl @@ -0,0 +1,293 @@ +#!/usr/bin/perl +# +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 Stephan Feddersen addons@h-loit.de # +# All Rights Reserved. # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### +# +# id: wioovpn.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen +# +# This wioovpn.pl is based on the Code from the IPCop WIO Addon +# and is extremly adapted to work with IPFire. +# +# Autor: Stephan Feddersen +# Co-Autor: Alexander Marx +# Co-Autor: Frank Mainz +# + +# enable only the following on debugging purpose +#use warnings; + +use strict; +use POSIX qw(strftime); + +my $logdir = "/var/log/wio"; + +require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/lang.pl'; +require '/usr/lib/wio/wio-lib.pl'; + +my %wiosettings = (); + +&General::readhash( "/var/ipfire/wio/wio.conf", %wiosettings ); + +my $mailremark = $wiosettings{'MAILREMARK'}; +my $logging = $wiosettings{'LOGGING'}; + +my ( @ovpnstatus, @ovpncfg, @ovpncache, @ovpnarray, @ovpnmatch, @ovpnwrite ); + +my $now = strftime "%a, %d.%m.%Y %H:%M:%S", localtime; +my $ovpnpid = "/var/run/openvpn.pid"; +my $ovpnmailmsg = ''; +my $ovpncache = "$logdir/.ovpncache"; +my $ovpnconfig = "/var/ipfire/ovpn/ovpnconfig"; + +my ( $name, $nameul, $ovpnclt, $ovpncltip, $realipadr, $connected ) = ''; +my ( $ovpnmailsub, $ovpnrwlogin, $ovpnrwstatus, $status, $remark, $logmsg ) = ''; + +my ( @vpnstatus, @vpncfg, @vpncache, @vpnarray, @vpnwrite ); + +my $vpnpid = "/var/run/charon.pid"; +my $vpnmailmsg = ''; +my $vpncache = "$logdir/.vpncache"; +my $vpnconfig = "/var/ipfire/vpn/config"; + +my ( $activ, $vpnmailsub, $vpnrwstatus, $status,) = ''; + +my $togglestat = 0; + +if ( ! -e "$ovpnpid" ) { + unlink "$ovpncache"; +} +else { + +@ovpnstatus = `cat /var/run/ovpnserver.log`; + +open(FILE, "$ovpnconfig"); +@ovpncfg = <FILE>; +close (FILE); + +unless ( -e "$ovpncache" ) { + open(FILE, ">$ovpncache"); + close (FILE); +} +else { + open(FILE, "$ovpncache"); + @ovpncache = <FILE>; + close (FILE); +} + +foreach (@ovpncfg) +{ + chomp; + + if ( $_ =~ "server" ) { next; } + + ( $name, $remark ) = (split (/,/, $_))[3, 26]; + + $status = 'off'; + + unless ( grep (/$name/, @ovpncache) ) { push (@ovpncache, "$name,$remark,$status\n"); } +} + +foreach (@ovpncache) +{ + chomp; + + ( $name, $remark, $status ) = split (/,/, $_); + + if ( grep (/,$name,/, @ovpncfg) ) { push (@ovpnarray, "$name,$remark,$status\n"); } +} + +foreach (@ovpnarray) +{ + chomp; + ( $name, $remark, $status ) = split (/,/, $_); + + if ( $name =~ m/_/ ) { $nameul = $name; } + else { ($nameul = $name) =~ s/ /_/g; } + + if ( grep (/$name/, @ovpnstatus) || grep (/$nameul/, @ovpnstatus) ) + { + foreach (@ovpnstatus) + { + chomp; + + if ( $_ =~ "ROUTING TABLE" ) { last; } + + @ovpnmatch = split (/,/, $_); + + if ( @ovpnmatch != 5 || $_ =~ "Common Name" ) { next; } + + ( $ovpnclt, $realipadr, undef, undef, $connected ) = @ovpnmatch; + + ( $ovpncltip, undef ) = split (/:/, $realipadr); + + $ovpnrwlogin = &WIO::statustime($connected); + + if ( $nameul eq $ovpnclt || $name eq $ovpnclt ) { + $ovpnrwstatus = "$Lang::tr{'wio up'}"; + $togglestat = ( $status ne 'on' ) ? 1 : 0; + $status = 'on'; + } + + if ( ! $name =~ m/_/ ) { $ovpnclt =~ s/_/ /g; } + + if ( $nameul eq $ovpnclt || $name eq $ovpnclt ) { push (@ovpnwrite, "$name,$remark,$status\n"); } + + if ( $togglestat == 1 && ($name eq $ovpnclt || $nameul eq $ovpnclt) ) + { + $ovpnmailsub = "WIO OVPN - $name - $ovpnrwstatus - $now"; + $logmsg = "Client: WIO OVPN $name - IP: $ovpncltip - Status: $ovpnrwstatus"; + $ovpnmailmsg = "Client : $name\nLogin : $ovpnrwlogin\nIP : $ovpncltip\nStatus : $ovpnrwstatus\n"; + + if ( $mailremark eq 'on' ) { + $ovpnmailmsg .= "Remark : $remark\n\n"; + } + + &WIO::mailsender($ovpnmailsub, $ovpnmailmsg); + if ( $logging eq 'on' ) { &General::log("wio","$logmsg"); } + undef ($ovpnmailsub); + undef ($ovpnmailmsg); + $togglestat = 0; + } + } + } + else { + if ( $status eq 'on' ) { + $ovpnrwstatus = "$Lang::tr{'wio down'}"; + $status = 'off'; + $ovpnmailsub = "WIO OVPN - $name - $ovpnrwstatus - $now"; + $logmsg = "Client: WIO OVPN $name - Status: $ovpnrwstatus"; + $ovpnmailmsg = "Client : $name\nLogout : $now\nStatus : $ovpnrwstatus\n"; + + if ( $mailremark eq 'on' ) { + $ovpnmailmsg .= "Remark : $remark\n\n"; + } + + &WIO::mailsender($ovpnmailsub, $ovpnmailmsg); + if ( $logging eq 'on' ) { &General::log("wio","$logmsg"); } + undef ($ovpnmailsub); + undef ($ovpnmailmsg); + } + + push (@ovpnwrite, "$name,$remark,$status\n"); + } +} + +open( FILE, "> $ovpncache" ); +print FILE @ovpnwrite; +close(FILE); + +} + +if ( ! -e "$vpnpid" ) { + unlink "$vpncache"; +} +else { + +if ( -e "$vpnpid" ) { + @vpnstatus = `/usr/local/bin/ipsecctrl I`; +} + +open(FILE, "$vpnconfig"); +@vpncfg = <FILE>; +close (FILE); + +if ( ! -e "$vpncache" ) { + open(FILE, ">$vpncache"); + close (FILE); +} +else { + open(FILE, "$vpncache"); + @vpncache = <FILE>; + close (FILE); +} + +foreach (@vpncfg) +{ + chomp; + + ( $activ, $name, $remark ) = (split (/,/, $_))[1, 2, 25]; + + if ( $remark eq 'off' ) { $remark = '-'; } + + $status = 'off'; + + if ( $activ eq "off" ) { next; } + + unless ( grep (/$name/, @vpncache) ) { push (@vpncache, "$name,$remark,$status\n"); } +} + +foreach (@vpncache) +{ + chomp; + + ( $name, $remark, $status ) = split (/,/, $_); + + if ( grep (/,$name,/, @vpncfg) ) { push (@vpnarray, "$name,$remark,$status\n"); } +} + +foreach (@vpnarray) +{ + chomp; + + ( $name, $remark, $status ) = split (/,/, $_); + + if ( grep (/$name{.*INSTALLED/ , @vpnstatus) ) + { + $vpnrwstatus = "$Lang::tr{'wio up'}"; + $togglestat = ( $status ne 'on' ) ? 1 : 0; + $status = 'on'; + } + else { + $vpnrwstatus = "$Lang::tr{'wio down'}"; + $togglestat = ( $status ne 'off' ) ? 1 : 0; + $status = 'off'; + } + + push (@vpnwrite, "$name,$remark,$status\n"); + + if ( $togglestat == 1 ) + { + $vpnmailsub = "WIO VPN - $name - $vpnrwstatus - $now"; + $logmsg = "Client: WIO VPN $name - Status: $vpnrwstatus $now"; + + if ( $mailremark eq 'on' ) { + if ( $status eq 'on' ) { $vpnmailmsg = "Client : $name\nLogin : $now\nStatus : $vpnrwstatus\nRemark : $remark\n"; } + else { $vpnmailmsg = "Client : $name\nLogout : $now\nStatus : $vpnrwstatus\nRemark : $remark\n"; } + } + else { + if ( $status eq 'on' ) { $vpnmailmsg = "Client : $name\nLogin : $now\nStatus : $vpnrwstatus\n"; } + else { $vpnmailmsg = "Client : $name\nLogout : $now\nStatus : $vpnrwstatus\n"; } + } + + &WIO::mailsender($vpnmailsub, $vpnmailmsg); + if ( $logging eq 'on' ) { &General::log("wio","$logmsg"); } + undef ($vpnmailsub); + undef ($vpnmailmsg); + $togglestat = 0; + } +} + +open( FILE, "> $vpncache" ); +print FILE @vpnwrite; +close(FILE); + +} diff --git a/src/wio/wio b/src/wio/wio new file mode 100644 index 0000000..dea5e57 --- /dev/null +++ b/src/wio/wio @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Script to run wio helpers +# +. /var/ipfire/wio/wio.conf + +MINUTE=`date +%M` + +if [ $ENABLE == on ]; then + + if [ $(($MINUTE%$CRON)) == 0 ]; then + /var/ipfire/wio/wio.pl > /dev/null + fi + + if [ $OVPNRWMAIL == on ]; then + if [ $(($MINUTE%$OVPNCRON)) == 0 ]; then + /var/ipfire/wio/wiovpn.pl > /dev/null + fi + else + rm -f /var/log/wio/.vpncache + rm -f /var/log/wio/.ovpncache + fi + +fi diff --git a/src/wio/wio-graphs.pl b/src/wio/wio-graphs.pl new file mode 100644 index 0000000..a5a58b4 --- /dev/null +++ b/src/wio/wio-graphs.pl @@ -0,0 +1,127 @@ +#!/usr/bin/perl +# +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 Stephan Feddersen addons@h-loit.de # +# All Rights Reserved. # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### +# +# id: wio-graphs.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen +# +# This wio-graphs.pl is based on the Code from the IPCop WIO Addon +# and is extremly adapted to work with IPFire. +# +# Autor: Stephan Feddersen +# Co-Autor: Alexander Marx +# + +package WIOGraphs; + +use strict; + +# enable only the following on debugging purpose +#use warnings; + +use RRDs; + +require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/lang.pl'; + +my ( %mainsettings, %color ) = (); + +&General::readhash('/var/ipfire/main/settings', %mainsettings); +&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", %color); + +sub wio { + my $hostid = $_[0]; + my $hostname = $_[1]; + my $period = $_[2]; + + my @rrd = (); + + push @rrd, ("-"); + push @rrd, @{&header($period, "$hostname ($Lang::tr{$period})")}; + push @rrd, @{&body($hostid)}; + + RRDs::graph (@rrd); + + my $error = RRDs::error; + print "Error in RRD::graph for Who Is Online: $error\n" if $error; +} + +sub body { + my $hostid = shift; + my $result = []; + + push @$result, "DEF:mode=/var/log/rrd/wio/$hostid.rrd:mode:AVERAGE"; + push @$result, "CDEF:online=mode,UN,0,mode,IF,50,GT,100,0,IF"; + push @$result, "CDEF:offline=mode,UN,100,mode,IF,50,LT,100,0,IF"; + push @$result, "AREA:online".$color{"color12"}.":$Lang::tr{'wio up'}\j"; + push @$result, "AREA:offline".$color{"color13"}.":$Lang::tr{'wio down'}\j"; + push @$result, "COMMENT:\r<span size='smaller'>$Lang::tr{'wio_last_update'}\: ". lastupdate(scalar localtime()) ."</span>\r"; + + return $result; +} + +sub lastupdate { + my $text = shift; + + return undef if not defined $text; + $text =~ s/\/\\/g; + $text =~ s/:/\:/g; + + return $text; +} + +sub header { + my $period = shift; + my $title = shift; + my $result = []; + + push @$result, ("--title", "$title"); + push @$result, ("--start", "-1$period", "-aPNG", "-i", "-z"); + push @$result, ("--border", "0"); + push @$result, ("--full-size-mode"); + push @$result, ("--slope-mode"); + push @$result, ("--pango-markup"); + push @$result, ("--alt-y-grid", "-w 910", "-h 300"); + if ( $period eq 'day' ) { push @$result, ("--x-grid", "MINUTE:30:HOUR:1:HOUR:2:0:%H:%M"); } + push @$result, ("--color", "SHADEA".$color{"color19"}); + push @$result, ("--color", "SHADEB".$color{"color19"}); + push @$result, ("--color", "BACK".$color{"color21"}); + + return $result; +} + +sub wiographbox { + print "<center>"; + print "<table width='100%' cellspacing='0'>"; + print "<tr>"; + print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?hour?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'hour'}."</b></a></td>"; + print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?day?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'day'}."</b></a></td>"; + print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?week?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'week'}."</b></a></td>"; + print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?month?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'month'}."</b></a></td>"; + print "<td align='center' bgcolor='".$color{"color20"}."'><a href='".$_[0]."?".$_[1]."?year?".$_[3]."' target='".$_[1]."box'><b>".$Lang::tr{'year'}."</b></a></td>"; + print "</tr>"; + print "</table>"; + print "<table width='100%' cellspacing='0'>"; + print "<tr><td align='center' colspan='8'> </td></tr>"; + print "<tr><td align='center' colspan='8'><iframe class='graph' src='".$_[0]."?".$_[1]."?".$_[2]."?".$_[3]."' scrolling='no' marginheight='0' frameborder='no' name='".$_[1]."box'></iframe></td></tr>"; + print "</table>"; + print "</center>"; +} diff --git a/src/wio/wio-lib.pl b/src/wio/wio-lib.pl new file mode 100644 index 0000000..2f23c1d --- /dev/null +++ b/src/wio/wio-lib.pl @@ -0,0 +1,206 @@ +#!/usr/bin/perl +# +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 Stephan Feddersen addons@h-loit.de # +# All Rights Reserved. # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### +# +# id: wio-lib.pl, v1.3.1 2017/07/11 21:31:16 sfeddersen +# +# This wio-lib.pl is based on the Code from the IPCop WIO Addon +# and is extremly adapted to work with IPFire. +# +# Autor: Stephan Feddersen +# Co-Autor: Alexander Marx +# Co-Autor: Frank Mainz +# + +package WIO; + +# enable only the following on debugging purpose +#use warnings; + +use strict; +use Socket; +use Time::Local; +use MIME::Lite; + +require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/header.pl'; +require '/var/ipfire/lang.pl'; + +my $mailfile = "${General::swroot}/dma/mail.conf"; +my %mail = (); +&General::readhash($mailfile, %mail); + +my $redactive = "/var/ipfire/red/active"; +my $msg = ''; + +############################################################################################################################ + +sub getdyndnsip { + my $ipadr = $_[0]; + my $host = $_[1]; + my @fetchip = (); + + if ( -e $redactive ) { + @fetchip = gethostbyname($host); + + if ( defined($fetchip[0]) ) { + @fetchip = map ( &Socket::inet_ntoa($_), @fetchip[4..$#fetchip]); + return ($fetchip[0], $Lang::tr{'wio_dyndns_success'}); + } + } + else { + return ($ipadr, $Lang::tr{'wio_dyndns_info'}); + } +} + +############################################################################################################################ + +sub contime { + my $str = $_[0]; + my %m = (); + @m{qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/} = (0 .. 11); + + if ( $str =~ /^\w{3}\ ([a-zA-Z]+)\ (\d{1,2})\ (\d{2}):(\d{2}):(\d{2}) (\d{4})$/ || + $str =~ /^\w{3}\ ([a-zA-Z]+)\ (\d{1})\ (\d{2}):(\d{2}):(\d{2}) (\d{4})$/ ) + { + my $past = timelocal($5, $4, $3, $2, $m{$1}, $6); + my $now = time; + + my $totalsecs = $now - $past; + my $days = int($totalsecs / 86400); + my $totalhours = int($totalsecs / 3600); + my $hours = $totalhours % 24; + my $totalmins = int($totalsecs / 60); + my $mins = $totalmins % 60; + my $secs = $totalsecs % 60; + + return "${days}d ${hours}h ${mins}m ${secs}s"; + } + else { + return; + } +} + +############################################################################################################################ + +sub statustime { + my $str = $_[0]; + my ( $day, $mon ) = ''; + + my %m = qw ( Jan 01 Feb 02 Mar 03 Apr 04 May 05 Jun 06 Jul 07 Aug 08 Sep 09 Oct 10 Nov 11 Dec 12 ); + + if ( $str =~ /^\w{3}\ ([a-zA-Z]+)\ (\d{1,2})\ (\d{2}):(\d{2}):(\d{2}) (\d{4})$/ || + $str =~ /^\w{3}\ ([a-zA-Z]+)\ (\d{1})\ (\d{2}):(\d{2}):(\d{2}) (\d{4})$/ ) + { + $mon = $m{$1}; + + if (length $2 < 2) { $day = "0$2"; } + else { $day = $2; } + + return "$day.$mon.$6 - $3:$4:$5"; + } + else { + return; + } +} + +############################################################################################################################ + +sub mailsender { + $msg = MIME::Lite->new( + From => $mail{'SENDER'}, + To => $mail{'RECIPIENT'}, + Subject => $_[0], + Type => 'multipart/mixed' + ); + + $msg->attach( + Type => 'TEXT', + Data => $_[1] + ); + + $msg->send_by_sendmail; +} + +############################################################################################################################ + +sub checkinto { + my ($checkip, $checkhost, @checkfile) = @_; + + if ( $checkip ne '' ) { + foreach (@checkfile) { + chomp; + if ( (split (/,/, $_))[2] eq $checkip ) { return $Lang::tr{'wio_ip_exists'}; last; } + } + } + + if ( $checkhost ne '' ) { + foreach (@checkfile) { + chomp; + if ( (split (/,/, $_))[3] eq $checkhost ) { + if ( $checkip ne '' ) { + my $fileip = (split (/,/, $_))[2]; + + $fileip =~ /^(\d+).(\d+).(\d+).(\d+)$/; + + my $fileip1 = $1; + my $fileip2 = $2; + my $fileip3 = $3; + my $fileip4 = $4; + + $checkip =~ /^(\d+).(\d+).(\d+).(\d+)$/; + + if ( $fileip1 == $1 && $fileip2 == $2 && $fileip3 == $3 ) { + return $Lang::tr{'wio_host_exists'}; last; } + } + else { return $Lang::tr{'wio_host_exists'}; last; } + } + } + } + + return; +} + +############################################################################################################################ + +sub clearfile { + my $file = $_[0]; + + open(FILE, "> $file"); + close(FILE); +} + +############################################################################################################################ + +sub color_devices() { + my $output = shift; + + if ( uc($output) eq "GREEN0" ) { $output = "<b><font color ='$Header::colourgreen'>$output</b>";} + elsif ( uc($output) eq "BLUE0" ) { $output = "<b><font color ='$Header::colourblue'>$output</b>"; } + elsif ( uc($output) eq "ORANGE0" ) { $output = "<b><font color ='$Header::colourorange'>$output</b>"; } + elsif ( uc($output) eq "RED0" ) { $output = "<b><font color ='$Header::colourred'>$output</b>"; } + else { return $output = "<b><font color ='#696565'>$output</b>"; } + + return $output; +} + +return 1; diff --git a/src/wio/wio.cgi b/src/wio/wio.cgi new file mode 100644 index 0000000..631e468 --- /dev/null +++ b/src/wio/wio.cgi @@ -0,0 +1,2143 @@ +#!/usr/bin/perl +# +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 Stephan Feddersen addons@h-loit.de # +# All Rights Reserved. # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### +# +# id: wio.cgi, v1.3.1 2017/07/11 21:31:16 sfeddersen +# +# This wio.cgi is based on the Code from the IPCop WIO Addon +# and is extremly adapted to work with IPFire. +# +# Autor: Stephan Feddersen +# Co-Autor: Alexander Marx +# Co-Autor: Frank Mainz +# + +use strict; + +# enable only the following on debugging purpose +#use warnings; +#no warnings 'once'; +#use CGI::Carp 'fatalsToBrowser'; + +my $debug = 0; + +use Socket; +use POSIX qw(strftime); +use File::Copy; +use Fatal qw/ open /; +use Net::Telnet; + +require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/lang.pl'; +require '/var/ipfire/header.pl'; +require '/usr/lib/wio/wio-lib.pl'; +require '/usr/lib/wio/wio-graphs.pl'; + +my $logdir = "/var/log/wio"; + +my ( %mainsettings, %mailsettings, %wiosettings, %cgiparams, %netsettings, %ipshash, + %vpnconfighash, %ovpnconfighash, %ovpnccdconfhash, %ovpnsettings, %checked, %selected, %color ) = (); + +&General::readhash('/var/ipfire/main/settings', %mainsettings); +&General::readhash('/var/ipfire/ethernet/settings', %netsettings); +&General::readhash('/var/ipfire/dma/mail.conf', %mailsettings); +&General::readhash('/var/ipfire/wio/wio.conf', %wiosettings); +&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", %color); +&General::readhasharray('/var/ipfire/ovpn/ovpnconfig', %ovpnconfighash); +&General::readhash('/var/ipfire/ovpn/settings', %ovpnsettings); +&General::readhasharray('/var/ipfire/ovpn/ccd.conf', %ovpnccdconfhash); +&General::readhasharray('/var/ipfire/vpn/config', %vpnconfighash); + +my $ipadrfile = "$logdir/wioips"; +my $onoffip = "$logdir/wioscip"; +my $wiosettings = "/var/ipfire/wio/wio.conf"; +my $dyndnsconfig = "/var/ipfire/ddns/config"; +my $importfile = "$logdir/importfile"; +my $wiofile = "$logdir/wiofile"; +my $editfile = "$logdir/editfile"; +my $hostfile = "/var/ipfire/main/hosts"; +my $dhcpfile = "/var/ipfire/dhcp/fixleases"; +my $imgstatic = "/images/wio"; +my $rrddir = "/var/log/rrd/wio"; +my $refreshbox = '<meta http-equiv="refresh" content="0;url=/cgi-bin/wio.cgi">'; +my $sortstring = '^IPADR|^HOST'; +my $ovpnaddon = "/var/ipfire/ovpn"; +my $ovpnpid = "/var/run/openvpn.pid"; +my $vpnpid = "/var/run/charon.pid"; +my $redactive = "/var/ipfire/red/active"; +my $redip = '-'; +my $now = strftime "%Y-%m-%d", localtime; + +if ( -e $redactive ) { + open(IPADDR, "/var/ipfire/red/local-ipaddress"); + $redip = <IPADDR>; + close IPADDR; + chomp($redip); +} + +my $i = 0; +my $idarp = 0; +my $iddyndns = 0; +my $idvpn = 0; +my $idovpn = 0; +my $idsort = 0; +my $nr = 0; +my $count = 0; +my $showcount = 0; + +my ( $infomessage, $errormessage, $importmessage, $message ) = ''; + +my ( $buttontext, $host, $timestamp, $ipadr, $on, $remark, $dyndns, $dyndnsip, $sendemailon, $net, $dev, $iprange, $output, $write, $webinterface, + $sendemailoff, $pingmethode, $online, $color, $bgcolor, $exitcode, $id, $line, $interface, $counter, $vpnn2nip, $vpnn2nmask, $ddns, $edc, + $edd, $wmon, $wmoff, $ipfqdn, $http, $wioscan, $statustxt, $status, $key, $ic, $text, $image ) = (); + +my ( @temp, @dates, @ipaddresses, @names, @remark, @sendemailon, @sendemailoff, @current, @ddns, @match, @webinterface, @arpcache, @arpadd, @line, + @hosts, @vpnstatus, @ovpnstatus, @activ, @dyndns, @pingmethode, @status, @id, @write, @log ); + +my @nosaved = ('ACTION','ID','CLIENTID','TIMESTAMP','IPADR','HOST','REMARK','DYNDNS','SENDEMAILON','SENDEMAILOFF','PINGMETHODE','ONLINE','WEBINTERFACE'); + +my @devs_color = ('GREEN','BLUE','ORANGE','RED'); +my @devs_net = ('green0','blue0','orange0','red0'); +my @devs_img = ('green.png','blue.png','orange.png','red.png'); +my @devs_alt = ('green','blue','orange','red'); + +my %ifacecolor = ( GREEN => 'wio_run_green', BLUE => 'wio_run_blue', ORANGE => 'wio_run_orange'); + +&loadips(); + +## some wio settings + +$wiosettings{'ACTION'} = ''; +$wiosettings{'COUNT'} = ''; +$wiosettings{'ID'} = ''; +$wiosettings{'CLIENTID'} = ''; +$wiosettings{'SORT'} = 'IPADR'; +$wiosettings{'HOST'} = ''; +$wiosettings{'IPADR'} = ''; +$wiosettings{'EN'} = 'on'; +$wiosettings{'REMARK'} = ''; +$wiosettings{'DYNDNS'} = ''; +$wiosettings{'CLIENTREMARK'} = ''; +$wiosettings{'SENDEMAILON'} = ''; +$wiosettings{'SENDEMAILOFF'} = ''; +$wiosettings{'PINGMETHODE'} = 'ip'; +$wiosettings{'WEBINTERFACE'} = '----'; +$wiosettings{'TIMEOUT'} = '1'; +$wiosettings{'TIMESTAMP'} = ''; +$wiosettings{'ONLINE'} = 'off'; +$wiosettings{'CRON'} = '15'; +$wiosettings{'OVPNCRON'} = '5'; +$wiosettings{'ENABLE'} = 'off'; +$wiosettings{'LOGGING'} = 'off'; +$wiosettings{'MAILREMARK'} = 'off'; +$wiosettings{'MAILSTYLE'} = 'email'; +$wiosettings{'OVPNRWMAIL'} = 'off'; +$wiosettings{'SHUTDOWN'} = 'off'; + +&Header::getcgihash(%wiosettings); +&Header::getcgihash(%mainsettings); +&Header::getcgihash(%mailsettings); +&Header::getcgihash(%netsettings); + +if ( $mailsettings{'USEMAIL'} eq 'on' ) { $wiosettings{'SENDEMAIL'} = 'on'; } +else { $wiosettings{'SENDEMAIL'} = 'off'; } + +if ( -e $wiofile ) { goto WIOSCAN; } + +## get network ips +foreach (@devs_color) { + if ( $netsettings{"${_}_DEV"} ne '' ) { + + $wiosettings{"${_}_IPLOW"} = inet_ntoa pack q/N/, (unpack (q/N/, inet_aton ($netsettings{"${_}_NETADDRESS"}))+1); + my @addrarr = split(/./,$netsettings{"${_}_ADDRESS"}); + my $ipaddress = unpack( "N", pack( "C4",@addrarr ) ); + + my @maskarr = split(/./,$netsettings{"${_}_NETMASK"}); + my $netmask = unpack( "N", pack( "C4",@maskarr ) ); + + my $bcast = ( $ipaddress & $netmask ) + ( ~ $netmask ); + my @bcastarr = inet_ntoa pack q/N/, (unpack (q/N/, inet_aton ($bcast))-1); + + $wiosettings{"${_}_IPHIGH"} = join(".",@bcastarr); + } +} + +## save wio settings + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_save'}.'1' ) { + unless ( `ps -A | grep wio.pl` ) { + $cgiparams{'SORT'} = $wiosettings{'SORT'}; + $cgiparams{'CRON'} = $wiosettings{'CRON'}; + $cgiparams{'OVPNCRON'} = $wiosettings{'OVPNCRON'}; + $cgiparams{'ENABLE'} = $wiosettings{'ENABLE'}; + $cgiparams{'LOGGING'} = $wiosettings{'LOGGING'}; + $cgiparams{'TIMEOUT'} = $wiosettings{'TIMEOUT'}; + $cgiparams{'ACTION'} = $wiosettings{'ACTION'}; + $cgiparams{'CLIENTREMARK'} = $wiosettings{'CLIENTREMARK'}; + $cgiparams{'MAILREMARK'} = $wiosettings{'MAILREMARK'}; + $cgiparams{'MAILSTYLE'} = $wiosettings{'MAILSTYLE'}; + $cgiparams{'OVPNRWMAIL'} = $wiosettings{'OVPNRWMAIL'}; + $cgiparams{'SHUTDOWN'} = $wiosettings{'SHUTDOWN'}; + + &General::writehash($wiosettings, %cgiparams); + &General::readhash($wiosettings, %wiosettings); + + if ( $wiosettings{'ENABLE'} eq 'off' ) { + &WIO::clearfile($ipadrfile); + unlink glob "$rrddir/*"; + } + } + else { + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## save imported clients + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_save'}.'2' ) { + unless ( `ps -A | grep wio.pl` ) { + while ( $count < $wiosettings{'COUNT'} ) { + if ( defined($wiosettings{"USE$count"}) && $wiosettings{"USE$count"} eq 'on' ) { + $wiosettings{'CLIENTID'} = $wiosettings{'CLIENTID$count'}; + $wiosettings{'TIMESTAMP'} = $wiosettings{"TIMESTAMP$count"}; + $wiosettings{'IPADR'} = $wiosettings{"IPADR$count"}; + $wiosettings{'HOST'} = $wiosettings{"HOST$count"}; + $wiosettings{'EN'} = $wiosettings{"EN$count"}; + $wiosettings{'REMARK'} = $wiosettings{"REMARK$count"}; + $wiosettings{'DYNDNS'} = $wiosettings{"DYNDNS$count"}; + $wiosettings{'SENDEMAILON'} = $wiosettings{"SENDEMAILON$count"}; + $wiosettings{'SENDEMAILOFF'} = $wiosettings{"SENDEMAILOFF$count"}; + $wiosettings{'PINGMETHODE'} = $wiosettings{"PINGMETHODE$count"}; + $wiosettings{'ONLINE'} = $wiosettings{"ONLINE$count"}; + $wiosettings{'WEBINTERFACE'} = $wiosettings{"WEBINTERFACE$count"}; + + &validSave(); + + if ($errormessage) { + open(FILE, ">> $editfile"); + print FILE "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n"; + close(FILE); + $importmessage = $errormessage; + } + else { + $wiosettings{'CLIENTID'} = &General::findhasharraykey (%ipshash); + unshift (@current, "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n"); + &SortDataFile('',@current); + } + } + $count++; + } + + map ($wiosettings{$_} = '' ,@nosaved); + unlink ($importfile); + if ( -e "$editfile" ) { goto EDIT; } + } + else { + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## add or update client + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_client_add'} ) { + unless ( `ps -A | grep wio.pl` ) { + &validSave(); + + unless ($errormessage) { + if ( $wiosettings{'ID'} eq '' && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} ) { + $wiosettings{'CLIENTID'} = &General::findhasharraykey (%ipshash); + unshift (@current, "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n"); + } + else { + @current[$wiosettings{'ID'}] = "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n"; + } + } + else { goto ERROR; } + + map ($wiosettings{$_} = '' ,@nosaved); + &SortDataFile('',@current); + } + else { + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## add arp client + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_add'} ) { + unless ( `ps -A | grep wio.pl` ) { + open(FILE, "$logdir/.arpcache"); + @arpadd = <FILE>; + close (FILE); + + chomp(@arpadd[$wiosettings{'ID'}]); + @temp = split (/,/, @arpadd[$wiosettings{'ID'}]); + + $wiosettings{'CLIENTID'} = &General::findhasharraykey (%ipshash); + $wiosettings{'IPADR'} = $temp[1]; + $wiosettings{'HOST'} = $temp[2]; + $wiosettings{'EN'} = 'on'; + + $wiosettings{'PINGMETHODE'} = 'ip'; + $wiosettings{'ONLINE'} = 'off'; + + open(FILE, ">> $editfile"); + print FILE "$wiosettings{'CLIENTID'},$wiosettings{'TIMESTAMP'},$wiosettings{'IPADR'},$wiosettings{'HOST'},$wiosettings{'EN'},$wiosettings{'REMARK'},$wiosettings{'DYNDNS'},$wiosettings{'SENDEMAILON'},$wiosettings{'SENDEMAILOFF'},$wiosettings{'PINGMETHODE'},$wiosettings{'ONLINE'},$wiosettings{'WEBINTERFACE'}\n"; + close(FILE); + + goto EDIT; + } + else { + undef($wiosettings{'ID'}); + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## enable / disabel client || enable / disable dyndns || enable / disable sendemailon || enable / disable sendemailoff || change ip / fqdn + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'enable disable client'} ) { $edc = 'on'; } +if ( $wiosettings{'ACTION'} eq $Lang::tr{'enable disable dyndns'} ) { $edd = 'on'; } +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_mail_online'} ) { $wmon = 'on'; } +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_mail_offline'} ) { $wmoff = 'on'; } +if (( $wiosettings{'ACTION'} eq $Lang::tr{'wio_ip_on'} ) || ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_fqdn_on'} )) { $ipfqdn = 'on'; } + +if ( defined($edc) || defined($edd) || defined($wmon) || defined($wmoff) || defined($ipfqdn) ) { + unless ( `ps -A | grep wio.pl` ) { + chomp(@current[$wiosettings{'ID'}]); + @temp = split (/,/, @current[$wiosettings{'ID'}]); + + if ( $edc eq 'on' ) { + $temp[4] = $temp[4] ne '' ? '' : 'on'; + $temp[10] = ''; + $temp[11] = ''; + $temp[1] = ''; + unlink "$rrddir/$temp[0].rrd"; + } + elsif ( $edd eq 'on' ) { $temp[6] = $temp[6] ne '' ? '' : 'on'; } + elsif ( $wmon eq 'on' ) { $temp[7] = $temp[7] ne '' ? '' : 'on'; } + elsif ( $wmoff eq 'on' ) { $temp[8] = $temp[8] ne '' ? '' : 'on'; } + elsif ( $ipfqdn eq 'on' ) { $temp[9] = $temp[9] eq 'fqdn' ? 'ip' : 'fqdn'; } + + @current[$wiosettings{'ID'}] = join (',', @temp)."\n"; + undef($wiosettings{'ID'}); + + &writeips(); + } + else { + undef($wiosettings{'ID'}); + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## refresh wio status || refresh single client status + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_refresh'} || $wiosettings{'ACTION'} eq $Lang::tr{'wio_sc_refresh'} ) { + + if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_sc_refresh'} ) { + open(FILE, "> $onoffip"); + print FILE @current[$wiosettings{'ID'}]; + close(FILE); + + undef($wiosettings{'ID'}); + } + +unless ( `ps -A | grep wio.pl` ) { + +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'wio'}, 1, $refreshbox); +&Header::openbigbox('100%', 'left', ''); +&Header::openbox('100%', 'left', $Lang::tr{'wio_info'}); + +print" +<table align='center' width='100%'> + <tr><td align='center'>$Lang::tr{'wio_msg'}</td></tr> + <tr><td> </td></tr> + <tr><td align='center'><img align='middle' src='/images/indicator.gif' /></td></tr> +</table> +"; + +&Header::closebox(); +&Header::closebigbox(); +&Header::closepage(); + +while ( system("/usr/local/bin/wiohelper", "&") ) {} + +exit 0; +} +else { + $infomessage = "$Lang::tr{'wio_already_running'}"; +} + +} + +## refresh dyndns ip + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_dyndns_refresh'} ) { + unless ( `ps -A | grep wio.pl` ) { + chomp(@current[$wiosettings{'ID'}]); + @temp = split (/,/, @current[$wiosettings{'ID'}]); + + ($temp[2], $infomessage) = &WIO::getdyndnsip($temp[2], $temp[3]); + + @current[$wiosettings{'ID'}] = join (',', @temp)."\n"; + + &writeips(); + + undef($wiosettings{'ID'}); + } + else { + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## edit client + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'edit'} ) { + unless ( `ps -A | grep wio.pl` ) { + chomp(@current[$wiosettings{'ID'}]); + @temp = split (/,/, @current[$wiosettings{'ID'}]); + + $wiosettings{'CLIENTID'} = $temp[0]; + $wiosettings{'TIMESTAMP'} = $temp[1]; + $wiosettings{'IPADR'} = $temp[2]; + $wiosettings{'HOST'} = $temp[3]; + $wiosettings{'EN'} = $temp[4]; + $wiosettings{'REMARK'} = $temp[5]; + $wiosettings{'DYNDNS'} = $temp[6]; + $wiosettings{'SENDEMAILON'} = $temp[7]; + $wiosettings{'SENDEMAILOFF'} = $temp[8]; + $wiosettings{'PINGMETHODE'} = $temp[9]; + $wiosettings{'ONLINE'} = $temp[10]; + $wiosettings{'WEBINTERFACE'} = $temp[11]; + } + else { + undef($wiosettings{'ACTION'}); + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## remove client + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_remove_client'} ) { + unless ( `ps -A | grep wio.pl` ) { + chomp(@current[$wiosettings{'ID'}]); + + @temp = split (/,/, @current[$wiosettings{'ID'}]); + + unlink "$rrddir/$temp[0].rrd"; + + splice (@current,$wiosettings{'ID'},1); + + &writeips(); + + undef($wiosettings{'ID'}); + } + else { + undef($wiosettings{'ID'}); + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## remove all clients + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_remove_all'} ) { + unless ( `ps -A | grep wio.pl` ) { + &WIO::clearfile($ipadrfile); + unlink glob "$rrddir/*"; + undef(@current); + } + else { + $infomessage = "$Lang::tr{'wio_error_function'}"; + } +} + +## back function + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_back'} ) { + if ( -e "$importfile" ) { unlink ($importfile); } + map ($wiosettings{$_} = '' ,@nosaved); + undef($errormessage); +} + +## import hosts, fixleases or csv file || scan networks (green/blue/orange) + +if ( $wiosettings{'ACTION'} eq 'wio_run_green' || + $wiosettings{'ACTION'} eq 'wio_run_blue' || + $wiosettings{'ACTION'} eq 'wio_run_orange') { $wioscan = 'on'; } + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' || + $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' || + $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'3' || + defined($wioscan) || defined($importmessage) ) { + +unless ( `ps -A | grep wio.pl` ) { + if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' && $importmessage eq '' ) { + + &Header::getcgihash(%wiosettings, {'wantfile' => 1, 'filevar' => 'CSVFILE'}); + + if ( $wiosettings{'CSVFILE'} eq '' ) { + $errormessage = $Lang::tr{'wio_no_file_selected'}; + $message = 2; goto ERROR; + } + + if ( $wiosettings{'CSVFILE'} =~ /[^a-z0-9A-Z\ .-_:\]+/ ) { + $errormessage = $Lang::tr{'wio_no_csv_error'}; + $message = 2; goto ERROR; + } + + if ( !($wiosettings{'CSVFILE'} =~ /.csv$/) ) { + $errormessage = $Lang::tr{'wio_no_csv'}; + $message = 2; goto ERROR; + } + + if (copy($wiosettings{'CSVFILE'}, "$logdir/importfile") != 1) { + $errormessage = $!; + $message = 2; goto ERROR; + } + } + +EDIT: + +&General::readhash($wiosettings, %wiosettings); + +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'wio'}, 1, ''); +&Header::openbigbox('100%', 'left'); + +if ($importmessage) { + &Header::openbox('100%', 'left', $Lang::tr{'wio_error'}, 'error'); + print" <table width='100%'><tr><td><font class='base'>$importmessage</font></td></tr></table>"; + &Header::closebox(); +} + +if ( -e "$editfile" ) { + open(FILE, "< $editfile" ); } +elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' ) { + open(FILE, "< $importfile" ); } +elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) { + open(FILE, "< $hostfile" ); } +elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'3' ) { + open(FILE, "< $dhcpfile" ); } +elsif ( $wioscan eq 'on' ) { + + foreach (keys(%ifacecolor)) { + if ( $netsettings{"${_}_DEV"} eq $wiosettings{'ID'} ) { + $dev = $netsettings{"${_}_DEV"}; + $iprange = $wiosettings{"${_}_IPLOW"} . "-" . $wiosettings{"${_}_IPHIGH"}; + + if ( $_ eq 'GREEN' ) { $color = "$Header::colourgreen"; $net = $Lang::tr{'wio_msg_green'}; } + elsif ( $_ eq 'BLUE' ) { $color = "$Header::colourblue"; $net = $Lang::tr{'wio_msg_blue'}; } + else { $color = "$Header::colourorange"; $net = $Lang::tr{'wio_msg_orange'}; } + } + } + +&Header::openbox('100%', 'left', $Lang::tr{'wio_info'}); + print"<table width='100%'> + <tr><td align='center'><font class='base'>$Lang::tr{'wio_msg_left'} </font><font class='base' color='$color'><b>$net</b></font> $Lang::tr{'wio_msg_center'} <font class='base' color='$color'><b>$dev</b></font><font class='base'> $Lang::tr{'wio_msg_right'} $Lang::tr{'wio_msg_hint'}</font></td></tr> + <tr><td> </td></tr> + <tr><td align='center'><img align='middle' src='/images/indicator.gif' /></td></tr> + </table>"; +&Header::closebox(); +&Header::closebigbox(); + + open(FILE, "/usr/local/bin/wioscan -wsa $dev $iprange |" ); + +} + +@hosts = <FILE>; +close(FILE); + +if ( $wioscan ne 'on' && ! -e $wiofile ) { @hosts = sort @hosts; } +else { + open(FILE, "> $wiofile"); + print FILE @hosts; + close(FILE); + + print"<meta http-equiv="refresh" content="0; URL=$ENV{'SCRIPT_NAME'}">"; + exit 0; +} + +WIOSCAN: + +if ( -e $wiofile ) { + open(FILE, "< $wiofile"); + @hosts = <FILE>; + close (FILE); + + &General::readhash($wiosettings, %wiosettings); + + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'wio'}, 1, ''); + &Header::openbigbox('100%', 'left'); +} + +foreach (@hosts) { + chomp; + + @line = split (/,/, $_); + + if ( -e $editfile || -e $importfile ) { + $wiosettings{'CLIENTID$count'} = $line[0]; + $wiosettings{'TIMESTAMP$count'} = $line[1]; + $wiosettings{'IPADR$count'} = $line[2]; + $wiosettings{'HOST$count'} = $line[3]; + $wiosettings{'EN$count'} = $line[4]; + $wiosettings{'REMARK$count'} = $line[5]; + $wiosettings{'DYNDNS$count'} = $line[6]; + $wiosettings{'SENDEMAILON$count'} = $line[7]; + $wiosettings{'SENDEMAILOFF$count'} = $line[8]; + $wiosettings{'PINGMETHODE$count'} = $line[9]; + $wiosettings{'ONLINE$count'} = $line[10]; + $wiosettings{'WEBINTERFACE$count'} = $line[11]; + $wiosettings{'USE$count'} = 'on'; + } + else { + $wiosettings{'IPADR$count'} = $line[1]; + $wiosettings{'EN$count'} = 'on'; + $wiosettings{'PINGMETHODE$count'} = 'ip'; + $wiosettings{'USE$count'} = 'on'; + + if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) { + $wiosettings{'HOST$count'} = $line[2]; + $wiosettings{'DOM$count'} = $line[3]; + $wiosettings{'REMARK$count'} = ''; + } + elsif ( $wioscan eq 'on' || -e $wiofile ) { + $wiosettings{'HOST$count'} = gethostbyaddr(inet_aton($line[1]), AF_INET); + if ($wiosettings{'HOST$count'} eq '') { $wiosettings{'HOST$count'} = $line[1]; } + $wiosettings{'REMARK$count'} = ''; + $wiosettings{'WEBINTERFACE$count'} = ''; + } + else { + $wiosettings{'HOST$count'} = $line[7]; + $wiosettings{'REMARK$count'} = $line[6]; + } + } + + $checked{'EN$count'}{'on'} = ($wiosettings{'EN$count'} eq '' ) ? '' : "checked='checked'"; + + $checked{'DYNDNS$count'}{'on'} = ($wiosettings{'DYNDNS$count'} eq '' ) ? '' : "checked='checked'"; + $checked{'SENDEMAILON$count'}{'on'} = ($wiosettings{'SENDEMAILON$count'} eq '' ) ? '' : "checked='checked'"; + $checked{'SENDEMAILOFF$count'}{'on'} = ($wiosettings{'SENDEMAILOFF$count'} eq '' ) ? '' : "checked='checked'"; + + $checked{'PINGMETHODE$count'}{'ip'} = $checked{'PINGMETHODE$count'}{'fqdn'} = ''; + $checked{'PINGMETHODE$count'}{$wiosettings{'PINGMETHODE$count'}} = "checked='checked'"; + + $checked{'USE$count'}{'on'} = ($wiosettings{'USE$count'} eq '' ) ? '' : "checked='checked'"; + + $selected{'WEBINTERFACE$count'}{'----'} = ''; + $selected{'WEBINTERFACE$count'}{'HTTP'} = ''; + $selected{'WEBINTERFACE$count'}{'HTTPS'} = ''; + $selected{'WEBINTERFACE$count'}{$wiosettings{'WEBINTERFACE$count'}} = "selected='selected'"; + +if (! &WIO::checkinto($wiosettings{'IPADR$count'}, $wiosettings{'HOST$count'}, @current) ) { + +if ( $importmessage ) { + &Header::openbox('100%', 'left', "$Lang::tr{'wio_import_data'}'$wiosettings{'HOST$count'}'$Lang::tr{'wio_import_data1'}"); +} +elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'1' || $wioscan eq 'on' || -e $wiofile || -e $editfile ) { + &Header::openbox('100%', 'left', "$Lang::tr{'wio_import_data'}'$wiosettings{'HOST$count'}'$Lang::tr{'wio_import_data2'}"); +} +elsif ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) { + &Header::openbox('100%', 'left', "$Lang::tr{'wio_import_data'}'$wiosettings{'HOST$count'}.$wiosettings{'DOM$count'}'$Lang::tr{'wio_import_data2'}"); +} +else { + &Header::openbox('100%', 'left', $Lang::tr{'wio_import_leases'}); +} + +print" +<form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> +<input type='hidden' name='ONLINE$count' value='$wiosettings{'ONLINE$count'}' /> + +<table width='100%'> +<tr> + <td>$Lang::tr{'wio_use'}</td> + <td><input type='checkbox' name='USE$count' $checked{'USE$count'}{'on'} /></td> +</tr> +<tr> + <td>$Lang::tr{'wio_client_enable'}</td> + <td><input type='checkbox' name='EN$count' $checked{'EN$count'}{'on'} /></td> +</tr> +<tr> + <td>$Lang::tr{'host ip'}:</td> + <td><input type='text' name='IPADR$count' value='$wiosettings{'IPADR$count'}' size='18' /></td> + <td>$Lang::tr{'hostname'}:</td> +"; + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'wio_import'}.'2' ) { + print"<td><input type='text' name='HOST$count' size='18' value='$wiosettings{'HOST$count'}.$wiosettings{'DOM$count'}' /></td>"; +} +else { + print"<td><input type='text' name='HOST$count' size='18' value='$wiosettings{'HOST$count'}' /></td>"; +} + +print" + <td>$Lang::tr{'remark'}:</td> + <td><input type='text' name='REMARK$count' value='$wiosettings{'REMARK$count'}' size='18' /></td> +</tr> +<tr> + <td class='base'>$Lang::tr{'wio_ping_send'}:</td> + <td align='left'><input type='radio' name='PINGMETHODE$count' value='ip' $checked{'PINGMETHODE$count'}{'ip'} /> IP <input type='radio' name='PINGMETHODE$count' value='fqdn' $checked{'PINGMETHODE$count'}{'fqdn'} /> FQDN</td> + <td>$Lang::tr{'wio_dyndns'}:</td> + <td><input type='checkbox' name='DYNDNS$count' $checked{'DYNDNS$count'}{'on'} /></td> +"; + +if ( $wiosettings{'SENDEMAIL'} eq 'on' ) { + print"<td>$Lang::tr{'wio_sendemail'}:</td> + <td><input type='checkbox' name='SENDEMAILON$count' $checked{'SENDEMAILON$count'}{'on'} /> $Lang::tr{'wio_online'} <input type='checkbox' name='SENDEMAILOFF$count' $checked{'SENDEMAILOFF$count'}{'on'} /> $Lang::tr{'wio_offline'}</td>"; +} +else { + print"<td colspan='2'> </td>"; +} + +print" +</tr> +<tr> + <td height='30'>$Lang::tr{'wio_ping_send'}:</td> + <td align='left' colspan='5'> + <select size='1' name='WEBINTERFACE$count' width='80' style='width: 80px'> + <option value='----' $selected{'WEBINTERFACE$count'}{'----'}>----</option> + <option value='HTTP' $selected{'WEBINTERFACE$count'}{'HTTP'}>HTTP</option> + <option value='HTTPS' $selected{'WEBINTERFACE$count'}{'HTTPS'}>HTTPS</option> + </select> + </td> +</tr> +</table> +"; + +&Header::closebox(); +$showcount++; +} +$count++; +} + +if ( $showcount gt 0 ) { +&Header::openbox('100%', 'left', $Lang::tr{'wio_import_infos'}); + +print" +<table width='100%'> +<tr> +"; + +if ($importmessage) { print"<td> </td>"; } +else { print"<td><font color='$color{'color11'}'>$Lang::tr{'wio_import_infos_csv'}</font></td>"; } + +print" +</tr> +<tr><td colspan='4'> </td></tr> +</table> +<table width='100%'> +<tr> + <td width='25%'> </td> + <td width='25%'><input type='hidden' name='COUNT' value='$count' /><input type='hidden' name='ACTION' value='$Lang::tr{'wio_save'}2' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_save'}' /></form></td> + <td width='25%'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='submit' name='ACTION' value='$Lang::tr{'wio_back'}' /></form></td> + <td width='25%'> </td> +</tr> +</table> +"; + +&Header::closebox(); +&Header::closebigbox(); +&Header::closepage(); +} +else { + print"<meta http-equiv="refresh" content="0; URL=$ENV{'SCRIPT_NAME'}?INFO">"; +} + +if ( -e "$editfile" ) { unlink ($editfile); } +if ( -e "$wiofile" ) { unlink($wiofile); } +exit 0; +} +else { + $infomessage = "$Lang::tr{'wio_error_function'}"; +} +} + +## skript function + +if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) { + my $string = $ENV{'QUERY_STRING'}; + + if ( $string eq 'INFO' ) { + $infomessage = $Lang::tr{'wio_import_info_csv'}; + } + else { + &General::readhash($wiosettings, %wiosettings); + + my $actual = $wiosettings{'SORT'}; + + if ($actual =~ $string) { + my $Rev = ''; + if ($actual !~ 'Rev') { $Rev = 'Rev'; } + $string.=$Rev; + } + + system("/bin/sed -i 's#$wiosettings{'SORT'}#$string#g' $wiosettings"); + + $wiosettings{'SORT'} = $string; + map ($wiosettings{$_} = '' ,@nosaved); + &SortDataFile('',@current); + } +} + +## main part + +ERROR: + +unless($message == 1) { &General::readhash($wiosettings, %wiosettings); } + +for ($i=5; $i<=60; $i+=5) { $selected{'CRON'}{$i} = ''; } + +$selected{'CRON'}{$wiosettings{'CRON'}} = "selected='selected'"; + +for ($i=1; $i<=15; $i++) { + $selected{'TIMEOUT'}{$i} = ''; + $selected{'OVPNCRON'}{$i} = ''; +} + +$selected{'TIMEOUT'}{$wiosettings{'TIMEOUT'}} = "selected='selected'"; +$selected{'OVPNCRON'}{$wiosettings{'OVPNCRON'}} = "selected='selected'"; + +$checked{'ENABLE'}{'off'} = $checked{'ENABLE'}{'on'} = ''; +$checked{'ENABLE'}{$wiosettings{'ENABLE'}} = "checked='checked'"; + +$checked{'LOGGING'}{'off'} = $checked{'LOGGING'}{'on'} = ''; +$checked{'LOGGING'}{$wiosettings{'LOGGING'}} = "checked='checked'"; + +$checked{'CLIENTREMARK'}{'off'} = $checked{'CLIENTREMARK'}{'on'} = ''; +$checked{'CLIENTREMARK'}{$wiosettings{'CLIENTREMARK'}} = "checked='checked'"; + +$checked{'MAILREMARK'}{'off'} = $checked{'MAILREMARK'}{'on'} = ''; +$checked{'MAILREMARK'}{$wiosettings{'MAILREMARK'}} = "checked='checked'"; + +$checked{'OVPNRWMAIL'}{'off'} = $checked{'OVPNRWMAIL'}{'on'} = ''; +$checked{'OVPNRWMAIL'}{$wiosettings{'OVPNRWMAIL'}} = "checked='checked'"; + +$checked{'SHUTDOWN'}{'off'} = $checked{'SHUTDOWN'}{'on'} = ''; +$checked{'SHUTDOWN'}{$wiosettings{'SHUTDOWN'}} = "checked='checked'"; + +$checked{'MAILSTYLE'}{'smail'} = $checked{'MAILSTYLE'}{'email'} = ''; +$checked{'MAILSTYLE'}{$wiosettings{'MAILSTYLE'}} = "checked='checked'"; + +&Header::showhttpheaders(); +&Header::openpage($Lang::tr{'wio'}, 1, "<meta http-equiv='expires' content='-1'><meta http-equiv='cache-control' content='no-store, no-cache, must-revalidate'><meta http-equiv='pragma' content='no-cache'>"); +&Header::openbigbox('100%', 'left', ''); + +## DEBUG / ERROR / INFO / UPDATE + +if ( $debug ) { + &Header::openbox('100%', 'left', 'DEBUG', 'warning'); + + print"errormessage: $errormessage<br />\n"; + print"infomessage: $infomessage<br />\n"; + + &hrline(); + + my $wiodebug = 0; + foreach (sort keys %wiosettings) { + print"$_ = $wiosettings{$_}<br />\n"; + $wiodebug++; + } + + &hrline(); + + my $netdebug = 0; + foreach (sort keys %netsettings) { + print"$_ = $netsettings{$_}<br />\n"; + $netdebug++; + } + &Header::closebox(); +} + +if ( $errormessage ) { + &Header::openbox('100%', 'left', $Lang::tr{'wio_error'}, 'error'); + print"<table width='100%'><tr><td><font class='base'><b>$errormessage</b></font></td></tr></table>"; + &Header::closebox(); +} + +if ( $infomessage ) { + &Header::openbox('100%', 'left', $Lang::tr{'wio_info'}, 'warning'); + print"<table width='100%'><tr><td><font class='base'><b>$infomessage</b></font></td></tr></table>"; + &Header::closebox(); +} + +## wio configuration + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'edit'}.'1' || $message == 1 || $wiosettings{'ENABLE'} eq 'off' ) { + +&Header::openbox('100%', 'left', $Lang::tr{'wio settings'}); + +print" +<form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> +<table width='100%'> +<tr> + <td width='45%' bgcolor='$color{'color20'}' align='left' height='20'><b> $Lang::tr{'wio_settings_msg'}</b></td> + <td width='2%'> </td> + <td width='53%'> </td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td colspan='3'>$Lang::tr{'wio_settings_msg_hint'}</td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio enabled'}</td> +"; + +print"<td> </td>"; + +if ( $wiosettings{'ENABLE'} eq 'on' ) { + print"<td align='left'><input type='checkbox' onClick="return confirm('$Lang::tr{'wio_disable_hint'}')" name='ENABLE' $checked{'ENABLE'}{'on'} /></td>"; +} +else { + print"<td align='left'><input type='checkbox' name='ENABLE' $checked{'ENABLE'}{'on'} /></td>"; +} +print" +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio_shutdown'}</td> + <td> </td> + <td align='left'><input type='checkbox' name='SHUTDOWN' $checked{'SHUTDOWN'}{'on'} /></td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio cron'}</td> + <td> </td> + <td align='left'><select size='1' name='CRON' size='5'> +"; + +for ($i=5; $i<=60; $i+=5) { printf("<option %s>%02s</option>\n",$selected{'CRON'}{$i},$i); } + +print" + </select> $Lang::tr{'wio min'}</td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio timeout'}</td> + <td> </td> + <td align='left'><select size='1' name='TIMEOUT' size='5'> +"; + +for ($i=1; $i<=15; $i++) { printf("<option %s>%02s</option>\n",$selected{'TIMEOUT'}{$i},$i); } + +print" + </select> $Lang::tr{'wio sec'}</td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio_logging'}</td> + <td> </td> + <td align='left'><input type='checkbox' name='LOGGING' $checked{'LOGGING'}{'on'} /></td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio_clientremark'}</td> + <td> </td> + <td align='left'><input type='checkbox' name='CLIENTREMARK' $checked{'CLIENTREMARK'}{'on'} /></td> +</tr> +<tr><td colspan='3'> </td></tr> + +"; + +if ( $wiosettings{'SENDEMAIL'} eq 'on' ) { +print" +<tr> + <td align='right'>$Lang::tr{'wio_mail_style'}:</td> + <td> </td> + <td align='left'><input type='radio' name='MAILSTYLE' value='smail' $checked{'MAILSTYLE'}{'smail'} /> $Lang::tr{'wio_mail_smail'} <input type='radio' name='MAILSTYLE' value='email' $checked{'MAILSTYLE'}{'email'} /> $Lang::tr{'wio_mail_email'}</td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio_mailremark_enabled'}</td> + <td> </td> + <td align='left'><input type='checkbox' name='MAILREMARK' $checked{'MAILREMARK'}{'on'}></td> +</tr> +<tr><td colspan='3'> </td></tr> +"; +} +if ( -e "$ovpnaddon" || ! -z "/var/ipfire/vpn/config" ) { +print" +<tr> + <td align='right'>$Lang::tr{'wio_mail_ovpnrw'}</td> + <td> </td> + <td align='left'><input type='checkbox' name='OVPNRWMAIL' $checked{'OVPNRWMAIL'}{'on'}></td> +</tr> +<tr><td colspan='3'> </td></tr> +<tr> + <td align='right'>$Lang::tr{'wio_ovpn_cron'}</td> + <td> </td> + <td align='left'><select size='1' name='OVPNCRON' size='5'> +"; + +for ($i=1; $i<=15; $i++) { printf("<option %s>%02s</option>\n",$selected{'OVPNCRON'}{$i},$i); } + +print" + </select> $Lang::tr{'wio min'}</td> +</tr> +<tr><td colspan='3'> </td></tr> +"; +} +print" +<tr><td colspan='3'> </td></tr> +<tr> + <td colspan='2'> </td> + <td align='left'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_save'}1' /><input type='submit' name='submit' value='$Lang::tr{'wio_save'}' />" + .($wiosettings{'ENABLE'} ne 'off' ? " <input type='button' onClick='location.href="/cgi-bin/wio.cgi"' value='$Lang::tr{'wio_back'}'>" : "") + ."</td> +</tr> +</table> +</form> +"; + +&Header::closebox(); +&Header::closebigbox(); +&Header::closepage(); +exit 0; +} + +## wio client status + +if ( $wiosettings{'ENABLE'} eq 'on') { + if ( !$errormessage && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} || $message == 2 ) { + &Header::openbox('100%', 'left', $Lang::tr{'wio stat'}); + + foreach (@current) { + chomp; + + ($id,$timestamp,$ipadr,$host,$on,$remark,$dyndns,$sendemailon,$sendemailoff,$pingmethode,$online,$webinterface) = split (/,/, $_); + + if ( defined($dyndns) && ( $dyndns =~ 'on' ) ) { + ($dyndnsip, $infomessage) = &WIO::getdyndnsip($ipadr, $host); + + if ( $dyndnsip ne $ipadr ) { + $ipadr = $dyndnsip; + $write = 'on'; + } + } + + push (@id,($id)); + + if ( $on eq 'on' ) { push (@dates,($timestamp)); } + else { push (@dates,('-')); } + + push (@ipaddresses,($ipadr)); + push (@names,($host)); + push (@activ,($on)); + push (@remark,($remark)); + push (@dyndns,($dyndns)); + push (@sendemailon,($sendemailon)); + push (@sendemailoff,($sendemailoff)); + push (@pingmethode,($pingmethode)); + push (@status,($online)); + push (@webinterface,($webinterface)); + + push (@write, "$id,$timestamp,$ipadr,$host,$on,$remark,$dyndns,$sendemailon,$sendemailoff,$pingmethode,$online,$webinterface\n"); + + $nr++; + } + + if ( defined($write) ) { &writeips(); } + +## wan connection + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr height='20'> + <td width='28%' bgcolor='$color{'color20'}' align='left'><b> $Lang::tr{'wio_wan_con'}</b></td> + <td width='72%' align='right'> </td> +</tr> +<tr><td colspan='2'> </td></tr> +</table> + +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color20'}' height='20'> + <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td> + <td width='15%' align='center'><b>$Lang::tr{'wio ipadress'}</b></td> + <td width='3%' align='center'><b>$Lang::tr{'wio network'}</b></td> + <td width='15%' align='center'><b>$Lang::tr{'wio_lanname'}</b></td> + <td width='15%' align='center'><b>$Lang::tr{'wio_wanname'}</b></td> + <td width='24%' align='center'><b>$Lang::tr{'wio_dyndns_hosts'}</b></td> + <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td> + <td width='14%' align='center'><b>$Lang::tr{'wio_wancheck'}</b></td> +</tr> +<tr bgcolor='$color{'color22'}' height='20'> + <td align='center'>01</td> + <td align='center'><font color='$Header::colourred'>$redip</b></font></td> + <td align='center'><img align='middle' src='$imgstatic/red.png' alt='$Lang::tr{'internet'}' title='$Lang::tr{'internet'}' /></td> + <td align='center'><font color='$Header::colourgreen'>".$mainsettings{'HOSTNAME'}.".".$mainsettings{'DOMAINNAME'}."</font></td> + <td align='center'><font color='$Header::colourred'>".( $redip ne '-' ? (gethostbyaddr(pack("C4", split (/./, $redip)), 2))[0] : '-' )."</font></td> + <td align='center'> +"; + +if ( -s "$dyndnsconfig" ) { + +open(FILE, "< $dyndnsconfig"); +@ddns = <FILE>; +close (FILE); + +$ddns = @ddns; +$bgcolor = "blue"; + + foreach (@ddns) { + chomp; + + @temp = split (/,/, $_); + + if ( $temp[7] eq "on" ) { $bgcolor = ( &General::DyndnsServiceSync (&General::GetDyndnsRedIP,$temp[1],$temp[2]) ? "$Header::colourgreen" : "$Header::colourred" ); } + + print"<font color='$bgcolor'>$temp[1].$temp[2]</font>"; + + if ( $iddyndns++ ne ($ddns-1) ) { print"<b>, </b>"; } + } +} +else { print"<b> - </b>"; } + +print" + </td> + <td align='center'> + <table bgcolor='".( -e $redactive ? "${Header::colourgreen}" : "${Header::colourred}" )."' cellpadding='2' cellspacing='0' width='100%'> + <tr height='20'> + <td align='center'><font color='white'><b>".( -e $redactive ? $Lang::tr{'wio_wan_up'} : $Lang::tr{'wio_wan_down'} )."</b></font></td> + </tr> + </table> + </td> + <td align='center'><font color='$Header::colourred'>".( -e "$redactive" ? &General::age("$redactive") : '-' )."</font></td> +</tr> +<tr height='1'><td colspan='9' bgcolor='#696565'></td></tr> +</table> +"; + +&hrline(); + +## vpn connection(s) + +if ( -e "$vpnpid" ) { + +@vpnstatus = `/usr/local/bin/ipsecctrl I`; + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr height='20'> + <td width='28%' bgcolor='$color{'color20'}' align='left'><b> $Lang::tr{'wio_vpn_con'}</b></td> + <td width='72%'> </td> +</tr> +<tr><td colspan='2'> </td></tr> +</table> +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color20'}' height='20'> + <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td> + <td width='19%' align='center'><b>$Lang::tr{'wio checked'}</b></td> + <td width='20%' align='center'><b>$Lang::tr{'name'}</b></td> + <td width='8%' align='center'><b>$Lang::tr{'type'}</b></td> + <td width='25%' align='center'><b>$Lang::tr{'wio_common_name'}</b></td> + <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td> + <td width='14%' align='center'><b>$Lang::tr{'wio_ovpn_connected'}</b></td> +</tr> +"; + +foreach $key (sort SortByTunnelName (keys(%vpnconfighash))) { + +my $vpncheck = ''; + +if ( -e '/var/log/wio/.vpncache' ) { + $vpncheck = strftime("%d.%m.%Y - %H:%M:%S",localtime(((stat('/var/log/wio/.vpncache'))[9]))); +} + +$status = "bgcolor='${Header::colourred}'"; +$statustxt = "$Lang::tr{'capsclosed'}"; + + if ($vpnconfighash{$key}[0] eq 'off') { + $status = "bgcolor='${Header::colourblue}'"; + $statustxt = "$Lang::tr{'capsclosed'}"; + } + + foreach (@vpnstatus) { + if ($_ =~ /$vpnconfighash{$key}[1]{.*INSTALLED/) { + $status = "bgcolor='${Header::colourgreen}'"; + $statustxt = "$Lang::tr{'capsopen'}"; + last; + } + } + + print"<tr".($idvpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>"; + + my $vpnnr = $idvpn+1; + + printf ("<td align='center'> %02d</td>", $vpnnr); + + print"<td align='center'>$vpncheck</td> + <td align='center'>$vpnconfighash{$key}[1]</td> + <td align='center'><img align='middle' src='$imgstatic/".( $vpnconfighash{$key}[3] eq 'host' ? "vpnrw.png' alt='$Lang::tr{'wio_rw'}' title='$Lang::tr{'wio_rw'}'" : "vpnn2n.png' alt='$Lang::tr{'wio_n2n'}' title='$Lang::tr{'wio_n2n'}'")." /></td> + <td align='center'>".($vpnconfighash{$key}[2] eq '%auth-dn' ? "$vpnconfighash{$key}[9]" : ($vpnconfighash{$key}[4] eq 'cert' ? "$vpnconfighash{$key}[2]" : ($vpnconfighash{$key}[8] ne '' ? "$vpnconfighash{$key}[10]" : " ")))."</td> + <td align='center'> + <table $status cellpadding='2' cellspacing='0' width='100%'> + <tr height='20'> + <td align='center'><font color='white'><b>$statustxt</b></font></td> + </tr> + </table> + </td> + <td align='center' height='20'> </td> + </tr> +"; + +if ($vpnconfighash{$key}[25] && $wiosettings{'CLIENTREMARK'} eq 'on') { + print"<tr".($idvpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'><td> </td><td colspan='16' align='left'>$vpnconfighash{$key}[25]</td></tr>"; +} + print"<tr height='1'><td colspan='7' bgcolor='#696565'></td></tr>"; + $idvpn++ +} + +print"</table>"; +&hrline(); +} + +## openvpn connection(s) + +if ( -e "$ovpnpid" ) { + +@ovpnstatus = `cat /var/run/ovpnserver.log`; + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr height='20'> + <td width='28%' bgcolor='$color{'color20'}' align='left'><b> $Lang::tr{'wio_ovpn_con'}</b></td> + <td width='72%'> </td> +</tr> +<tr><td colspan='2'> </td></tr> +</table> +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color20'}' height='20'> + <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td> + <td width='19%' align='center'><b>$Lang::tr{'wio checked'}</b></td> + <td width='20%' align='center'><b>$Lang::tr{'wio ipadress'}</b></td> + <td width='8%' align='center'><b>$Lang::tr{'type'}</b></td> + <td width='25%' align='center'><b>$Lang::tr{'common name'}</b></td> + <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td> + <td width='14%' align='center'><b>$Lang::tr{'wio_ovpn_connected'}</b></td> +</tr> +"; + + foreach $key (keys %ovpnconfighash) { + + my ( $ovpnclt, $ovpntime, $ovpnrwip, $ovpncheck ) = ''; + + if ( -e '/var/log/wio/.ovpncache' ) { + $ovpncheck = strftime("%d.%m.%Y - %H:%M:%S",localtime(((stat('/var/log/wio/.ovpncache'))[9]))); + } + + print"<tr".($idovpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>"; + + my $ovpnnr = $idovpn+1; + + printf ("<td align='center' height='20'> %02d</td>", $ovpnnr); + + if ($ovpnconfighash{$key}[3] eq 'net') { + $image = "$imgstatic/ovpnn2n.png"; + $text = "$Lang::tr{'wio_n2n'}"; + } + else { + $image = "$imgstatic/ovpnrw.png"; + $text = "$Lang::tr{'wio_rw'}"; + } + + if ( $ovpnconfighash{$key}[0] eq 'off' ) { + $status = "${Header::colourblue}"; + $statustxt = "$Lang::tr{'capsclosed'}"; + } + else { + + if ($ovpnconfighash{$key}[3] eq 'net') { + if (-e "/var/run/$ovpnconfighash{$key}[1]n2n.pid") { + my @output = ""; + my @tustate = ""; + my $tport = $ovpnconfighash{$key}[22]; + my $tnet = new Net::Telnet ( Timeout=>5, Errmode=>'return', Port=>$tport); + if ($tport ne '') { + $tnet->open('127.0.0.1'); + @output = $tnet->cmd(String => 'state', Prompt => '/(END.*\n|ERROR:.*\n)/'); + @tustate = split(/,/, $output[1]); + $ovpntime = &WIO::contime(scalar localtime($tustate[0])); + + if (($tustate[1] eq 'CONNECTED')) { + $status = "${Header::colourgreen}"; + $statustxt = "$Lang::tr{'capsopen'}"; + }else { + $status = "${Header::colourred}"; + $statustxt = "$tustate[1]"; + } + } + } + } + else { + foreach (@ovpnstatus) { + if ( $_ =~ /^(.+),(\d+.\d+.\d+.\d+:\d+),(\d+),(\d+),(.+)/ ) { + @match = split (m/^(.+),(\d+.\d+.\d+.\d+:\d+),(\d+),(\d+),(.+)/, $_); + $match[1] =~ s/[_]/ /g; + } + + if ( $match[1] ne "Common Name" && ($match[1] eq $ovpnconfighash{$key}[2]) ) { + $ovpnclt = $match[1]; + $ovpntime = &WIO::contime($match[5]); + } + + if ( $_ =~ /^(\d+.\d+.\d+.\d+),(.+),(\d+.\d+.\d+.\d+:\d+),(.+)/ ) { + @match = split(m/^(\d+.\d+.\d+.\d+),(.+),(\d+.\d+.\d+.\d+:\d+),(.+)/, $_); + } + + if ( $match[1] ne "Virtual Address" && $match[2] eq $ovpnclt ) { + $ovpnrwip = $match[1]; + $ovpncheck = &WIO::statustime($match[4]); + } + + if ( $ovpnclt eq $ovpnconfighash{$key}[2] ) { + $status = "${Header::colourgreen}"; + $statustxt = "$Lang::tr{'capsopen'}"; + } + else { + $status = "${Header::colourred}"; + $statustxt = "$Lang::tr{'capsclosed'}"; + } + } + } +} + + print" + <td align='center'>$ovpncheck</td> + <td align='center'>".( defined($ovpnrwip)? "$ovpnrwip" : " ")."</td> + <td align='center'><img align='middle' src='$image' alt='$text' title='$text' /></td> + <td align='center'>".($ovpnconfighash{$key}[2] eq '%auth-dn' ? "$ovpnconfighash{$key}[9]" : ($ovpnconfighash{$key}[4] eq 'cert' ? "$ovpnconfighash{$key}[2]": " "))."</td> + <td align='center'><table bgcolor='$status' cellpadding='2' cellspacing='0' width='100%'><tr height='20'><td align='center'><font color='white'><b>$statustxt</b></font></td></tr></table></td> + <td align='center'>".(defined($ovpntime)? "$ovpntime" : " ")."</td> +</tr> +"; + if ($ovpnconfighash{$key}[25] && $wiosettings{'CLIENTREMARK'} eq 'on') { + print"<tr".($idovpn % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'><td> </td><td colspan='16' align='left'>$ovpnconfighash{$key}[25]</td></tr>"; + } + + print"<tr height='1'><td colspan='17' bgcolor='#696565'></td></tr>"; + $idovpn++ + } + print"</table>"; + &hrline(); +} +#} + +## client status + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr height='20'> + <td width='28%' bgcolor='$color{'color20'}' align='left'><b> $Lang::tr{'wio_clients'}</b></td> + <td width='72%'> </td> +</tr> +<tr><td colspan='2'> </td></tr> +</table> + +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color20'}' height='20'> + <td width='3%' align='center'><b>$Lang::tr{'wio_id'}</b></td> + <td width='4%' align='center'><b>$Lang::tr{'wio_activ'}</b></td> + <td width='5%' align='center'><b>$Lang::tr{'wio_check'}</b></td> + <td width='15%' align='center'><b>$Lang::tr{'wio checked'}</b></td> + <td width='4%' align='center'><b>$Lang::tr{'wio_webinterface'}</b></td> + <td width='11%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IPADR'><b>$Lang::tr{'wio ipadress'}</b></a></td> + <td width='5%' align='center'><b>$Lang::tr{'wio network'}</b></td> + <td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?HOST'><b>$Lang::tr{'wio name'}</b></a></td> + <td width='11%' align='center'><b>$Lang::tr{'wio image'}</b></td> + <td width='4%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_refresh'}' /><input type='image' name='$Lang::tr{'wio_refresh'}' src='$imgstatic/refresh.png' align='middle' alt='$Lang::tr{'wio_refresh'}' title='$Lang::tr{'wio_refresh'}' /></form></td> + <td width='4%' colspan='2' align='center'><b>$Lang::tr{'wio_dyndns'}</b></td> + <td width='12%' colspan='4' align='center'><b>$Lang::tr{'action'}</b></td> + <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_remove_all'}' /><input type='image' name='$Lang::tr{'wio_remove_all'}' src='/images/delete.gif' align='middle' alt='$Lang::tr{'wio_remove_all'}' title='$Lang::tr{'wio_remove_all'}' onClick="return confirm('$Lang::tr{'wio_remove_all_hint'}')"/></form></td> +</tr> +"; + +for (my $a=0; $a<$nr; $a++) { + +my $gif = 'off.gif'; +my $gdesc = $Lang::tr{'wio_client_off'}; +my $dyndnsimg = 'on.gif'; +my $dyndnsimgtxt = $Lang::tr{'wio_dyndns_on'}; +my $mailonimg = 'wio/mailgreenon.png'; +my $mailonimgtxt = $Lang::tr{'wio_mail_online_on'}; +my $mailoffimg = 'wio/mailredon.png'; +my $mailoffimgtxt = $Lang::tr{'wio_mail_offline_on'}; +my $pingimg = ''; +my $pingtxt = ''; +my $webimg = ''; + +if ( $activ[$a] eq 'on' ) { + $gif = 'on.gif'; + $gdesc = $Lang::tr{'wio_client_on'}; +} + +if ( $dyndns[$a] ne 'on' ) { + $dyndnsimg = 'off.gif'; + $dyndnsimgtxt = $Lang::tr{'wio_dyndns_off'}; +} + +if ( $sendemailon[$a] ne 'on' ) { + $mailonimg = 'wio/mailgreenoff.png'; + $mailonimgtxt = $Lang::tr{'wio_mail_online_off'}; +} + +if ( $sendemailoff[$a] ne 'on' ) { + $mailoffimg = 'wio/mailredoff.png'; + $mailoffimgtxt = $Lang::tr{'wio_mail_offline_off'}; +} + +if ( $webinterface[$a] eq 'HTTP' ) { + $webimg = 'wio/http.png'; +} +elsif ( $webinterface[$a] eq 'HTTPS' ) { + $webimg = 'wio/https.png'; +} +else { + $webimg = 'wio/none.png'; +} + +$bgcolor = $status[$a] eq "on" ? "${Header::colourgreen}" : ($status[$a] eq "off" && $dates[$a] eq "") ? "${Header::colourblue}" : "${Header::colourred}"; +$statustxt = $status[$a] eq "on" ? "$Lang::tr{'wio up'}" : ($status[$a] eq "off" && $dates[$a] eq "") ? "$Lang::tr{'wio_no_image'}" : "$Lang::tr{'wio down'}"; + +print"<tr".($a % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>"; +printf ("<td align='center'> %02d</td>", $a+1); + +print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'enable disable client'}' /> + <input type='image' name='$Lang::tr{'enable disable client'}' src='/images/$gif' align='middle' alt='$gdesc' title='$gdesc' /> + <input type='hidden' name='ID' value='$a' /></form></td>"; + +if ( $pingmethode[$a] eq 'ip') { + print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_ip_on'}' /> + <input type='image' name='$Lang::tr{'wio_ip_on'}' src='/images/wio/ip.png' align='middle' alt='$Lang::tr{'wio_ip_on'}' title='$Lang::tr{'wio_ip_on'}' /> + <input type='hidden' name='ID' value='$a' /></form></td>"; +} +else { + print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_fqdn_on'}' /> + <input type='image' name='$Lang::tr{'wio_fqdn_on'}' src='/images/wio/fqdn.png' align='middle' alt='$Lang::tr{'wio_fqdn_on'}' title='$Lang::tr{'wio_fqdn_on'}' /> + <input type='hidden' name='ID' value='$a' /></form></td>"; +} + +print"<td align='center'>$dates[$a]</td>"; + +print"<td align='center'><img align='middle' src='/images/$webimg' /></td>"; + +if ( $webinterface[$a] eq 'HTTP' ) { + print"<td align='center'><a title="$Lang::tr{'wio_webinterface_link'}" href="http://$ipaddresses%5B$a%5D%5C" target="_blank">$ipaddresses[$a]</a></td>"; +} +elsif ( $webinterface[$a] eq 'HTTPS' ) { + print"<td align='center'><a title="$Lang::tr{'wio_webinterface_link'}" href="https://$ipaddresses%5B$a%5D%5C" target="_blank">$ipaddresses[$a]</a></td>"; +} +else { + print"<td align='center'>$ipaddresses[$a]</td>"; +} + +my $dotip = length($ipaddresses[$a]) - rindex($ipaddresses[$a],'.'); + SWITCH: { + foreach (@devs_color) { + my $in = 0; + $ic = "${_}"; + + foreach $interface (@devs_net) { + next if ( $netsettings{"$ic"."_DEV"} eq 'red0' && ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE')); + if ( $netsettings{"$ic"."_DEV"} eq $interface ) { + if ( &General::IpInSubnet($ipaddresses[$a], $netsettings{"$ic"."_NETADDRESS"}, $netsettings{"$ic"."_NETMASK"}) ) { + print"<td align='center' height='20'><img src='$imgstatic/$devs_img[$in]' alt='$Lang::tr{$devs_alt[$in]}' title='$Lang::tr{$devs_alt[$in]}' /></td>"; + last SWITCH; + } + } + $in++; + } + } + + if ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE') { + my $redipadr = qx'ip addr | grep red0 | grep inet | awk "{print $2}"'; + my @rednet = split ("/", $redipadr); + chomp ($rednet[1]); + my $red_netmask = General::iporsubtodec($rednet[1]); + my $red_netaddress = Network::get_netaddress("$rednet[0]/$red_netmask"); + + if ( &General::IpInSubnet($ipaddresses[$a], $red_netaddress, $red_netmask) ) { + print"<td align='center' height='20'><img src='$imgstatic/red.png' alt='$Lang::tr{'wio_red_lan'}' title='$Lang::tr{'wio_red_lan'}' /></td>"; + last SWITCH; + } + else { + print"<td align='center'><img align='middle' src='$imgstatic/white.png' alt='$Lang::tr{'wio_unknown_lan'}' title='$Lang::tr{'wio_unknown_lan'}' /></td>"; + last SWITCH; + } + } + + if ( -e "$vpnpid" ) { + foreach $key (keys(%vpnconfighash)) { + next unless ($vpnconfighash{$key}[3] eq 'net'); + + my $convertip = &General::ipcidr2msk($vpnconfighash{$key}[11]); + + my @net = split ("/", $convertip); + + $vpnn2nip = $net[0]; + $vpnn2nmask = length($net[1]) - rindex($net[1],'.'); + + if (substr($ipaddresses[$a],0,length($ipaddresses[$a])-$dotip) eq substr($vpnn2nip,0,length($vpnn2nip)-$vpnn2nmask)) { + print"<td align='center'><img align='middle' src='$imgstatic/vpn.png' alt='IPSec' title='IPSec' /></td>"; + last SWITCH; + } + } + } + + if ( $ovpnsettings{'DOVPN_SUBNET'} ne '' ) { + @match = split ("/", $ovpnsettings{'DOVPN_SUBNET'}); + + if ( &General::IpInSubnet($ipaddresses[$a], $match[0], $match[1]) ) { + print"<td align='center'><img src='$imgstatic/ovpn.png' alt='OpenVPN' title='OpenVPN' /></td>"; + last SWITCH; + } + } + + if ( %ovpnccdconfhash ne '' ) { + foreach $key (keys(%ovpnccdconfhash)) { + + my $convertip = &General::ipcidr2msk($ovpnccdconfhash{$key}[1]); + + my @net = split ("/", $convertip); + + $vpnn2nip = $net[0]; + $vpnn2nmask = length($net[1]) - rindex($net[1],'.'); + + if (substr($ipaddresses[$a],0,length($ipaddresses[$a])-$dotip) eq substr($vpnn2nip,0,length($vpnn2nip)-$vpnn2nmask)) { + print"<td align='center'><img align='middle' src='$imgstatic/ovpn.png' alt='OpenVPN' title='OpenVPN' /></td>"; + last SWITCH; + } + + } + } + } + +if ( $webinterface[$a] eq 'HTTP' ) { + print"<td align='center'><a title="$Lang::tr{'wio_webinterface_link'}" href="http://$names%5B$a%5D%5C" target="_blank">$names[$a]</a></td>"; +} +elsif ( $webinterface[$a] eq 'HTTPS' ) { + print"<td align='center'><a title="$Lang::tr{'wio_webinterface_link'}" href="https://$names%5B$a%5D%5C" target="_blank">$names[$a]</a></td>"; +} +else { + print"<td align='center'>$names[$a]</td>"; +} + +print" + <td> + <table bgcolor='$bgcolor' cellpadding='2' cellspacing='0' width='100%'> + <tr height='20'> + <td align='center'><font color='$color{'color21'}'><b>$statustxt</b></font></td> + </tr> + </table> + </td> + + <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_sc_refresh'}' /> + <input type='image' name='$Lang::tr{'wio_sc_refresh'}' src='$imgstatic/refresh.png' align='middle' alt='$Lang::tr{'wio_sc_refresh'}' title='$Lang::tr{'wio_sc_refresh'}' /> + <input type='hidden' name='ID' value='$a' /></form></td> + + <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'enable disable dyndns'}' /> + <input type='image' name='$Lang::tr{'enable disable dyndns'}' src='/images/$dyndnsimg' align='middle' alt='$dyndnsimgtxt' title='$dyndnsimgtxt' /> + <input type='hidden' name='ID' value='$a' /></form></td>"; + +if ( defined($dyndns[$a]) && ($dyndns[$a] eq 'on') ) { + print"<td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_dyndns_refresh'}' /> + <input type='image' name='$Lang::tr{'wio_dyndns_refresh'}' src='/images/reload.gif' align='middle' alt='$Lang::tr{'wio_dyndns_refresh'}' title='$Lang::tr{'wio_dyndns_refresh'}' /> + <input type='hidden' name='ID' value='$a' /></form></td>"; +} +else { + print"<td width='3%' align='center'>-</td>"; +} + +if ( -e "/var/log/rrd/wio/$id[$a].rrd" ) { + print" + <td width='3%' align='center'><form method='post' action='/cgi-bin/wiographs.cgi' enctype='multipart/form-data'> + <input type='image' name='$Lang::tr{'wio_graphs'}' src='$imgstatic/graph.png' align='middle' alt='$Lang::tr{'wio_graphs'}' title='$Lang::tr{'wio_graphs'}' /> + <input type='hidden' name='HOSTID' value='$id[$a]' /><input type='hidden' name='HOSTNAME' value='$names[$a]' /></form></td> + "; +} +else { + print "<td width='3%' align='center'><img src='$imgstatic/no_graph.png' align='middle' alt='$Lang::tr{'wio_no_graphs'}' title='$Lang::tr{'wio_no_graphs'}' /></td>"; +} + +if ( $wiosettings{'SENDEMAIL'} eq 'on') { + print"<td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_mail_online'}' /> + <input type='image' name='$Lang::tr{'wio_mail_online'}' src='/images/$mailonimg' align='middle' alt='$mailonimgtxt' title='$mailonimgtxt' /> + <input type='hidden' name='ID' value='$a' /></form></td> + <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_mail_offline'}' /> + <input type='image' name='$Lang::tr{'wio_mail_offline'}' src='/images/$mailoffimg' align='middle' alt='$mailoffimgtxt' title='$mailoffimgtxt' /> + <input type='hidden' name='ID' value='$a' /></form></td>"; +} +else { + print"<td width='3%' align='center'>-</td> + <td width='3%' align='center'>-</td>"; +} + +print" + <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' /> + <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' align='middle' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' /> + <input type='hidden' name='ID' value='$a' /></form></td> + + <td width='3%' align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_remove_client'}' /> + <input type='image' name='$Lang::tr{'wio_remove_client'}' src='/images/delete.gif' align='middle' alt='$Lang::tr{'wio_remove_client'}' title='$Lang::tr{'wio_remove_client'}' onClick="return confirm('$Lang::tr{'wio_remove_client_hint'}')" /> + <input type='hidden' name='ID' value='$a' /></form></td></tr> +"; + +if ($remark[$a] && $wiosettings{'CLIENTREMARK'} eq 'on') { + print"<tr".($a % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'><td> </td><td colspan='16' align='left'>$remark[$a]</td></tr>"; +} + print"<tr height='1'><td colspan='17' bgcolor='#696565'></td></tr>"; +} + +print"</table>"; + +&Header::closebox(); + +} + +## add / modify client + +$checked{'EN'}{'on'} = ($wiosettings{'EN'} eq '' ) ? '' : "checked='checked'"; + +$checked{'DYNDNS'}{'off'} = $checked{'DYNDNS'}{'on'} = ''; +$checked{'DYNDNS'}{$wiosettings{'DYNDNS'}} = "checked='checked'"; + +$checked{'SENDEMAILON'}{'off'} = $checked{'SENDEMAILON'}{'on'} = ''; +$checked{'SENDEMAILON'}{$wiosettings{'SENDEMAILON'}} = "checked='checked'"; + +$checked{'SENDEMAILOFF'}{'off'} = $checked{'SENDEMAILOFF'}{'on'} = ''; +$checked{'SENDEMAILOFF'}{$wiosettings{'SENDEMAILOFF'}} = "checked='checked'"; + +if (! defined($errormessage) && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} ) { + $wiosettings{'PINGMETHODE'} = 'ip'; +} + +$checked{'PINGMETHODE'}{'ip'} = $checked{'PINGMETHODE'}{'fqdn'} = ''; +$checked{'PINGMETHODE'}{$wiosettings{'PINGMETHODE'}} = "checked='checked'"; + +$selected{'WEBINTERFACE'}{'----'} = ''; +$selected{'WEBINTERFACE'}{'HTTP'} = ''; +$selected{'WEBINTERFACE'}{'HTTPS'} = ''; +$selected{'WEBINTERFACE'}{$wiosettings{'WEBINTERFACE'}} = "selected='selected'"; + +$buttontext = $Lang::tr{'wio_client_add'}; + +if ( $wiosettings{'ACTION'} eq $Lang::tr{'edit'} || defined($errormessage) && ! defined($message) ) { + &Header::openbox('100%', 'left', $Lang::tr{'wio_edit_client'}); + $buttontext = $Lang::tr{'update'}; +} +else { + &Header::openbox('100%', 'left', $Lang::tr{'wio_edit_settings'}); +} + +if (! defined($errormessage) && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} ) { +print" +<table width='100%' border='0' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b> $Lang::tr{'wio_add'}</b></td> + <td width='72%' align='right'> </td> +</tr> +<tr> + <td> </td> +</tr> +</table> +"; +} + +print" +<form method='post' action='$ENV{'SCRIPT_NAME'}'> +<input type='hidden' name='ID' value='$wiosettings{'ID'}' /> +<input type='hidden' name='CLIENTID' value='$wiosettings{'CLIENTID'}' /> +<input type='hidden' name='ONLINE' value='$wiosettings{'ONLINE'}' /> +<input type='hidden' name='TIMESTAMP' value='$wiosettings{'TIMESTAMP'}' /> +"; + +print" +<table width='100%' border='0' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td height='30'>$Lang::tr{'wio_client_enable'}</td> + <td align='left'><input type='checkbox' name='EN' $checked{'EN'}{'on'} /></td> + <td colspan='4'> </td> +</tr> +<tr> + <td height='30'>$Lang::tr{'wio ipadress'}:</td> + <td align='left'><input type='text' name='IPADR' value='$wiosettings{'IPADR'}' size='25' /></td> + <td>$Lang::tr{'wio name'}:</td> + <td align='left'><input type='text' name='HOST' value='$wiosettings{'HOST'}' size='25' /></td> + <td>$Lang::tr{'remark'}:</td> + <td align='left'><input type='text' name='REMARK' value='$wiosettings{'REMARK'}' size='30'></td> +</tr> +<tr> + <td height='30'>$Lang::tr{'wio_ping_send'}:</td> + <td align='left'><input type='radio' name='PINGMETHODE' value='ip' $checked{'PINGMETHODE'}{'ip'} /> IP <input type='radio' name='PINGMETHODE' value='fqdn' $checked{'PINGMETHODE'}{'fqdn'} /> FQDN</td> + <td>$Lang::tr{'wio_dyndns'}:</td> + <td align='left'><input type='checkbox' name='DYNDNS' $checked{'DYNDNS'}{'on'} /></td> +"; + +if ( $wiosettings{'SENDEMAIL'} eq 'on' ) { + print"<td>$Lang::tr{'wio_sendemail'}:</td> + <td><input type='checkbox' name='SENDEMAILON' $checked{'SENDEMAILON'}{'on'} /> $Lang::tr{'wio_online'} <input type='checkbox' name='SENDEMAILOFF' $checked{'SENDEMAILOFF'}{'on'} /> $Lang::tr{'wio_offline'}</td>"; +} +else { + print"<td colspan='2'> </td>"; +} + +print" +</tr> +<tr> + <td height='30'>$Lang::tr{'wio_ping_send'}:</td> + <td align='left' colspan='5'> + <select size='1' name='WEBINTERFACE' width='80' style='width: 80px'> + <option value='----' $selected{'WEBINTERFACE'}{'----'}>----</option> + <option value='HTTP' $selected{'WEBINTERFACE'}{'HTTP'}>HTTP</option> + <option value='HTTPS' $selected{'WEBINTERFACE'}{'HTTPS'}>HTTPS</option> + </select> + </td> +</tr> +</table> +<table width='100%' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td width='20%' align='center'> </td> +"; + +if ( $buttontext eq $Lang::tr{'update'} && ( defined($errormessage) || $wiosettings{'ACTION'} eq $Lang::tr{'edit'}) && ! defined($message) ) { + print"<td width='20%' align='center'> </td> + <td width='20%' align='center'> </td> + <td width='20%' align='center'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_client_add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></td> + <td width='20%' align='center'><input type='button' onClick='location.href="/cgi-bin/wio.cgi"' value='$Lang::tr{'wio_back'}'></form></td>"; +} +else { + print"<td width='20%' align='center'> </td> + <td width='20%' align='center'> </td> + <td width='20%' align='center'> </td> + <td width='20%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_client_add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></form></td>"; +} + +print" +</tr> +</table> +"; + +if ( $wiosettings{'ENABLE'} eq 'on' && !$errormessage && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} || $message == 2 ) { + +&hrline(); + +## arp table entries + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b> $Lang::tr{'wio_arp_table_entries'}</b></td> + <td width='72%'> </td> +</tr> +<tr><td colspan='2'> </td></tr> +</table> + +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color20'}'> + <td width='5%' align='center' height='20'><b>$Lang::tr{'wio_id'}</b></td> + <td width='20%' align='center' height='20'><b>$Lang::tr{'wio_hwaddress'}</b></td> + <td width='20%' align='center' height='20'><b>$Lang::tr{'wio ipadress'}</b></td> + <td width='15%' align='center' height='20'><b>$Lang::tr{'wio network'}</b></td> + <td width='20%' align='center' height='20'><b>$Lang::tr{'wio name'}</b></td> + <td width='15%' align='center' height='20'><b>$Lang::tr{'wio_iface'}</b></td> + <td width='5%' align='center' height='20'><b>$Lang::tr{'action'}</b></td> +</tr> +"; + +$output = `/sbin/ip neigh list`; +$output = &Header::cleanhtml($output,"y"); + +my $arpcnt = 0; + +foreach $line (split(/\n/, $output)) +{ + if ($line =~ m/^(.*) dev ([^ ]+) lladdr ([0-9a-f:]*) (.*)$/) { + my $arphost = gethostbyaddr(inet_aton($1), AF_INET); + if ( $arphost eq 'localhost' ) { $arphost = ''; } + push (@arpcache, "$3,$1,$arphost,$2\n"); + } + elsif ($line =~ m/^(.*) dev ([^ ]+) (.*)$/) { + my $arphost = gethostbyaddr(inet_aton($1), AF_INET); + if ( $arphost eq 'localhost' ) { $arphost = ''; } + push (@arpcache, ",$1,$arphost,$2\n"); + } + + $arpcnt++; +} + +&SortDataFile('arpcache',@arpcache); + +foreach (@arpcache) { + chomp; + + @line = split (/,/, $_); + + print"<tr".($idarp % 2?" bgcolor='$color{'color20'}'":" bgcolor='$color{'color22'}'")." height='20'>"; + printf ("<td align='center'> %02d</td>", $idarp+1); + print"<td align='center'>$line[0]</td> + <td align='center'>$line[1]</td>"; + +SWITCH: { + + foreach (@devs_color) { + my $in = 0; + $ic = "${_}"; + + foreach $interface (@devs_net) { + next if ( $netsettings{"$ic"."_DEV"} eq 'red0' && ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE')); + + if ($netsettings{"$ic"."_DEV"} eq $interface) { + if ( &General::IpInSubnet($line[1], $netsettings{"$ic"."_NETADDRESS"}, $netsettings{"$ic"."_NETMASK"}) ) { + print"<td align='center'><img src='$imgstatic/$devs_img[$in]' alt='$Lang::tr{$devs_alt[$in]}' title='$Lang::tr{$devs_alt[$in]}' /></td>"; + last SWITCH; + } + } + + $in++; + } + } + + if ($netsettings{"RED_TYPE"} eq 'DHCP' || $netsettings{"RED_TYPE"} eq 'PPPOE') { + my $redipadr = qx'ip addr | grep red0 | grep inet | awk "{print $2}"'; + my @rednet = split ("/", $redipadr); + chomp ($rednet[1]); + my $red_netmask = General::iporsubtodec($rednet[1]); + my $red_netaddress = Network::get_netaddress("$rednet[0]/$red_netmask"); + + if ( &General::IpInSubnet($line[1], $red_netaddress, $red_netmask) ) { + print"<td align='center' height='20'><img src='$imgstatic/red.png' alt='$Lang::tr{'wio_red_lan'}' title='$Lang::tr{'wio_red_lan'}' /></td>"; + last SWITCH; + } + else { + print"<td align='center'><img align='middle' src='$imgstatic/white.png' alt='$Lang::tr{'wio_unknown_lan'}' title='$Lang::tr{'wio_unknown_lan'}' /></td>"; + last SWITCH; + } + } +} + + print"<td align='center'>$line[2]</td> + <td align='center'>".&WIO::color_devices($line[3])."</td>"; + + unless (&WIO::checkinto($line[1], '', @current)) { + print"<td align='center'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'> + <input type='hidden' name='ACTION' value='$Lang::tr{'wio_add'}' /> + <input type='image' name='$Lang::tr{'wio_add'}' src='/images/add.gif' align='middle' alt='$Lang::tr{'wio_add'}' title='$Lang::tr{'wio_add'}' /> + <input type='hidden' name='ID' value='$idarp' /></form></td>"; + } + else { + print"<td align='center'><img src='$imgstatic/add.png' align='middle' alt='$Lang::tr{'wio_no_add'}' title='$Lang::tr{'wio_no_add'}' /></td>"; + } + +print"</tr>"; +print"<tr height='1'><td colspan='17' bgcolor='#696565'></td></tr>"; +$idarp++ +} + +print" +</table> +"; + +&hrline(); + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b> $Lang::tr{'wio_import_file'}</b></td> + <td width='72%'> </td> +</tr> +<tr><td colspan='2'> </td></tr> +</table> +<table width='100%' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color22'}'> + <form method='post' action='/cgi-bin/wio.cgi' enctype='multipart/form-data'> + <td width='35%' align='right'>$Lang::tr{'wio_import_csv'} </td> + <td width='40%' align='center'><input type='file' name='CSVFILE' size='30' /></td> + <td width='25%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_import'}1' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_import'}' /></td> + </form> +</tr> +<tr><td colspan='3'> </td></tr> +<tr bgcolor='$color{'color22'}'> + <form method='post' action='/cgi-bin/wio.cgi' enctype='multipart/form-data'> + <td width='35%' align='right'>$Lang::tr{'wio_import_hosts'} </td> + <td width='40%' align='center'> </td> + <td width='25%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_import'}2' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_import'}' /></td> + </form> +</tr> +<tr><td colspan='3'> </td></tr> +<tr bgcolor='$color{'color22'}'> + <form method='post' action='/cgi-bin/wio.cgi' enctype='multipart/form-data'> + <td width='35%' align='right'>$Lang::tr{'wio_import_fixleases'} </td> + <td width='40%' align='center'> </td> + <td width='25%' align='right'><input type='hidden' name='ACTION' value='$Lang::tr{'wio_import'}3' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_import'}' /></td> + </form> +</tr> +</table> +"; + +&hrline; + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td width='28%' bgcolor='$color{'color20'}' align='left' height='20'><b> $Lang::tr{'wio_net_scan'}</b></td> + <td width='72%'> </td> +</tr> +</table> +<table width='100%' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr> + <td colspan='3'> </td> +</tr> +"; + +foreach (keys(%ifacecolor)) { + if ( $_ eq 'GREEN' ) { $color = "$Header::colourgreen"; $net = $Lang::tr{'wio_net_scan_green'}; } + elsif ( $_ eq 'BLUE' ) { $color = "$Header::colourblue"; $net = $Lang::tr{'wio_net_scan_blue'}; } + else { $color = "$Header::colourorange"; $net = $Lang::tr{'wio_net_scan_orange'}; } + + if ( $netsettings{"${_}_DEV"} eq 'disabled' || $netsettings{"${_}_DEV"} eq '' || $netsettings{"${_}_ADDRESS"} eq '' ) { next; } + else { + print <<END; + + <tr bgcolor='$color{'color22'}'> + <td width='35%' align='right'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'>$Lang::tr{'wio_net_scan_vl'} <font color='$color'><b>$net</b></font> $Lang::tr{'wio_net_scan_l'}<font color='$color'><b> $netsettings{"${_}_DEV"} </b></font>$Lang::tr{'wio_net_scan_r'}</td> + <td width='40%' align='center'><input type='text' name='${_}_IPLOW' value='$wiosettings{"${_}_IPLOW"}' size='14' STYLE='background-color:$color; text-align: center; color:white' /> - <input type='text' name='${_}_IPHIGH' value='$wiosettings{"${_}_IPHIGH"}' size='14' STYLE='background-color:$color; text-align: center; color:white' /></td> + <td width='25%' align='right'><input type='hidden' name='ACTION' value='$ifacecolor{$_}' /><input type='hidden' name='ID' value='$netsettings{"${_}_DEV"}' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_net_scan_run'}'></form></td> + </tr> + <tr> + <td colspan='3'> </td> + </tr> +END + } +} + +print" +</tr> +</table> +</form> +"; + +&Header::closebox(); +} + +if ( $wiosettings{'ENABLE'} eq 'on' && !$errormessage && $wiosettings{'ACTION'} ne $Lang::tr{'edit'} || $message == 2 ) { + +&Header::openbox('100%', 'left', $Lang::tr{'wio_service'}); + +print" +<table border='0' width='100%' bordercolor='$Header::bordercolour' cellspacing='0' cellpadding='0' style='border-collapse: collapse'> +<tr bgcolor='$color{'color22'}'> + <td colspan='2' align='right'></td> + <td width='10%' align='right'><form method='post' action='/cgi-bin/logs.cgi/log.dat' enctype='multipart/form-data'><input type='hidden' name='SECTION' value='wio' /><input type='submit' name='SUBMIT' value='$Lang::tr{'system logs'}' /></form></td> + <td width='10%' align='right'><form method='post' action='$ENV{'SCRIPT_NAME'}' enctype='multipart/form-data'><input type='hidden' name='ACTION' value='$Lang::tr{'edit'}1' /><input type='submit' name='SUBMIT' value='$Lang::tr{'wio_edit_set'}' /></form></td> +</tr> +</table> +"; +} + +&Header::closebox(); +} + +&Header::closebigbox(); +&Header::closepage(); + +############################################################################################################################ + +sub SortDataFile { +my ($data,@checkfile) = @_; + my $idsort = 0; + our %entries = (); + + sub sortips { + my $qs = ''; + + if (rindex ($wiosettings{'SORT'},'Rev') != -1) { + $qs = substr ($wiosettings{'SORT'},0,length($wiosettings{'SORT'})-3); + + if ($qs eq 'IPADR') { + my @a = split (/./,$entries{$a}->{$qs}); + my @b = split (/./,$entries{$b}->{$qs}); + ($b[0]<=>$a[0]) || + ($b[1]<=>$a[1]) || + ($b[2]<=>$a[2]) || + ($b[3]<=>$a[3]); + } + else { + $entries{$b}->{$qs} cmp $entries{$a}->{$qs}; + } + } + else { + $qs = $wiosettings{'SORT'}; + + if ($qs eq 'IPADR') { + my @a = split (/./,$entries{$a}->{$qs}); + my @b = split (/./,$entries{$b}->{$qs}); + ($a[0]<=>$b[0]) || + ($a[1]<=>$b[1]) || + ($a[2]<=>$b[2]) || + ($a[3]<=>$b[3]); + } + else { + $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; + } + } + } + + if ($data eq 'arpcache') { + foreach (@checkfile) { + chomp; + @temp = split (',', $_); + + my @record = ('KEY',$idsort++,'MAC',$temp[0],'IPADR',$temp[1],'HOST',$temp[2],'REMARK',$temp[3],'IFACE',$temp[4]); + my $record = (); + %{$record} = @record; + $entries{$record->{KEY}} = $record; + } + + open(FILE, "> $logdir/.arpcache"); + + foreach (sort sortips keys %entries) { + print FILE "$entries{$_}->{MAC},$entries{$_}->{IPADR},$entries{$_}->{HOST},$entries{$_}->{REMARK},$entries{$_}->{IFACE},$entries{$_}->{HW}\n"; + } + + close(FILE); + + open (FILE, "$logdir/.arpcache"); + @arpcache = <FILE>; + close (FILE); + } + else { + foreach (@checkfile) { + chomp; + @temp = split (',', $_); + + my @record = ('KEY',$idsort++,'CLIENTID',$temp[0],'TIMESTAMP',$temp[1],'IPADR',$temp[2],'HOST',$temp[3],'EN',$temp[4],'REMARK',$temp[5],'DYNDNS',$temp[6],'SENDEMAILON',$temp[7],'SENDEMAILOFF',$temp[8],'PINGMETHODE',$temp[9],'ONLINE',$temp[10],'WEBINTERFACE',$temp[11]); + my $record = (); + %{$record} = @record; + $entries{$record->{KEY}} = $record; + } + + open(FILE, "> $ipadrfile"); + + foreach (sort sortips keys %entries) { + print FILE "$entries{$_}->{CLIENTID},$entries{$_}->{TIMESTAMP},$entries{$_}->{IPADR},$entries{$_}->{HOST},$entries{$_}->{EN},$entries{$_}->{REMARK},$entries{$_}->{DYNDNS},$entries{$_}->{SENDEMAILON},$entries{$_}->{SENDEMAILOFF},$entries{$_}->{PINGMETHODE},$entries{$_}->{ONLINE},$entries{$_}->{WEBINTERFACE}\n"; + } + + close(FILE); + + &loadips(); + } +} + +############################################################################################################################ + +sub hrline { + +print"<table width='100%'><tr><td colspan='2' height='35'><hr></td></tr></table>"; + +} + +############################################################################################################################ + +sub back { + +print"<table width='100%'><tr><td width='10%'><a href='/cgi-bin/wio.cgi'><img src='/images/wio/back.png' alt='$Lang::tr{'wio_back'}' title='$Lang::tr{'wio_back'}' /></a></td><td> </td></tr></table>"; + +} + +############################################################################################################################ + +sub loadips { + +&General::readhasharray($ipadrfile, %ipshash); + +open(FILE, "< $ipadrfile"); +@current = <FILE>; +close (FILE); + +} + +############################################################################################################################ + +sub writeips { + +open(FILE, "> $ipadrfile"); +if ( defined($write) ) { print FILE @write; } +else { print FILE @current; } +close(FILE); + +} + +############################################################################################################################ + +sub SortByTunnelName +{ + if ($vpnconfighash{$a}[1] lt $vpnconfighash{$b}[1]) { + return -1; + } + elsif ($vpnconfighash{$a}[1] gt $vpnconfighash{$b}[1]) { + return 1; + } + else { + return 0; + } +} + +############################################################################################################################ + +sub validSave +{ + if ( $wiosettings{'IPADR'} eq '' && $wiosettings{'PINGMETHODE'} eq 'ip' && $wiosettings{'DYNDNS'} eq '' ) { + $errormessage = $Lang::tr{'wio_ip_empty'}; + } + + if ( $wiosettings{'IPADR'} ne '' && (! &General::validip($wiosettings{'IPADR'})) ) { + $errormessage = $Lang::tr{'wio_ip_error'}; + } + + if ( $wiosettings{'HOST'} eq '' && $wiosettings{'PINGMETHODE'} eq 'fqdn' ) { + $errormessage = $Lang::tr{'wio_host_empty'}; + } + + if ( $wiosettings{'HOST'} ne '' && (! &General::validdomainname($wiosettings{'HOST'})) ) { + $errormessage = $Lang::tr{'wio_host_error'}; + } + + if ( $wiosettings{'DYNDNS'} eq 'on' && (! defined($errormessage)) ) { + unless(&General::validfqdn($wiosettings{'HOST'})) { $errormessage = $Lang::tr{'wio_fqdn_error'}; } + ( $wiosettings{'IPADR'}, $infomessage ) = &WIO::getdyndnsip($wiosettings{'IPADR'}, $wiosettings{'HOST'}); + $wiosettings{'PINGMETHODE'} = 'fqdn'; + } + + if ( $wiosettings{'ID'} eq '' && ! defined($errormessage) ) { $errormessage = &WIO::checkinto($wiosettings{'IPADR'}, $wiosettings{'HOST'}, @current); } + + if ( $wiosettings{'REMARK'} ne '' ) { $wiosettings{'REMARK'} =~ s/,/,/g; } +} diff --git a/src/wio/wiographs.cgi b/src/wio/wiographs.cgi new file mode 100644 index 0000000..7370237 --- /dev/null +++ b/src/wio/wiographs.cgi @@ -0,0 +1,73 @@ +#!/usr/bin/perl +# +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2017 Stephan Feddersen addons@h-loit.de # +# All Rights Reserved. # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see http://www.gnu.org/licenses/. # +# # +############################################################################### +# +# id: wiographs.cgi, v1.3.1 2017/07/11 21:31:16 sfeddersen +# +# This wiographs.cgi is based on the Code from the IPCop WIO Addon +# and is extremly adapted to work with IPFire. +# +# Autor: Stephan Feddersen +# Co-Autor: Alexander Marx +# + +use strict; + +# enable only the following on debugging purpose +#use warnings; +#no warnings 'once'; +#use CGI::Carp 'fatalsToBrowser'; + +use CGI; +my $cgi = new CGI; +my $hostid = $cgi->param("HOSTID"); +my $hostname = $cgi->param("HOSTNAME"); + +require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/header.pl'; +require '/var/ipfire/lang.pl'; +require '/usr/lib/wio/wio-graphs.pl'; + +my @querry = split(/?/,$ENV{'QUERY_STRING'}); + +$querry[0] = '' unless defined $querry[0]; # hostid +$querry[1] = '' unless defined $querry[1]; # period +$querry[2] = '' unless defined $querry[2]; # hostname + +if ($querry[0] =~ "$hostid") { + print "Content-type: image/png\n\n"; + binmode(STDOUT); + &WIOGraphs::wio($querry[0], $querry[2], $querry[1]); +} +else { + &Header::showhttpheaders(); + &Header::openpage("$Lang::tr{'wio'}", 1, ''); + &Header::openbigbox('100%', 'left'); + &Header::openbox('100%', 'left', "$Lang::tr{'wio_graphs_stat'} $hostname"); + &WIOGraphs::wiographbox("wiographs.cgi","$hostid","day","$hostname"); + print"<table width='100%'><tr><td align='center'><a href='/cgi-bin/wio.cgi'><img src='/images/wio/back.png' alt='$Lang::tr{'wio_back'}' title='$Lang::tr{'wio_back'}' /></a></td></tr></table>"; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); +} + +1; diff --git a/src/wio/wioips b/src/wio/wioips new file mode 100644 index 0000000..e69de29
hooks/post-receive -- IPFire 2.x development tree