Merge remote-tracking branch 'origin/next' into install-raid

This commit is contained in:
Michael Tremer
2014-08-20 21:46:49 +02:00
273 changed files with 32959 additions and 2113 deletions

View File

@@ -71,6 +71,13 @@ create_files() {
case "${1}" in
start)
if [[ ! -L "/var/run" ]]; then
boot_mesg "Repair /var/run symlink to /run..."
mv -u /var/run/* /run/ 2>&1 > /dev/null
rm -rf /var/run
ln -s ../run /var/run
fi
boot_mesg -n "Cleaning file systems:" ${INFO}
boot_mesg -n " /tmp" ${NORMAL}

53
src/initscripts/init.d/dhcrelay Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/sh
########################################################################
# Begin $rc_base/init.d/dhcrelay
#
# Description : The DHCP Relay Daemon
#
########################################################################
. /etc/sysconfig/rc
. ${rc_functions}
CONFIG_FILE="/var/ipfire/dhcp/relay"
if [ -r "${CONFIG_FILE}" ]; then
eval $(/usr/local/bin/readhash ${CONFIG_FILE})
fi
ARGS="-q"
for interface in ${INTERFACES}; do
ARGS="${ARGS} -i ${interface}"
done
ARGS="${ARGS} ${SERVERS}"
case "${1}" in
start)
boot_mesg "Starting DHCP Relay..."
loadproc /usr/sbin/dhcrelay ${ARGS}
;;
stop)
boot_mesg "Stopping DHCP Relay..."
killproc -p /var/run/dhcrelay.pid /usr/sbin/dhcrelay
;;
restart)
${0} stop
sleep 1
${0} start
;;
status)
statusproc /usr/sbin/dhcrelay
;;
*)
echo "Usage: ${0} {start|stop|restart|status}"
exit 1
;;
esac
# End $rc_base/init.d/dhcrelay

View File

@@ -20,7 +20,20 @@ if [ -e "/etc/sysconfig/dnsmasq" ]; then
. /etc/sysconfig/dnsmasq
fi
CACHE_SIZE=2500
ENABLE_DNSSEC=1
SHOW_SRV=1
TRUST_ANCHOR=".,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
function dnssec_args() {
local cmdline="--dnssec"
if [ -n "${TRUST_ANCHOR}" ]; then
cmdline="${cmdline} --trust-anchor=${TRUST_ANCHOR}"
fi
echo "${cmdline}"
}
function dns_forward_args() {
local file="${1}"
@@ -41,7 +54,6 @@ function dns_forward_args() {
echo "${cmdline}"
}
case "${1}" in
start)
# kill already running copy of dnsmasq...
@@ -73,6 +85,15 @@ case "${1}" in
# Add custom forward dns zones.
ARGS="${ARGS} $(dns_forward_args /var/ipfire/dnsforward/config)"
# Enabled DNSSEC validation
if [ "${ENABLE_DNSSEC}" -eq 1 ]; then
ARGS="${ARGS} $(dnssec_args)"
fi
if [ -n "${CACHE_SIZE}" ]; then
ARGS="${ARGS} --cache-size=${CACHE_SIZE}"
fi
loadproc /usr/sbin/dnsmasq -l /var/state/dhcp/dhcpd.leases $ARGS
if [ "${SHOW_SRV}" -eq 1 ] && [ "${DNS1}" != "" -o "${DNS2}" != "" ]; then

View File

@@ -64,16 +64,20 @@ iptables_init() {
iptables -A BADTCP -i lo -j RETURN
# Disallow packets frequently used by port-scanners
# nmap xmas
iptables -A BADTCP -p tcp --tcp-flags ALL FIN,URG,PSH -j PSCAN
# Null
iptables -A BADTCP -p tcp --tcp-flags ALL NONE -j PSCAN
# FIN
# NMAP FIN/URG/PSH (XMAS scan)
iptables -A BADTCP -p tcp --tcp-flags ALL FIN,URG,PSH -j PSCAN
# SYN/RST/ACK/FIN/URG
iptables -A BADTCP -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j PSCAN
# ALL/ALL
iptables -A BADTCP -p tcp --tcp-flags ALL ALL -j PSCAN
# FIN Stealth
iptables -A BADTCP -p tcp --tcp-flags ALL FIN -j PSCAN
# SYN/RST (also catches xmas variants that set SYN+RST+...)
iptables -A BADTCP -p tcp --tcp-flags SYN,RST SYN,RST -j PSCAN
# SYN/FIN (QueSO or nmap OS probe)
iptables -A BADTCP -p tcp --tcp-flags SYN,FIN SYN,FIN -j PSCAN
# Null
iptables -A BADTCP -p tcp --tcp-flags ALL NONE -j PSCAN
# NEW TCP without SYN
iptables -A BADTCP -p tcp ! --syn -m conntrack --ctstate NEW -j NEWNOTSYN
@@ -83,6 +87,7 @@ iptables_init() {
# Connection tracking chain
iptables -N CONNTRACK
iptables -A CONNTRACK -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A CONNTRACK -m conntrack --ctstate INVALID -j DROP
# Fix for braindead ISP's
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
@@ -254,20 +259,6 @@ iptables_init() {
iptables -t nat -N REDNAT
iptables -t nat -A POSTROUTING -j REDNAT
# Filter logging of incoming broadcasts.
iptables -N BROADCAST_FILTER
iptables -A INPUT -j BROADCAST_FILTER
iptables -A BROADCAST_FILTER -i "${GREEN_DEV}" -d "${GREEN_BROADCAST}" -j DROP
if [ -n "${BLUE_DEV}" -a -n "${BLUE_BROADCAST}" ]; then
iptables -A BROADCAST_FILTER -i "${BLUE_DEV}" -d "${BLUE_BROADCAST}" -j DROP
fi
if [ -n "${ORANGE_DEV}" -a -n "${ORANGE_BROADCAST}" ]; then
iptables -A BROADCAST_FILTER -i "${ORANGE_DEV}" -d "${ORANGE_BROADCAST}" -j DROP
fi
# Apply OpenVPN firewall rules
/usr/local/bin/openvpnctrl --firewall-rules
@@ -286,10 +277,16 @@ iptables_init() {
/usr/sbin/firewall-policy
# Install firewall rules for the red interface.
iptables_red
iptables_red_up
# If red has not been brought up yet, we will
# add the blocking rules for MASQUERADE
if [ ! -e "/var/ipfire/red/active" ]; then
iptables_red_down
fi
}
iptables_red() {
iptables_red_up() {
iptables -F REDINPUT
iptables -F REDFORWARD
iptables -t nat -F REDNAT
@@ -336,16 +333,49 @@ iptables_red() {
# Outgoing masquerading (don't masqerade IPSEC (mark 50))
iptables -t nat -A REDNAT -m mark --mark 50 -o $IFACE -j RETURN
if [ "$IFACE" != "$GREEN_DEV" ]; then
iptables -t nat -A REDNAT -o $IFACE -j MASQUERADE
if [ "$IFACE" = "$GREEN_DEV" ]; then
MASQUERADE_GREEN="off"
fi
local NO_MASQ_NETWORKS
if [ "${MASQUERADE_GREEN}" = "off" ]; then
NO_MASQ_NETWORKS="${NO_MASQ_NETWORKS} ${GREEN_NETADDRESS}/${GREEN_NETMASK}"
fi
if [ "${MASQUERADE_BLUE}" = "off" ]; then
NO_MASQ_NETWORKS="${NO_MASQ_NETWORKS} ${BLUE_NETADDRESS}/${BLUE_NETMASK}"
fi
if [ "${MASQUERADE_ORANGE}" = "off" ]; then
NO_MASQ_NETWORKS="${NO_MASQ_NETWORKS} ${ORANGE_NETADDRESS}/${ORANGE_NETMASK}"
fi
local network
for network in ${NO_MASQ_NETWORKS}; do
iptables -t nat -A REDNAT -s "${network}" -o "${IFACE}" -j RETURN
done
# Masquerade everything else
iptables -t nat -A REDNAT -o $IFACE -j MASQUERADE
fi
# Reload all rules.
/usr/local/bin/firewallctrl
}
iptables_red_down() {
# Prohibit packets to reach the masquerading rule
# while the wan interface is down - this is required to
# circumvent udp related NAT issues
# http://forum.ipfire.org/index.php?topic=11127.0
iptables -F REDFORWARD
iptables -A REDFORWARD -o $IFACE -j DROP
# Reload all rules.
/usr/local/bin/firewallctrl
}
# See how we were called.
case "$1" in
start)
@@ -376,9 +406,9 @@ case "$1" in
/etc/sysconfig/firewall.local start
fi
;;
reload)
reload|up)
boot_mesg "Reloading firewall"
iptables_red
iptables_red_up
evaluate_retval
# run local firewall configuration, if present
@@ -386,6 +416,11 @@ case "$1" in
/etc/sysconfig/firewall.local reload
fi
;;
down)
boot_mesg "Disabling firewall access to RED"
iptables_red_down
evaluate_retval
;;
restart)
# run local firewall configuration, if present
if [ -x /etc/sysconfig/firewall.local ]; then

View File

@@ -0,0 +1,3 @@
#!/bin/bash
exec /etc/rc.d/init.d/firewall down

View File

@@ -0,0 +1,3 @@
#!/bin/bash
exec /etc/rc.d/init.d/firewall up

View File

@@ -1,5 +1,3 @@
#!/bin/bash
/usr/local/bin/setddns.pl -f
exit 0
exec /usr/bin/ddns update-all

View File

@@ -28,12 +28,18 @@ case "${1}" in
fi
boot_mesg "Starting Random Number Generator Daemon..."
loadproc /usr/sbin/rngd --no-tpm=1
if pidofproc /usr/sbin/rngd &>/dev/null; then
# Is already running.
echo_ok
else
loadproc /usr/sbin/rngd --no-tpm=1
fi
;;
stop)
boot_mesg "Stopping Random Number Generator Daemon..."
killproc /usr/sbin/rngd
killproc -p /var/run/rngd.pid /usr/sbin/rngd
;;
restart)

View File

@@ -4,19 +4,28 @@
# Based on sysklogd script from LFS-3.1 and earlier.
# Rewritten by Gerard Beekmans - gerard@linuxfromscratch.org
#$LastChangedBy: bdubbs $
#$Date: 2005-08-01 14:29:19 -0500 (Mon, 01 Aug 2005) $
. /etc/sysconfig/rc
. $rc_functions
function fix_permissions() {
local lockdir="/var/lib/samba/winbindd_privileged"
chmod 750 "${lockdir}"
chgrp wbpriv "${lockdir}"
}
case "$1" in
start)
fix_permissions
boot_mesg "Starting nmbd..."
loadproc /usr/sbin/nmbd -D
boot_mesg "Starting smbd..."
loadproc /usr/sbin/smbd -D
boot_mesg "Starting winbind..."
loadproc /usr/sbin/winbindd
;;
stop)
@@ -25,6 +34,9 @@ case "$1" in
boot_mesg "Stopping nmbd..."
killproc -p /var/run/nmbd.pid /usr/sbin/nmbd
boot_mesg "Stopping winbind..."
killproc -p /var/run/winbindd.pid /usr/sbin/winbindd
;;
reload)
@@ -33,6 +45,9 @@ case "$1" in
boot_mesg "Reloading nmbd..."
reloadproc /usr/sbin/nmbd
boot_mesg "Reloading winbind..."
reloadproc /usr/sbin/winbindd
;;
restart)
@@ -44,6 +59,7 @@ case "$1" in
status)
statusproc /usr/sbin/nmbd
statusproc /usr/sbin/smbd
statusproc /usr/sbin/winbindd
;;
*)

View File

@@ -1,50 +0,0 @@
#!/bin/bash
# Begin $rc_base/init.d/winbind
# Based on sysklogd script from LFS-3.1 and earlier.
# Rewritten by Gerard Beekmans - gerard@linuxfromscratch.org
#$LastChangedBy: bdubbs $
#$Date: 2005-08-01 14:29:19 -0500 (Mon, 01 Aug 2005) $
. /etc/sysconfig/rc
. $rc_functions
PIDFILE="/var/run/winbindd.pid"
KILLDELAY="10"
case "$1" in
start)
boot_mesg "Starting winbind..."
loadproc /usr/sbin/winbindd
;;
stop)
boot_mesg "Stopping winbind..."
killproc -p ${PIDFILE} /usr/sbin/winbind
;;
reload)
boot_mesg "Reloading winbind..."
reloadproc /usr/sbin/winbindd
;;
restart)
$0 stop
sleep 1
$0 start
;;
status)
statusproc /usr/sbin/winbindd
;;
*)
echo "Usage: $0 {start|stop|reload|restart|status}"
exit 1
;;
esac
# End $rc_base/init.d/winbind

View File

@@ -10,165 +10,136 @@
char command[BUFFER_SIZE];
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
if (!(initsetuid()))
exit(1);
if (!(initsetuid()))
exit(1);
// Check what command is asked
if (argc == 1) {
fprintf (stderr, "Missing smbctrl command!\n");
return 1;
// Check what command is asked
if (argc==1)
{
fprintf (stderr, "Missing smbctrl command!\n");
return 1;
}
else if (strcmp(argv[1], "smbuserdisable")==0)
{
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -d %s >/dev/null", argv[2]);
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "smbuserenable")==0)
{
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -e %s >/dev/null", argv[2]);
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "smbuserdelete")==0)
{
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -x %s >/dev/null", argv[2]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/userdel %s >/dev/null", argv[2]);
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "smbsafeconf")==0)
{
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/shares > /var/ipfire/samba/smb.conf");
return 0;
}
else if (strcmp(argv[1], "smbsafeconfcups")==0)
{
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/shares /var/ipfire/samba/printer > /var/ipfire/samba/smb.conf");
return 0;
}
else if (strcmp(argv[1], "smbsafeconfpdc")==0)
{
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/pdc /var/ipfire/samba/shares > /var/ipfire/samba/smb.conf");
return 0;
}
else if (strcmp(argv[1], "smbsafeconfpdccups")==0)
{
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/pdc /var/ipfire/samba/shares /var/ipfire/samba/printer > /var/ipfire/samba/smb.conf");
return 0;
}
else if (strcmp(argv[1], "smbglobalreset")==0)
{
safe_system("/bin/cat /var/ipfire/samba/default.global /var/ipfire/samba/shares > /var/ipfire/samba/smb.conf");
safe_system("/bin/cat /var/ipfire/samba/default.settings > /var/ipfire/samba/settings");
safe_system("/bin/cat /var/ipfire/samba/default.global > /var/ipfire/samba/global");
safe_system("/bin/cat /var/ipfire/samba/default.pdc > /var/ipfire/samba/pdc");
return 0;
}
else if (strcmp(argv[1], "smbsharesreset")==0)
{
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/default.shares > /var/ipfire/samba/smb.conf");
safe_system("/bin/cat /var/ipfire/samba/default.shares > /var/ipfire/samba/shares");
return 0;
}
else if (strcmp(argv[1], "smbprinterreset")==0)
{
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/shares /var/default.printer > /var/ipfire/samba/smb.conf");
safe_system("/bin/cat /var/ipfire/samba/default.printer > /var/ipfire/samba/printer");
return 0;
}
else if (strcmp(argv[1], "smbstop")==0)
{
safe_system("/etc/rc.d/init.d/samba stop >/dev/null");
safe_system("/usr/local/bin/sambactrl disable");
return 0;
}
else if (strcmp(argv[1], "smbstart")==0)
{
safe_system("/etc/rc.d/init.d/samba start >/dev/null");
safe_system("/usr/local/bin/sambactrl enable");
return 0;
}
else if (strcmp(argv[1], "smbrestart")==0)
{
safe_system("/etc/rc.d/init.d/samba restart >/dev/null");
return 0;
}
else if (strcmp(argv[1], "smbreload")==0)
{
safe_system("/etc/rc.d/init.d/samba reload >/dev/null");
return 0;
}
else if (strcmp(argv[1], "smbstatus")==0)
{
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbstatus 2>/dev/null");
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "smbuseradd")==0)
{
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/groupadd sambauser >/dev/null");
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/useradd -c 'Samba User' -m -g %s -s %s %s >/dev/null", argv[4], argv[5], argv[2]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "echo %s:%s | chpasswd", argv[2], argv[3]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/bin/printf '%s\n%s\n' | /usr/bin/smbpasswd -as %s >/dev/null", argv[3], argv[3], argv[2]);
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "smbpcadd")==0)
{
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/groupadd sambawks >/dev/null");
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/useradd -c 'Samba Workstation' -g %s -s %s %s >/dev/null", argv[3], argv[4], argv[2]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -a -m %s >/dev/null", argv[2]);
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "smbchangepw")==0)
{
snprintf(command, BUFFER_SIZE-1, "echo %s:%s | chpasswd", argv[2], argv[3]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/bin/printf '%s\n%s\n' | /usr/bin/smbpasswd -as %s >/dev/null", argv[3], argv[3], argv[2]);
safe_system(command);
return 0;
}
else if (strcmp(argv[1], "readsmbpasswd")==0)
{
safe_system("/bin/chown root:nobody /var/ipfire/samba/private >/dev/null");
safe_system("/bin/chown root:nobody /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 640 /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 650 /var/ipfire/samba/private >/dev/null");
return 0;
}
else if (strcmp(argv[1], "locksmbpasswd")==0)
{
safe_system("/bin/chown root:root /var/ipfire/samba/private >/dev/null");
safe_system("/bin/chown root:root /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 600 /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 600 /var/ipfire/samba/private >/dev/null");
return 0;
}
else if (strcmp(argv[1], "enable")==0)
{
safe_system("touch /var/ipfire/samba/enable");
safe_system("ln -snf /etc/rc.d/init.d/samba /etc/rc.d/rc3.d/S45samba");
safe_system("ln -snf /etc/rc.d/init.d/samba /etc/rc.d/rc0.d/K48samba");
safe_system("ln -snf /etc/rc.d/init.d/samba /etc/rc.d/rc6.d/K48samba");
return 0;
}
else if (strcmp(argv[1], "disable")==0)
{
safe_system("unlink /var/ipfire/samba/enable");
safe_system("rm -rf /etc/rc.d/rc*.d/*samba");
return 0;
}
return 0;
} else if (strcmp(argv[1], "smbuserdisable") == 0) {
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -d %s >/dev/null", argv[2]);
safe_system(command);
} else if (strcmp(argv[1], "smbuserenable") == 0) {
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -e %s >/dev/null", argv[2]);
safe_system(command);
} else if (strcmp(argv[1], "smbuserdelete") == 0) {
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -x %s >/dev/null", argv[2]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/userdel %s >/dev/null", argv[2]);
safe_system(command);
} else if (strcmp(argv[1], "smbsafeconf") == 0) {
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/shares > /var/ipfire/samba/smb.conf");
} else if (strcmp(argv[1], "smbsafeconfcups") == 0) {
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/shares /var/ipfire/samba/printer > /var/ipfire/samba/smb.conf");
} else if (strcmp(argv[1], "smbsafeconfpdc") == 0) {
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/pdc /var/ipfire/samba/shares > /var/ipfire/samba/smb.conf");
} else if (strcmp(argv[1], "smbsafeconfpdccups") == 0) {
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/pdc /var/ipfire/samba/shares /var/ipfire/samba/printer > /var/ipfire/samba/smb.conf");
} else if (strcmp(argv[1], "smbglobalreset") == 0) {
safe_system("/bin/cat /var/ipfire/samba/default.global /var/ipfire/samba/shares > /var/ipfire/samba/smb.conf");
safe_system("/bin/cat /var/ipfire/samba/default.settings > /var/ipfire/samba/settings");
safe_system("/bin/cat /var/ipfire/samba/default.global > /var/ipfire/samba/global");
safe_system("/bin/cat /var/ipfire/samba/default.pdc > /var/ipfire/samba/pdc");
} else if (strcmp(argv[1], "smbsharesreset") == 0) {
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/default.shares > /var/ipfire/samba/smb.conf");
safe_system("/bin/cat /var/ipfire/samba/default.shares > /var/ipfire/samba/shares");
} else if (strcmp(argv[1], "smbprinterreset") == 0) {
safe_system("/bin/cat /var/ipfire/samba/global /var/ipfire/samba/shares /var/default.printer > /var/ipfire/samba/smb.conf");
safe_system("/bin/cat /var/ipfire/samba/default.printer > /var/ipfire/samba/printer");
} else if (strcmp(argv[1], "smbstop") == 0) {
safe_system("/etc/rc.d/init.d/samba stop >/dev/null");
safe_system("/usr/local/bin/sambactrl disable");
} else if (strcmp(argv[1], "smbstart") == 0) {
safe_system("/etc/rc.d/init.d/samba start >/dev/null");
safe_system("/usr/local/bin/sambactrl enable");
} else if (strcmp(argv[1], "smbrestart") == 0) {
safe_system("/etc/rc.d/init.d/samba restart >/dev/null");
} else if (strcmp(argv[1], "smbreload") == 0) {
safe_system("/etc/rc.d/init.d/samba reload >/dev/null");
} else if (strcmp(argv[1], "smbstatus") == 0) {
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbstatus 2>/dev/null");
safe_system(command);
} else if (strcmp(argv[1], "smbuseradd") == 0) {
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/groupadd sambauser >/dev/null");
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/useradd -c 'Samba User' -m -g %s -s %s %s >/dev/null", argv[4], argv[5], argv[2]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "echo %s:%s | chpasswd", argv[2], argv[3]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/bin/printf '%s\n%s\n' | /usr/bin/smbpasswd -as %s >/dev/null", argv[3], argv[3], argv[2]);
safe_system(command);
} else if (strcmp(argv[1], "smbpcadd") == 0) {
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/groupadd sambawks >/dev/null");
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/sbin/useradd -c 'Samba Workstation' -g %s -s %s %s >/dev/null", argv[3], argv[4], argv[2]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/bin/smbpasswd -a -m %s >/dev/null", argv[2]);
safe_system(command);
} else if (strcmp(argv[1], "smbchangepw") == 0) {
snprintf(command, BUFFER_SIZE-1, "echo %s:%s | chpasswd", argv[2], argv[3]);
safe_system(command);
snprintf(command, BUFFER_SIZE-1, "/usr/bin/printf '%s\n%s\n' | /usr/bin/smbpasswd -as %s >/dev/null", argv[3], argv[3], argv[2]);
safe_system(command);
} else if (strcmp(argv[1], "readsmbpasswd") == 0) {
safe_system("/bin/chown root:nobody /var/ipfire/samba/private >/dev/null");
safe_system("/bin/chown root:nobody /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 640 /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 650 /var/ipfire/samba/private >/dev/null");
} else if (strcmp(argv[1], "locksmbpasswd") == 0) {
safe_system("/bin/chown root:root /var/ipfire/samba/private >/dev/null");
safe_system("/bin/chown root:root /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 600 /var/ipfire/samba/private/smbpasswd >/dev/null");
safe_system("/bin/chmod 600 /var/ipfire/samba/private >/dev/null");
} else if (strcmp(argv[1], "enable") == 0) {
safe_system("touch /var/ipfire/samba/enable");
safe_system("ln -snf /etc/rc.d/init.d/samba /etc/rc.d/rc3.d/S45samba");
safe_system("ln -snf /etc/rc.d/init.d/samba /etc/rc.d/rc0.d/K48samba");
safe_system("ln -snf /etc/rc.d/init.d/samba /etc/rc.d/rc6.d/K48samba");
} else if (strcmp(argv[1], "disable") == 0) {
safe_system("unlink /var/ipfire/samba/enable");
safe_system("rm -rf /etc/rc.d/rc*.d/*samba");
} else if (strcmp(argv[1], "join") == 0) {
if (argc == 4) {
snprintf(command, BUFFER_SIZE - 1, "/usr/bin/net join -U \"%s%%%s\"",
argv[2], argv[3]);
return safe_system(command);
} else {
fprintf(stderr, "Wrong number of arguments. Need username and password.\n");
return 1;
}
}
return 0;
}

View File

@@ -22,6 +22,7 @@
############################################################################
#
. /opt/pakfire/lib/functions.sh
extract_backup_includes
make_backup ${NAME}
remove_files

View File

@@ -0,0 +1,44 @@
#!/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
extract_files
restore_backup ${NAME}
# Fix permissions.
chmod 777 /srv/web/owncloud/apps
chmod 777 /srv/web/owncloud/config
# Create data directory.
mkdir -p /var/owncloud/data
chown -R nobody:nobody /var/owncloud
# Import web interface certificates if none exist.
if [ ! -e "/etc/httpd/owncloud.crt" ] && [ ! -e "/etc/httpd/owncloud.key" ]; then
cat /etc/httpd/server.crt > /etc/httpd/owncloud.crt
cat /etc/httpd/server.key > /etc/httpd/owncloud.key
fi
/etc/init.d/apache reload
exit 0

View File

@@ -0,0 +1,30 @@
#!/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
make_backup ${NAME}
remove_files
/etc/init.d/apache reload
exit 0

View File

@@ -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

View File

@@ -22,6 +22,14 @@
############################################################################
#
. /opt/pakfire/lib/functions.sh
# If the wbpriv group does not exist yet, then create it and put squid
# into it.
if ! getent group wbpriv >/dev/null; then
groupadd -g 88 wbpriv
usermod -a -G wbpriv squid
fi
extract_files
restore_backup ${NAME}
/usr/local/bin/sambactrl smbstart

View File

@@ -23,6 +23,14 @@
#
. /opt/pakfire/lib/functions.sh
./uninstall.sh
# If the wbpriv group does not exist yet, then create it and put squid
# into it.
if ! getent group wbpriv >/dev/null; then
groupadd -g 88 wbpriv
usermod -a -G wbpriv squid
fi
extract_files
restore_backup ${NAME}
echo "passdb backend = smbpasswd" >> /var/ipfire/samba/smb.conf

View File

@@ -0,0 +1,35 @@
#!/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}
#Generate SQLite DB if it does not exist
if [ ! -f /var/ipfire/accounting/acct.db ]; then
perl /var/ipfire/accounting/dbinstall.pl
chmod 644 /var/ipfire/accounting/acct.db
chown nobody.nobody /var/ipfire/accounting/acct.db
fi
rm -f /var/ipfire/accounting/dbinstall.pl
/usr/local/bin/update-lang-cache

View File

@@ -0,0 +1,27 @@
#!/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

View File

@@ -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

View File

@@ -0,0 +1,365 @@
diff --git a/Makefile b/Makefile
index 292c8bd..5e0cdbe 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
- domain.o dnssec.o blockdata.o
+ domain.o dnssec.o blockdata.o isc.o
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h
diff --git a/src/cache.c b/src/cache.c
index 5cec918..1f5657f 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -17,7 +17,7 @@
#include "dnsmasq.h"
static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
-#ifdef HAVE_DHCP
+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER)
static struct crec *dhcp_spare = NULL;
#endif
static struct crec *new_chain = NULL;
@@ -222,6 +222,9 @@ static void cache_free(struct crec *crecp)
crecp->flags &= ~F_BIGNAME;
}
+ if (crecp->flags & F_DHCP)
+ free(crecp->name.namep);
+
#ifdef HAVE_DNSSEC
cache_blockdata_free(crecp);
#endif
@@ -1110,7 +1113,7 @@ void cache_reload(void)
total_size = read_hostsfile(ah->fname, ah->index, total_size, (struct crec **)daemon->packet, revhashsz);
}
-#ifdef HAVE_DHCP
+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER)
struct in_addr a_record_from_hosts(char *name, time_t now)
{
struct crec *crecp = NULL;
@@ -1188,7 +1191,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
addrlen = sizeof(struct in6_addr);
}
#endif
-
+
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME)))
@@ -1253,7 +1256,11 @@ void cache_add_dhcp_entry(char *host_name, int prot,
else
crec->ttd = ttd;
crec->addr.addr = *host_address;
+#ifdef HAVE_ISC_READER
+ crec->name.namep = strdup(host_name);
+#else
crec->name.namep = host_name;
+#endif
crec->uid = next_uid();
cache_hash(crec);
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 1c96a0e..156ac9a 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -934,6 +934,11 @@ int main (int argc, char **argv)
poll_resolv(0, daemon->last_resolv != 0, now);
daemon->last_resolv = now;
+
+#ifdef HAVE_ISC_READER
+ if (daemon->lease_file && !daemon->dhcp)
+ load_dhcp(now);
+#endif
}
if (FD_ISSET(piperead, &rset))
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 3032546..a40b2a9 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1447,3 +1447,8 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force);
time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases);
#endif
+
+/* isc.c */
+#ifdef HAVE_ISC_READER
+void load_dhcp(time_t now);
+#endif
diff --git a/src/isc.c b/src/isc.c
new file mode 100644
index 0000000..5106442
--- /dev/null
+++ b/src/isc.c
@@ -0,0 +1,251 @@
+/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and
+ Michael Tremer
+
+ 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; version 2 dated June, 1991, or
+ (at your option) version 3 dated 29 June, 2007.
+
+ 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/>.
+
+ Code in this file is based on contributions by John Volpe and
+ Simon Kelley. Updated for recent versions of dnsmasq by
+ Michael Tremer.
+*/
+
+#include "dnsmasq.h"
+
+#ifdef HAVE_ISC_READER
+#define MAXTOK 50
+
+struct isc_dhcp_lease {
+ char* name;
+ char* fqdn;
+ time_t expires;
+ struct in_addr addr;
+ struct isc_dhcp_lease* next;
+};
+
+static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) {
+ struct isc_dhcp_lease* lease = whine_malloc(sizeof(*lease));
+
+ lease->name = strdup(hostname);
+ if (daemon->domain_suffix) {
+ asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix);
+ }
+ lease->expires = 0;
+ lease->next = NULL;
+
+ return lease;
+}
+
+static void dhcp_lease_free(struct isc_dhcp_lease* lease) {
+ if (!lease)
+ return;
+
+ if (lease->name)
+ free(lease->name);
+ if (lease->fqdn)
+ free(lease->fqdn);
+ free(lease);
+}
+
+static int next_token(char* token, int buffsize, FILE* fp) {
+ int c, count = 0;
+ char* cp = token;
+
+ while ((c = getc(fp)) != EOF) {
+ if (c == '#') {
+ do {
+ c = getc(fp);
+ } while (c != '\n' && c != EOF);
+ }
+
+ if (c == ' ' || c == '\t' || c == '\n' || c == ';') {
+ if (count)
+ break;
+ } else if ((c != '"') && (count < buffsize - 1)) {
+ *cp++ = c;
+ count++;
+ }
+ }
+
+ *cp = 0;
+ return count ? 1 : 0;
+}
+
+static long get_utc_offset() {
+ time_t t = time(NULL);
+ struct tm* time_struct = localtime(&t);
+
+ return time_struct->tm_gmtoff;
+}
+
+static time_t parse_lease_time(const char* token_date, const char* token_time) {
+ time_t time = (time_t)(-1);
+ struct tm lease_time;
+
+ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, &lease_time.tm_mon, &lease_time.tm_mday) == 3) {
+ lease_time.tm_year -= 1900;
+ lease_time.tm_mon -= 1;
+
+ if (sscanf(token_time, "%d:%d:%d", &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) {
+ time = mktime(&lease_time) + get_utc_offset();
+ }
+ }
+
+ return time;
+}
+
+static struct isc_dhcp_lease* find_lease(const char* hostname, struct isc_dhcp_lease* leases) {
+ struct isc_dhcp_lease* lease = leases;
+
+ while (lease) {
+ if (strcmp(hostname, lease->name) == 0) {
+ return lease;
+ }
+ lease = lease->next;
+ }
+
+ return NULL;
+}
+
+static off_t lease_file_size = (off_t)0;
+static ino_t lease_file_inode = (ino_t)0;
+
+void load_dhcp(time_t now) {
+ struct isc_dhcp_lease* leases = NULL;
+
+ struct stat statbuf;
+ if (stat(daemon->lease_file, &statbuf) == -1) {
+ return;
+ }
+
+ /* Do nothing if the lease file has not changed. */
+ if ((statbuf.st_size <= lease_file_size) && (statbuf.st_ino == lease_file_inode))
+ return;
+
+ lease_file_size = statbuf.st_size;
+ lease_file_inode = statbuf.st_ino;
+
+ FILE* fp = fopen(daemon->lease_file, "r");
+ if (!fp) {
+ my_syslog(LOG_ERR, _("failed to load %s:%s"), daemon->lease_file, strerror(errno));
+ return;
+ }
+
+ my_syslog(LOG_INFO, _("reading %s"), daemon->lease_file);
+
+ char* hostname = daemon->namebuff;
+ struct in_addr host_address;
+ time_t time_starts = -1;
+ time_t time_ends = -1;
+ int nomem;
+
+ char token[MAXTOK];
+ while ((next_token(token, MAXTOK, fp))) {
+ if (strcmp(token, "lease") == 0) {
+ hostname[0] = '\0';
+
+ if (next_token(token, MAXTOK, fp) && ((host_address.s_addr = inet_addr(token)) != (in_addr_t)-1)) {
+ if (next_token(token, MAXTOK, fp) && *token == '{') {
+ while (next_token(token, MAXTOK, fp) && *token != '}') {
+ if ((strcmp(token, "client-hostname") == 0) || (strcmp(token, "hostname") == 0)) {
+ if (next_token(hostname, MAXDNAME, fp)) {
+ if (!canonicalise(hostname, &nomem)) {
+ *hostname = 0;
+ my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file);
+ }
+ }
+ } else if ((strcmp(token, "starts") == 0) || (strcmp(token, "ends") == 0)) {
+ char token_date[MAXTOK];
+ char token_time[MAXTOK];
+
+ int is_starts = strcmp(token, "starts") == 0;
+
+ // Throw away the weekday and parse the date.
+ if (next_token(token, MAXTOK, fp) && next_token(token_date, MAXTOK, fp) && next_token(token_time, MAXTOK, fp)) {
+ time_t time = parse_lease_time(token_date, token_time);
+
+ if (is_starts)
+ time_starts = time;
+ else
+ time_ends = time;
+ }
+ }
+ }
+
+ if (!*hostname)
+ continue;
+
+ if ((time_starts == -1) || (time_ends == -1))
+ continue;
+
+ if (difftime(now, time_ends) > 0)
+ continue;
+
+ char* dot = strchr(hostname, '.');
+ if (dot) {
+ if (!daemon->domain_suffix || hostname_isequal(dot + 1, daemon->domain_suffix)) {
+ my_syslog(LOG_WARNING,
+ _("Ignoring DHCP lease for %s because it has an illegal domain part"),
+ hostname);
+ continue;
+ }
+ *dot = 0;
+ }
+
+ // Search for an existing lease in the list
+ // with the given host name and update the data
+ // if needed.
+ struct isc_dhcp_lease* lease = find_lease(hostname, leases);
+
+ // If no lease already exists, we create a new one
+ // and append it to the list.
+ if (!lease) {
+ lease = dhcp_lease_new(hostname);
+
+ lease->next = leases;
+ leases = lease;
+ }
+
+ // Only update more recent leases.
+ if (lease->expires > time_ends)
+ continue;
+
+ lease->addr = host_address;
+ lease->expires = time_ends;
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+
+ // Drop all entries.
+ cache_unhash_dhcp();
+
+ while (leases) {
+ struct isc_dhcp_lease *lease = leases;
+ leases = lease->next;
+
+ if (lease->fqdn) {
+ cache_add_dhcp_entry(lease->fqdn, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires);
+ }
+
+ if (lease->name) {
+ cache_add_dhcp_entry(lease->name, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires);
+ }
+
+ // Cleanup
+ dhcp_lease_free(lease);
+ }
+}
+
+#endif
diff --git a/src/option.c b/src/option.c
index daa728f..d16c982 100644
--- a/src/option.c
+++ b/src/option.c
@@ -1642,7 +1642,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err(_("bad MX target"));
break;
-#ifdef HAVE_DHCP
+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER)
case 'l': /* --dhcp-leasefile */
daemon->lease_file = opt_string_alloc(arg);
break;

View File

@@ -0,0 +1,65 @@
From cdb755c5f16a6768c3e8b1f345fe15fc9244228d Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Wed, 18 Jun 2014 20:52:53 +0100
Subject: [PATCH] Fix FTBFS with Nettle-3.0.
---
CHANGELOG | 3 +++
src/dnssec.c | 18 ++++++++++++------
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/dnssec.c b/src/dnssec.c
index 2ffb75d..69bfc29 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -28,6 +28,12 @@
#include <nettle/nettle-meta.h>
#include <nettle/bignum.h>
+/* Nettle-3.0 moved to a new API for DSA. We use a name that's defined in the new API
+ to detect Nettle-3, and invoke the backwards compatibility mode. */
+#ifdef dsa_params_init
+#include <nettle/dsa-compat.h>
+#endif
+
#define SERIAL_UNDEF -100
#define SERIAL_EQ 0
@@ -121,8 +127,8 @@ static int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char
return 1;
}
-static int rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
- unsigned char *digest, int algo)
+static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
+ unsigned char *digest, int algo)
{
unsigned char *p;
size_t exp_len;
@@ -173,8 +179,8 @@ static int rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned
return 0;
}
-static int dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
- unsigned char *digest, int algo)
+static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
+ unsigned char *digest, int algo)
{
unsigned char *p;
unsigned int t;
@@ -293,10 +299,10 @@ static int verify(struct blockdata *key_data, unsigned int key_len, unsigned cha
switch (algo)
{
case 1: case 5: case 7: case 8: case 10:
- return rsa_verify(key_data, key_len, sig, sig_len, digest, algo);
+ return dnsmasq_rsa_verify(key_data, key_len, sig, sig_len, digest, algo);
case 3: case 6:
- return dsa_verify(key_data, key_len, sig, sig_len, digest, algo);
+ return dnsmasq_dsa_verify(key_data, key_len, sig, sig_len, digest, algo);
#ifndef NO_NETTLE_ECC
case 13: case 14:
--
1.7.10.4

View File

@@ -0,0 +1,88 @@
From 063efb330a3f341c2548e2cf1f67f83e49cd6395 Mon Sep 17 00:00:00 2001
From: Simon Kelley <simon@thekelleys.org.uk>
Date: Tue, 17 Jun 2014 19:49:31 +0100
Subject: [PATCH] Build config: add -DNO_GMP for use with nettle/mini-gmp
---
Makefile | 2 +-
bld/pkg-wrapper | 9 +++++++--
src/config.h | 7 +++++++
src/dnssec.c | 3 ++-
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/Makefile b/Makefile
index c58b50b..17eeb27 100644
--- a/Makefile
+++ b/Makefile
@@ -61,7 +61,7 @@ lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CON
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.1`
nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed`
nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed`
-gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --copy -lgmp`
+gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
sunos_libs = `if uname | grep SunOS >/dev/null 2>&1; then echo -lsocket -lnsl -lposix4; fi`
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
diff --git a/bld/pkg-wrapper b/bld/pkg-wrapper
index 9f9332d..0ddb678 100755
--- a/bld/pkg-wrapper
+++ b/bld/pkg-wrapper
@@ -11,9 +11,14 @@ in=`cat`
if grep "^\#[[:space:]]*define[[:space:]]*$search" config.h >/dev/null 2>&1 || \
echo $in | grep $search >/dev/null 2>&1; then
-
+# Nasty, nasty, in --copy, arg 2 is another config to search for, use with NO_GMP
if [ $op = "--copy" ]; then
- pkg="$*"
+ if grep "^\#[[:space:]]*define[[:space:]]*$pkg" config.h >/dev/null 2>&1 || \
+ echo $in | grep $pkg >/dev/null 2>&1; then
+ pkg=""
+ else
+ pkg="$*"
+ fi
elif grep "^\#[[:space:]]*define[[:space:]]*${search}_STATIC" config.h >/dev/null 2>&1 || \
echo $in | grep ${search}_STATIC >/dev/null 2>&1; then
pkg=`$pkg --static $op $*`
diff --git a/src/config.h b/src/config.h
index 2155544..ee6d218 100644
--- a/src/config.h
+++ b/src/config.h
@@ -105,6 +105,8 @@ HAVE_AUTH
define this to include the facility to act as an authoritative DNS
server for one or more zones.
+HAVE_DNSSEC
+ include DNSSEC validator.
NO_IPV6
NO_TFTP
@@ -118,6 +120,11 @@ NO_AUTH
which are enabled by default in the distributed source tree. Building dnsmasq
with something like "make COPTS=-DNO_SCRIPT" will do the trick.
+NO_NETTLE_ECC
+ Don't include the ECDSA cypher in DNSSEC validation. Needed for older Nettle versions.
+NO_GMP
+ Don't use and link against libgmp, Useful if nettle is built with --enable-mini-gmp.
+
LEASEFILE
CONFFILE
RESOLVFILE
diff --git a/src/dnssec.c b/src/dnssec.c
index 44d626b..2ffb75d 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -26,7 +26,8 @@
# include <nettle/ecc-curve.h>
#endif
#include <nettle/nettle-meta.h>
-#include <gmp.h>
+#include <nettle/bignum.h>
+
#define SERIAL_UNDEF -100
#define SERIAL_EQ 0
--
1.7.10.4

View File

@@ -0,0 +1,245 @@
diff --git a/minilzo/minilzo.c b/minilzo/minilzo.c
index 34ce0f0..ecfdf66 100644
--- a/minilzo/minilzo.c
+++ b/minilzo/minilzo.c
@@ -3547,6 +3547,8 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
#undef TEST_LBO
#undef NEED_IP
#undef NEED_OP
+#undef TEST_IV
+#undef TEST_OV
#undef HAVE_TEST_IP
#undef HAVE_TEST_OP
#undef HAVE_NEED_IP
@@ -3561,6 +3563,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# if (LZO_TEST_OVERRUN_INPUT >= 2)
# define NEED_IP(x) \
if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun
# endif
#endif
@@ -3572,6 +3575,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# undef TEST_OP
# define NEED_OP(x) \
if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun
# endif
#endif
@@ -3602,11 +3606,13 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
+# define TEST_IV(x) ((void) 0)
#endif
#if defined(NEED_OP)
# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
+# define TEST_OV(x) ((void) 0)
#endif
#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
@@ -3687,6 +3693,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
{
t += 255;
ip++;
+ TEST_IV(t);
NEED_IP(1);
}
t += 15 + *ip++;
@@ -3835,6 +3842,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 31 + *ip++;
@@ -3879,6 +3887,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 7 + *ip++;
@@ -4073,6 +4082,8 @@ lookbehind_overrun:
#undef TEST_LBO
#undef NEED_IP
#undef NEED_OP
+#undef TEST_IV
+#undef TEST_OV
#undef HAVE_TEST_IP
#undef HAVE_TEST_OP
#undef HAVE_NEED_IP
@@ -4087,6 +4098,7 @@ lookbehind_overrun:
# if (LZO_TEST_OVERRUN_INPUT >= 2)
# define NEED_IP(x) \
if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun
# endif
#endif
@@ -4098,6 +4110,7 @@ lookbehind_overrun:
# undef TEST_OP
# define NEED_OP(x) \
if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun
# endif
#endif
@@ -4128,11 +4141,13 @@ lookbehind_overrun:
# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
+# define TEST_IV(x) ((void) 0)
#endif
#if defined(NEED_OP)
# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
+# define TEST_OV(x) ((void) 0)
#endif
#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
@@ -4213,6 +4228,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
{
t += 255;
ip++;
+ TEST_IV(t);
NEED_IP(1);
}
t += 15 + *ip++;
@@ -4361,6 +4377,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 31 + *ip++;
@@ -4405,6 +4422,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 7 + *ip++;
diff --git a/src/lzo1_d.ch b/src/lzo1_d.ch
index 40a5bfd..c442d9c 100644
--- a/src/lzo1_d.ch
+++ b/src/lzo1_d.ch
@@ -76,6 +76,8 @@
#undef TEST_LBO
#undef NEED_IP
#undef NEED_OP
+#undef TEST_IV
+#undef TEST_OV
#undef HAVE_TEST_IP
#undef HAVE_TEST_OP
#undef HAVE_NEED_IP
@@ -91,6 +93,7 @@
# if (LZO_TEST_OVERRUN_INPUT >= 2)
# define NEED_IP(x) \
if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun
# endif
#endif
@@ -102,6 +105,7 @@
# undef TEST_OP /* don't need both of the tests here */
# define NEED_OP(x) \
if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun
# endif
#endif
@@ -135,11 +139,13 @@
# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
+# define TEST_IV(x) ((void) 0)
#endif
#if defined(NEED_OP)
# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
+# define TEST_OV(x) ((void) 0)
#endif
diff --git a/src/lzo1b_d.ch b/src/lzo1b_d.ch
index fe5f361..36b4b6b 100644
--- a/src/lzo1b_d.ch
+++ b/src/lzo1b_d.ch
@@ -187,6 +187,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;
diff --git a/src/lzo1f_d.ch b/src/lzo1f_d.ch
index 9e942f5..0c2199e 100644
--- a/src/lzo1f_d.ch
+++ b/src/lzo1f_d.ch
@@ -84,6 +84,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
{
t += 255;
ip++;
+ TEST_IV(t);
NEED_IP(1);
}
t += 31 + *ip++;
@@ -138,6 +139,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 31 + *ip++;
diff --git a/src/lzo1x_d.ch b/src/lzo1x_d.ch
index 49cf326..c804cc7 100644
--- a/src/lzo1x_d.ch
+++ b/src/lzo1x_d.ch
@@ -120,6 +120,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
{
t += 255;
ip++;
+ TEST_IV(t);
NEED_IP(1);
}
t += 15 + *ip++;
@@ -273,6 +274,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 31 + *ip++;
@@ -317,6 +319,7 @@ match:
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 7 + *ip++;
diff --git a/src/lzo2a_d.ch b/src/lzo2a_d.ch
index 48e51ca..954f07e 100644
--- a/src/lzo2a_d.ch
+++ b/src/lzo2a_d.ch
@@ -131,6 +131,7 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += *ip++;

View File

@@ -0,0 +1,175 @@
Submitted By: Pierre Labastie <pierre dot labastie at eamil dot fr>
Date: 2014-03-04
Initial Package Version: 1.12.1
Upstream Status: In upstream GIT
Origin: Upstream
Description: Fixes http://krbdev.mit.edu/rt/Ticket/Display.html?id=7860
--- a/src/plugins/kdb/db2/libdb2/mpool/mpool.c
+++ b/src/plugins/kdb/db2/libdb2/mpool/mpool.c
@@ -81,9 +81,9 @@ mpool_open(key, fd, pagesize, maxcache)
/* Allocate and initialize the MPOOL cookie. */
if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
return (NULL);
- CIRCLEQ_INIT(&mp->lqh);
+ TAILQ_INIT(&mp->lqh);
for (entry = 0; entry < HASHSIZE; ++entry)
- CIRCLEQ_INIT(&mp->hqh[entry]);
+ TAILQ_INIT(&mp->hqh[entry]);
mp->maxcache = maxcache;
mp->npages = sb.st_size / pagesize;
mp->pagesize = pagesize;
@@ -143,8 +143,8 @@ mpool_new(mp, pgnoaddr, flags)
bp->flags = MPOOL_PINNED | MPOOL_INUSE;
head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
+ TAILQ_INSERT_HEAD(head, bp, hq);
+ TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
return (bp->page);
}
@@ -168,8 +168,8 @@ mpool_delete(mp, page)
/* Remove from the hash and lru queues. */
head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
+ TAILQ_REMOVE(head, bp, hq);
+ TAILQ_REMOVE(&mp->lqh, bp, q);
free(bp);
return (RET_SUCCESS);
@@ -208,10 +208,10 @@ mpool_get(mp, pgno, flags)
* of the lru chain.
*/
head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
+ TAILQ_REMOVE(head, bp, hq);
+ TAILQ_INSERT_HEAD(head, bp, hq);
+ TAILQ_REMOVE(&mp->lqh, bp, q);
+ TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
/* Return a pinned page. */
bp->flags |= MPOOL_PINNED;
@@ -261,8 +261,8 @@ mpool_get(mp, pgno, flags)
* of the lru chain.
*/
head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_INSERT_HEAD(head, bp, hq);
- CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
+ TAILQ_INSERT_HEAD(head, bp, hq);
+ TAILQ_INSERT_TAIL(&mp->lqh, bp, q);
/* Run through the user's filter. */
if (mp->pgin != NULL)
@@ -311,8 +311,8 @@ mpool_close(mp)
BKT *bp;
/* Free up any space allocated to the lru pages. */
- while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
- CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
+ while ((bp = mp->lqh.tqh_first) != NULL) {
+ TAILQ_REMOVE(&mp->lqh, mp->lqh.tqh_first, q);
free(bp);
}
@@ -332,8 +332,7 @@ mpool_sync(mp)
BKT *bp;
/* Walk the lru chain, flushing any dirty pages to disk. */
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
+ for (bp = mp->lqh.tqh_first; bp != NULL; bp = bp->q.tqe_next)
if (bp->flags & MPOOL_DIRTY &&
mpool_write(mp, bp) == RET_ERROR)
return (RET_ERROR);
@@ -363,8 +362,7 @@ mpool_bkt(mp)
* off any lists. If we don't find anything we grow the cache anyway.
* The cache never shrinks.
*/
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
+ for (bp = mp->lqh.tqh_first; bp != NULL; bp = bp->q.tqe_next)
if (!(bp->flags & MPOOL_PINNED)) {
/* Flush if dirty. */
if (bp->flags & MPOOL_DIRTY &&
@@ -375,8 +373,8 @@ mpool_bkt(mp)
#endif
/* Remove from the hash and lru queues. */
head = &mp->hqh[HASHKEY(bp->pgno)];
- CIRCLEQ_REMOVE(head, bp, hq);
- CIRCLEQ_REMOVE(&mp->lqh, bp, q);
+ TAILQ_REMOVE(head, bp, hq);
+ TAILQ_REMOVE(&mp->lqh, bp, q);
#if defined(DEBUG) && !defined(DEBUG_IDX0SPLIT)
{ void *spage;
spage = bp->page;
@@ -450,7 +448,7 @@ mpool_look(mp, pgno)
BKT *bp;
head = &mp->hqh[HASHKEY(pgno)];
- for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
+ for (bp = head->tqh_first; bp != NULL; bp = bp->hq.tqe_next)
if ((bp->pgno == pgno) && (bp->flags & MPOOL_INUSE)) {
#ifdef STATISTICS
++mp->cachehit;
@@ -494,8 +492,7 @@ mpool_stat(mp)
sep = "";
cnt = 0;
- for (bp = mp->lqh.cqh_first;
- bp != (void *)&mp->lqh; bp = bp->q.cqe_next) {
+ for (bp = mp->lqh.tqh_first; bp != NULL; bp = bp->q.tqe_next) {
(void)fprintf(stderr, "%s%d", sep, bp->pgno);
if (bp->flags & MPOOL_DIRTY)
(void)fprintf(stderr, "d");
--- a/src/plugins/kdb/db2/libdb2/mpool/mpool.h
+++ b/src/plugins/kdb/db2/libdb2/mpool/mpool.h
@@ -47,8 +47,8 @@
/* The BKT structures are the elements of the queues. */
typedef struct _bkt {
- CIRCLEQ_ENTRY(_bkt) hq; /* hash queue */
- CIRCLEQ_ENTRY(_bkt) q; /* lru queue */
+ TAILQ_ENTRY(_bkt) hq; /* hash queue */
+ TAILQ_ENTRY(_bkt) q; /* lru queue */
void *page; /* page */
db_pgno_t pgno; /* page number */
@@ -59,9 +59,9 @@ typedef struct _bkt {
} BKT;
typedef struct MPOOL {
- CIRCLEQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */
+ TAILQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */
/* hash queue array */
- CIRCLEQ_HEAD(_hqh, _bkt) hqh[HASHSIZE];
+ TAILQ_HEAD(_hqh, _bkt) hqh[HASHSIZE];
db_pgno_t curcache; /* current number of cached pages */
db_pgno_t maxcache; /* max number of cached pages */
db_pgno_t npages; /* number of pages in the file */
--- a/src/plugins/kdb/db2/libdb2/test/run.test
+++ b/src/plugins/kdb/db2/libdb2/test/run.test
@@ -71,10 +71,11 @@ main()
}
getnwords() {
- # Delete blank lines because the db code appears not to
- # like empty keys. On Debian Linux, $DICT appears to contain
- # some non-ASCII characters, and "rev" chokes on them.
- sed -e '/^$/d' < $DICT | cat -v | sed -e ${1}q
+ # Delete blank lines because the db code appears not to like
+ # empty keys. Omit lines with non-alphanumeric characters to
+ # avoid shell metacharacters and non-ASCII characters which
+ # could cause 'rev' to choke.
+ LC_ALL=C sed -e '/^$/d' -e '/[^A-Za-z]/d' < $DICT | sed -e ${1}q
}
# Take the first hundred entries in the dictionary, and make them

View File

@@ -1,863 +0,0 @@
#!/usr/bin/perl
#
# SmoothWall CGIs
#
# This code is distributed under the terms of the GPL
#
# (c) The SmoothWall Team
#
# $Id: setddns.pl,v 1.4.2.32 2006/02/07 01:29:47 franck78 Exp $
#
#close(STDIN);
#close(STDOUT);
#close(STDERR);
use strict;
use IO::Socket;
use Net::SSLeay;
require '/var/ipfire/general-functions.pl';
#Prototypes functions
sub encode_base64 ($;$);
my %settings;
my $filename = "${General::swroot}/ddns/config";
my $cachefile = "${General::swroot}/ddns/ipcache";
my $ipcache = 0;
my @current = ();
if (open(FILE, "$filename")) {
@current = <FILE>;
close(FILE);
unless(@current) {
exit 0;
}
} else {
&General::log('Dynamic DNS failure : unable to open config file.');
exit 0;
}
&General::readhash("${General::swroot}/ddns/settings", \%settings);
# ignore monthly update if not in minimize update mode
exit 0 if (($settings{'MINIMIZEUPDATES'} ne 'on') && ($ARGV[1] eq '-m'));
my $ip = &General::GetDyndnsRedIP();
if ($ip eq "unavailable") {
&General::log("Dynamic DNS error: RED/Public IP is unavailable");
exit(0);
}
#&General::log("Dynamic DNS public router IP is: $ip");
if ($ARGV[0] eq '-f') {
unlink ($cachefile); # next regular calls will try again if this force update fails.
} else {
open(IPCACHE, "$cachefile");
$ipcache = <IPCACHE>;
close(IPCACHE);
chomp $ipcache;
}
if ($ip ne $ipcache) {
my $id = 0;
my $success = 0;
my $line;
my $lines = @current;
foreach $line (@current) {
$id++;
chomp($line);
my @temp = split(/\,/,$line);
unless ($temp[7] ne "on") {
$settings{'SERVICE'} = $temp[0];
$settings{'HOSTNAME'} = $temp[1];
$settings{'DOMAIN'} = $temp[2];
$settings{'PROXY'} = $temp[3];
$settings{'WILDCARDS'} = $temp[4];
$settings{'LOGIN'} = $temp[5];
$settings{'PASSWORD'} = $temp[6];
$settings{'ENABLED'} = $temp[7];
#Some connection are very stable (more than 40 days). Finally force
#one update / month to avoid account lost
#cron call once/week with -f & once/month with -f -m options
#minimize update ?
if ( ($settings{'MINIMIZEUPDATES'} eq 'on') && ($ARGV[1] ne '-m') ) {
if (General::DyndnsServiceSync($ip, $settings{'HOSTNAME'},$settings{'DOMAIN'})) {
&General::log ("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} is uptodate [$ip]");
$success++;
next; # do not update, go to test next service
}
}
if ($settings{'SERVICE'} ne "dns.lightningwirelabs.com") {
my @service = split(/\./, "$settings{'SERVICE'}");
$settings{'SERVICE'} = "$service[0]";
}
if ($settings{'SERVICE'} eq 'no-ip') {
open(F, ">${General::swroot}/ddns/noipsettings");
flock F, 2;
print F "PROXY=" . ($settings{'PROXY'} eq 'on' ? "Y\n" : "N\n");
print F "PASSWORD=$settings{'PASSWORD'}\n";
print F "NAT=N\n";
print F "LOGIN=$settings{'LOGIN'}\n";
print F "INTERVAL=1\n";
if ($settings{'HOSTNAME'} !~ s/$General::noipprefix//) {
print F "HOSTNAME=$settings{'HOSTNAME'}\n";
print F "GROUP=\n";
} else {
print F "HOSTNAME=\n";
print F "GROUP=$settings{'HOSTNAME'}\n";
}
print F "DOMAIN=$settings{'DOMAIN'}\n";
print F "DEVICE=\n";
print F "DAEMON=N\n";
close(F);
my @ddnscommand = ('/usr/bin/noip','-c',"${General::swroot}/ddns/noipsettings",'-i',"$ip");
my $result = system(@ddnscommand);
if ( $result != 0) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
}
}
elsif ($settings{'SERVICE'} eq 'all-inkl') {
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
my ($out, $response) = Net::SSLeay::get_https("dyndns.kasserver.com", 443, "/", Net::SSLeay::make_headers(
'User-Agent' => 'IPFire', 'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")
));
# Valid response are 'ok' 'nochange'
if ($response =~ m%HTTP/1\.. 200 OK%) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server, check your credentials)");
}
}
elsif ($settings{'SERVICE'} eq 'cjb') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
my ($out, $response) = Net::SSLeay::get_http( 'www.cjb.net',
80,
"/cgi-bin/dynip.cgi?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&ip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/has been updated to point to/ ) {
&General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (bad password or login)");
} else {
&General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for cjb.net ($settings{'LOGIN'}) : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'selfhost') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
my ($out, $response) = Net::SSLeay::get_https( 'carol.selfhost.de',
443,
"/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&textmodi=1",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/status=(200|204)/ ) {
$out =~ s/\n/ /g;
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'dnspark') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_https( "www.dnspark.net",
443,
"/api/dynamic/update.php?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire',
'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")
)
);
# Valid response are 'ok' 'nochange'
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/^(ok|nochange)/ ) {
$out =~ s/\n/ /g;
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");
}
}
elsif ($settings{'SERVICE'} eq 'dns.lightningwirelabs.com') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my $authstring;
if ($settings{'LOGIN'} eq "token") {
$authstring = "token=$settings{'PASSWORD'}";
} else {
$authstring = "username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}";
}
my $user_agent = &General::MakeUserAgent();
my ($out, $response) = Net::SSLeay::get_https("dns.lightningwirelabs.com", 443,
"/update?hostname=$settings{'HOSTDOMAIN'}&address4=$ip&$authstring",
Net::SSLeay::make_headers('User-Agent' => $user_agent)
);
# Valid response are 'ok' 'nochange'
if ($response =~ m%HTTP/1\.. 200 OK%) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials)");
}
}
elsif ($settings{'SERVICE'} eq 'enom') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_http( 'dynamic.name-services.com',
80,
"/interface.asp?Command=SetDNSHost&Zone=$settings{'DOMAIN'}&DomainPassword=$settings{'PASSWORD'}&Address=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
if ($response =~ m%HTTP/1\.. 200 OK%) {
#Valid responses from update => ErrCount=0
if ( $out !~ m/ErrCount=0/ ) {
$out =~ s/(\n|\x0D)/ /g;
$out =~ /Err1=([\w ]+) /;
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'nsupdate') {
# Fetch UI configurable values and assemble the host name.
my $hostName="$settings{'DOMAIN'}";
if ($settings{'HOSTNAME'} ne "") {
$hostName="$settings{'HOSTNAME'}.$hostName";
}
my $keyName=$settings{'LOGIN'};
my $keySecret=$settings{'PASSWORD'};
# Use a relatively long TTL value to reduce load on DNS.
# Some public Dynamic DNS servers use values around 4 hours,
# some use values as low as 60 seconds.
# XXX Maybe we could fetch the master value from the server
# (not the timed-down version supplied by DNS cache)
my $timeToLive="3600";
# Internal setting that can be used to override the DNS server
# where the update is applied. It can be of use when testing
# against a private DNS server.
my $masterServer="";
# Prepare the nsupdate command script to remove and re-add the
# updated A record for the domain.
my $cmdFile="/tmp/nsupdate-$hostName-commands";
my $logFile="/tmp/nsupdate-$hostName-result";
open(TF, ">$cmdFile");
if ($masterServer ne "") {
print TF "server $masterServer\n";
}
if ($keyName ne "" && $keySecret ne "") {
print TF "key $keyName $keySecret\n";
}
print TF "update delete $hostName A\n";
print TF "update add $hostName $timeToLive A $ip\n";
print TF "send\n";
close(TF);
# Run nsupdate with -v to use TCP instead of UDP because we're
# issuing multiple cmds and potentially long keys, and -d to
# get diagnostic result output.
my $result = system("/usr/bin/nsupdate -v -d $cmdFile 2>$logFile");
if ($result != 0) {
&General::log("Dynamic DNS ip-update for $hostName : failure");
open(NSLOG, "$logFile");
my @nsLog = <NSLOG>;
close(NSLOG);
my $logLine;
foreach $logLine (@nsLog) {
chomp($logLine);
if ($logLine ne "") {
&General::log("... $logLine");
}
}
} else {
&General::log("Dynamic DNS ip-update for $hostName : success");
$success++;
}
unlink $cmdFile, $logFile;
}
elsif ($settings{'SERVICE'} eq 'freedns') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
my ($out, $response) = Net::SSLeay::get_https( 'freedns.afraid.org',
443,
"/dynamic/update.php?$settings{'LOGIN'}",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
#Valid responses from service are:
#Updated n host(s) <domain>
#ERROR: <ip> has not changed.
if ($response =~ m%HTTP/1\.. 200 OK%) {
#Valid responses from update => ErrCount=0
if ( $out !~ m/(^Updated|Address .* has not changed)/ig ) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'spdns.de') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_https( 'update.spdns.de', 443,
"/nic/update?&hostname=$settings{'HOSTDOMAIN'}&myip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' ,
'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"))
);
#Valid responses from service are:
# good xxx.xxx.xxx.xxx
# nochg xxx.xxx.xxx.xxx
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ($out !~ m/good |nochg /ig) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'strato') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_https( 'dyndns.strato.com',
443,
"/nic/update?hostname=$settings{'HOSTDOMAIN'}&myip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire',
'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}") )
);
if ($response =~ m%HTTP/1\.. 200 OK%) {
#Valid responses from update => ErrCount=0
if ( $out =~ m/good |nochg /ig) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure1 ($out)");
$success++;
}
} elsif ( $out =~ m/<title>(.*)<\/title>/ig ) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure2 ($1)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure3 ($response)");
}
}
elsif ($settings{'SERVICE'} eq 'regfish') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
my ($out, $response) = Net::SSLeay::get_https( 'dyndns.regfish.de',
443,
"/?fqdn=$settings{'DOMAIN'}&ipv4=$ip&forcehost=1&authtype=secure&token=$settings{'LOGIN'}",
Net::SSLeay::make_headers('User-Agent' => 'Ipfire' )
);
#Valid responses from service are:
#success|100|update succeeded!
#success|101|no update needed at this time..
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/(success\|(100|101)\|)/ig ) {
&General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'ovh') {
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
my $peer = 'www.ovh.com';
my $peerport = 80;
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
}
my $sock;
unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
&General::log("Dynamic DNS failure : could not connect to $peer:$peerport: $@");
next;
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($GET_CMD, $code64);
$GET_CMD = "GET http://www.ovh.com/nic/update?system=dyndns&hostname=$settings{'HOSTDOMAIN'}&myip=$ip HTTP/1.1\r\n";
$GET_CMD .= "Host: www.ovh.com\r\n";
chomp($code64 = encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}"));
$GET_CMD .= "Authorization: Basic $code64\r\n";
$GET_CMD .= "User-Agent: ipfire\r\n";
#$GET_CMD .= "Content-Type: application/x-www-form-urlencoded\r\n";
$GET_CMD .= "\r\n";
print $sock "$GET_CMD";
my $out = '';
while(<$sock>) {
$out .= $_;
}
close($sock);
#HTTP response => error (in Title tag) else text response
#Valid responses from service:good,nochg (ez-ipupdate like)
#Should use ez-ipdate but "system=dyndns" is not present
if ( $out =~ m/<Title>(.*)<\/Title>/ig ) {
&General::log("Dynamic DNS ovh.com : failure ($1)");
}
elsif ($out !~ m/good |nochg /ig) {
$out =~ s/.+?\015?\012\015?\012//s; # header HTTP
my @out = split("\r", $out);
&General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : failure ($out[1])");
} else {
&General::log("Dynamic DNS ip-update for $settings{'DOMAIN'} : success");
$success++;
}
}
elsif ($settings{'SERVICE'} eq 'dtdns') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_http( 'www.dtdns.com',
80,
"/api/autodns.cfm?id=$settings{'HOSTDOMAIN'}&pw=$settings{'PASSWORD'}",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
#Valid responses from service are:
# now points to
#
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/Host .* now points to/ig ) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
}
}
#namecheap test
elsif ($settings{'SERVICE'} eq 'namecheap') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
my ($out, $response) = Net::SSLeay::get_https( 'dynamicdns.park-your-domain.com',
443,
"/update?host=$settings{'HOSTNAME'}&domain=$settings{'DOMAIN'}&password=$settings{'PASSWORD'}&ip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
#Valid responses from service are:
# wait confirmation!!
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/<ErrCount>0<\/ErrCount>/ ) {
$out =~ m/<Err1>(.*)<\/Err1>/;
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($1)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure (could not connect to server)");
}
}
#end namecheap test
elsif ($settings{'SERVICE'} eq 'dynu') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_http( 'dynserv.ca',
80,
"/dyn/dynengine.cgi?func=set&name=$settings{'LOGIN'}&pass=$settings{'PASSWORD'}&ip=$ip&domain=$settings{'DOMAIN'}",
Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
);
#Valid responses from service are:
# 02 == Domain already exists, refreshing data for ... => xxx.xxx.xxx.xxx
#
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/Domain already exists, refreshing data for/ig ) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server)");
}
}
elsif ($settings{'SERVICE'} eq 'udmedia') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_https( 'www.udmedia.de',
443,
"/nic/update?myip=$ip&username=$settings{'HOSTDOMAIN'}&password=$settings{'PASSWORD'}",
Net::SSLeay::make_headers('User-Agent' => 'IPFire',
'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")) );
# Valid response are 'ok' 'nochange'
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/^(ok|nochg)/ ) {
$out =~ s/\n/ /g;
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials---$out-$response--)");
}
}
elsif ($settings{'SERVICE'} eq 'twodns') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_https( 'update.twodns.de',
443,
"/update?hostname=$settings{'HOSTDOMAIN'}&ip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire',
'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")) );
# Valid response are 'ok' 'nochange'
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/^(good|nochg)/ ) {
$out =~ s/\n/ /g;
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials---$out-$response--)");
}
}
elsif ($settings{'SERVICE'} eq 'variomedia') {
# use proxy ?
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
}
if ($settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my ($out, $response) = Net::SSLeay::get_https( 'dyndns.variomedia.de',
443,
"/nic/update?hostname=$settings{'HOSTDOMAIN'}&myip=$ip",
Net::SSLeay::make_headers('User-Agent' => 'IPFire',
'Authorization' => 'Basic ' . encode_base64("$settings{'LOGIN'}:$settings{'PASSWORD'}")) );
# Valid response is 'good $ip'
if ($response =~ m%HTTP/1\.. 200 OK%) {
if ( $out !~ m/^good $ip/ ) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} ($ip) : failure ($out)");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} ($ip) : success");
$success++;
}
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'} : failure (could not connect to server, check your credentials---$out-$response--)");
}
}
else {
if ($settings{'WILDCARDS'} eq 'on') {
$settings{'WILDCARDS'} = '-w';
} else {
$settings{'WILDCARDS'} = '';
}
if (($settings{'SERVICE'} eq 'dyndns-custom' ||
$settings{'SERVICE'} eq 'easydns' ||
$settings{'SERVICE'} eq 'zoneedit') && $settings{'HOSTNAME'} eq '') {
$settings{'HOSTDOMAIN'} = $settings{'DOMAIN'};
} else {
$settings{'HOSTDOMAIN'} = "$settings{'HOSTNAME'}.$settings{'DOMAIN'}";
}
my @ddnscommand = ('/usr/bin/ez-ipupdate', '-a', "$ip", '-S', "$settings{'SERVICE'}", '-u', "$settings{'LOGIN'}:$settings{'PASSWORD'}", '-h', "$settings{'HOSTDOMAIN'}", "$settings{'WILDCARDS'}", '-q');
my $result = system(@ddnscommand);
if ( $result != 0) {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: failure");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTDOMAIN'}: success");
$success++;
}
}
} else {
# If a line is disabled, then we should discount it
$lines--;
}
}
if ($lines == $success) {
open(IPCACHE, ">$cachefile");
flock IPCACHE, 2;
print IPCACHE $ip;
close(IPCACHE);
exit 1;
}
}
exit 0;
# Extracted from Base64.pm
sub encode_base64 ($;$) {
my $res = "";
my $eol = $_[1];
$eol = "\n" unless defined $eol;
pos($_[0]) = 0; # ensure start at the beginning
while ($_[0] =~ /(.{1,45})/gs) {
$res .= substr(pack('u', $1), 1);
chop($res);
}
$res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
# fix padding at the end
my $padding = (3 - length($_[0]) % 3) % 3;
$res =~ s/.{$padding}$/'=' x $padding/e if $padding;
# break encoded string into lines of no more than 76 characters each
if (length $eol) {
$res =~ s/(.{1,76})/$1$eol/g;
}
$res;
}
__END__
old code for selfhost.de
my %proxysettings;
&General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
my $peer = 'carol.selfhost.de';
my $peerport = 80;
if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
}
my $sock;
unless($sock = new IO::Socket::INET (PeerAddr => $peer, PeerPort => $peerport, Proto => 'tcp', Timeout => 5)) {
die "Could not connect to $peer:$peerport: $@";
return 1;
}
my $GET_CMD;
$GET_CMD = "GET https://carol.selfhost.de/update?username=$settings{'LOGIN'}&password=$settings{'PASSWORD'}&myip=$ip&textmodi=1 HTTP/1.1\r\n";
$GET_CMD .= "Host: carol.selfhost.de\r\n";
$GET_CMD .= "User-Agent: ipfire\r\n";
$GET_CMD .= "Connection: close\r\n\r\n";
print $sock "$GET_CMD";
my $out = '';
while(<$sock>) {
$out .= $_;
}
close($sock);
if ( $out !~ m/status=(200|204)/ ) {
#cleanup http response...
$out =~ s/.+?\015?\012\015?\012//s; # header HTTP
my @out = split("\r", $out);
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : failure ($out[1])");
} else {
&General::log("Dynamic DNS ip-update for $settings{'HOSTNAME'}.$settings{'DOMAIN'} : success");
$success++;
}

View File

@@ -0,0 +1,5 @@
$sublogs->{'32.proxy'} = {'caption' => $Lang::tr{'acct menu'},
'uri' => '/cgi-bin/accounting.cgi',
'title' => $Lang::tr{'acct menu'},
'enabled' => 1,
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,923 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2014 IPFire Team <alexander.marx@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/>. #
# #
###############################################################################
package ACCT;
use DBI;
use POSIX;
use Time::Local;
use PDF::API2;
use utf8;
use Encode;
use File::Copy;
use File::Temp qw/ tempfile tempdir /;
###############################################################################
my $dbh;
my $dsn="dbi:SQLite:dbname=/var/ipfire/accounting/acct.db";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst)=localtime();
my %mainsettings;
###############################################################################
&General::readhash("/var/ipfire/main/settings", \%mainsettings);
my $uplang=uc($mainsettings{'LANGUAGE'});
#############
# Functions #
#############
sub connectdb {
$dbh = DBI->connect($dsn, "", "",{RaiseError => 1, AutoCommit => 1})or die "ERROR $!";
return $dbh;
}
sub closedb {
$dbh->disconnect();
return $dbh;
}
sub getminmax {
my $min;
my $max;
$dbh=&connectdb;
my $sth = $dbh->prepare('Select min(TIME_RUN),max(TIME_RUN) from ACCT;');
$sth->execute;
while ( my @row = $sth->fetchrow_array ) {
$min=$row[0];
$max=$row[1];
}
$dbh->disconnect();
return ($min,$max);
}
sub cleardbtraf {
&connectdb;
$dbh->do("DELETE FROM ACCT;");
$dbh->do("DELETE FROM ACCT_HIST;");
&closedb;
}
sub cleardb {
&connectdb;
$dbh->do("DELETE FROM ACCT;");
$dbh->do("DELETE FROM ACCT_HIST;");
$dbh->do("DELETE FROM ACCT_ADDR ");
$dbh->do("DELETE FROM BILLINGGRP");
$dbh->do("DELETE FROM BILLINGHOST");
&closedb;
}
sub delbefore {
my $till=$_[0];
&connectdb;
$dbh->do("DELETE FROM ACCT WHERE TIME_RUN < ".$till.";");
$dbh->do("DELETE FROM ACCT_HIST WHERE TIME_RUN < date('".$till."','unixepoch');");
&closedb;
}
sub movedbdata {
$dbh->do("insert into ACCT_HIST select datetime(TIME_RUN,'unixepoch'),NAME,SUM(BYTES) from ACCT where date(TIME_RUN,'unixepoch') < date('now','-2 months') group by NAME,date(TIME_RUN,'unixepoch');");
$dbh->do("DELETE FROM ACCT WHERE datetime(TIME_RUN,'unixepoch') < date('now','-2 months');");
}
sub gethourgraphdata {
my $table=$_[0];
my $from=$_[1];
my $till=$_[2];
my $name=$_[3];
my $res;
$dbh=connectdb;
if ($table eq 'ACCT'){
$res = $dbh->selectall_arrayref( "SELECT TIME_RUN,BYTES FROM ACCT WHERE TIME_RUN BETWEEN ".$from." AND ".$till." AND NAME = '".$name."';");
}else{
$res = $dbh->selectall_arrayref( "SELECT TIME_RUN,BYTES FROM ACCT_HIST WHERE TIME_RUN BETWEEN date(".$from.",'unixepoch') AND date(".$till.",'unixepoch') AND NAME = '".$name."';");
}
return $res;
}
sub getmonthgraphdata {
my $table=$_[0];
my $from=$_[1];
my $till=$_[2];
my $name=$_[3];
my $res;
$dbh=connectdb;
if ($table eq 'ACCT'){
$res = $dbh->selectall_arrayref( "SELECT strftime('%d.%m.%Y',xx.tag),(SELECT SUM(BYTES)/1024/1024 FROM ACCT WHERE date(TIME_RUN,'unixepoch') <= xx.tag and NAME = '".$name."') kum_bytes FROM (SELECT date(TIME_RUN,'unixepoch') tag,SUM(BYTES)/1024/1024 sbytes FROM ACCT WHERE NAME='".$name."' and TIME_RUN between ".$from." and ".$till." GROUP by date(TIME_RUN,'unixepoch')) xx;");
}else{
$res = $dbh->selectall_arrayref( "SELECT TIME_RUN, (SELECT SUM(BYTES)/1024/1024 FROM ACCT_HIST WHERE TIME_RUN <= ah.TIME_RUN and NAME = '".$name."') kum_bytes FROM ACCT_HIST ah WHERE TIME_RUN BETWEEN date(".$from.",'unixepoch') AND date(".$till.",'unixepoch') AND NAME = '".$name."' group by TIME_RUN;");
}
$dbh=closedb;
return $res;
}
sub writeaddr {
my $comp = $_[0];
my $type = $_[1];
my $name1 = $_[2];
my $str = $_[3];
my $nr = $_[4];
my $post = $_[5];
my $city = $_[6];
my $bank = $_[7];
my $iban = $_[8];
my $bic = $_[9];
my $blz = $_[10];
my $kto = $_[11];
my $mail = $_[12];
my $inet = $_[13];
my $hrb = $_[14];
my $ustid = $_[15];
my $tel = $_[16];
my $fax = $_[17];
$dbh=&connectdb;
#COMPANY,TYPE,NAME1,STR,NR,POSTCODE,CITY,BANK,IBAN,BLZ,ACCOUNT,EMAIL,INTERNET,HRB,USTID,TEL,FAX
my $sql = "INSERT INTO ACCT_ADDR (COMPANY,TYPE,NAME1,STR,NR,POSTCODE,CITY,BANK,IBAN,BIC,BLZ,ACCOUNT,EMAIL,INTERNET,HRB,USTID,TEL,FAX) VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
my $sth = $dbh->prepare( $sql );
$sth->execute( $comp,$type,$name1,$str,$nr,$post,$city,$bank,$iban,$bic,$blz,$kto,$mail,$inet,$hrb,$ustid,$tel,$fax );
$dbh=&closedb;
}
sub updateaddr {
my $type = $_[0];
my $comp = $_[1];
my $name1 = $_[2];
my $str = $_[3];
my $nr = $_[4];
my $post = $_[5];
my $city = $_[6];
my $bank = $_[7];
my $iban = $_[8];
my $bic = $_[9];
my $blz = $_[10];
my $kto = $_[11];
my $mail = $_[12];
my $inet = $_[13];
my $hrb = $_[14];
my $ustid = $_[15];
my $tel = $_[16];
my $fax = $_[17];
my $oldname = $_[18];
$dbh=&connectdb;
$dbh->do("UPDATE ACCT_ADDR SET COMPANY=?,TYPE=?,NAME1=?,STR=?,NR=?,POSTCODE=?,CITY=?,BANK=?,IBAN=?,BIC=?,BLZ=?,ACCOUNT=?,EMAIL=?,INTERNET=?,HRB=?,USTID=?,TEL=?,FAX=? WHERE COMPANY=?", undef,$comp,$type,$name1,$str,$nr,$post,$city,$bank,$iban,$bic,$blz,$kto,$mail,$inet,$hrb,$ustid,$tel,$fax,$oldname)or die "Could not UPDATE Address.";
$dbh=&closedb;
}
sub deladdr {
my $comp = $_[0];
$dbh=&connectdb;
$dbh->do("DELETE FROM ACCT_ADDR WHERE COMPANY=?", undef,$comp )or die "Could not delete address $comp!";
$dbh=&closedb;
}
sub getaddresses {
$dbh=&connectdb;
my $res=$dbh->selectall_arrayref("SELECT (SELECT COUNT(NAME) FROM BILLINGGRP GROUP BY NAME),* FROM ACCT_ADDR ORDER BY COMPANY;");
$dbh=&closedb;
return $res;
}
sub gethosts{
$dbh=&connectdb;
my $res =$dbh->selectall_arrayref("SELECT NAME from ACCT GROUP BY NAME ORDER BY NAME;");
$dbh=&closedb;
return $res;
}
sub getbillgroups {
$dbh=connectdb;
my $res=$dbh->selectall_arrayref("SELECT NAME,HOST,CUST,BILLTEXT,(SELECT COUNT(HOST) FROM BILLINGHOST WHERE BILLINGGRP.NAME=BILLINGHOST.GRP),CENT FROM BILLINGGRP ORDER BY NAME;");
return $res;
$dbh->disconnect();
}
sub getextrabillpos {
my $grp=$_[0];
$dbh=&connectdb;
my $res=$dbh->selectall_arrayref("SELECT * from BILLPOS WHERE GRP =?", undef,$grp);
$dbh=&closedb;
return $res;
}
sub savebillgroup {
my $grp=$_[0];
my $txt=$_[1];
my $host=$_[2];
my $cust=$_[3];
my $ust=$_[4];
my @ips=@{$_[5]};
$dbh=&connectdb;
my $sql = "INSERT INTO BILLINGGRP (NAME,BILLTEXT,HOST,CUST,CENT) VALUES (?,?,?,?,?)";
my $sth = $dbh->prepare( $sql );
$sth->execute( $grp,$txt,$host,$cust,$ust );
foreach my $ip (@ips){
my $sql = "INSERT INTO BILLINGHOST (GRP,HOST) VALUES (?,?)";
my $sth = $dbh->prepare( $sql ) or die "Could not prepare insert into BILLINGHOST $!";
$sth->execute( $grp,$ip ) or die "Could not execute INSERT into BILLINGHOST $!";
}
$dbh=&closedb;
}
sub updatebillgrouphost {
my $oldgrp=$_[0];
my $newgrp=$_[1];
$dbh=&connectdb;
my $sql = "UPDATE BILLINGGRP SET HOST=? WHERE HOST=?;";
my $sth = $dbh->prepare( $sql );
$sth->execute( $newgrp,$oldgrp );
$dbh=&closedb;
}
sub updatebillgroupcust {
my $oldgrp=$_[0];
my $newgrp=$_[1];
$dbh=&connectdb;
my $sql = "UPDATE BILLINGGRP SET CUST=? WHERE CUST=?;";
my $sth = $dbh->prepare( $sql );
$sth->execute( $newgrp,$oldgrp );
$dbh=&closedb;
}
sub deletebillgroup {
my $name=shift;
$dbh=connectdb;
$dbh->do("DELETE FROM BILLINGGRP WHERE NAME=?;", undef,$name);
$dbh->do("DELETE FROM BILLINGHOST WHERE GRP=?;", undef,$name);
&closedb;
}
sub savebillpos {
my $grp=$_[0];
my $amnt=$_[1];
my $pos=$_[2];
my $price=$_[3];
$dbh=&connectdb;
my $sql = "INSERT INTO BILLPOS (GRP,AMOUNT,POS,PRICE) VALUES (?,?,?,?)";
my $sth = $dbh->prepare( $sql )or die "Could not prepare insert into BILLINGPOS $!";
$sth->execute( $grp,$amnt,$pos,$price ) or die "Could not execute INSERT into BILLINGHOST $!";
$dbh->disconnect();
}
sub updatebillpos {
my $oldgrp=shift;
my $newgrp=shift;
$dbh=&connectdb;
my $sql = "UPDATE BILLPOS SET GRP=? WHERE GRP=?;";
my $sth = $dbh->prepare( $sql );
$sth->execute( $newgrp,$oldgrp );
my $sql1 = "UPDATE BILLS SET GRP=? WHERE GRP=?;";
my $sth1 = $dbh->prepare( $sql1 );
$sth1->execute( $newgrp,$oldgrp );
$dbh=&closedb;
#Now rename directories
rename ("/srv/web/ipfire/html/accounting/logo/$oldgrp","/srv/web/ipfire/html/accounting/logo/$newgrp");
rename ("/var/ipfire/accounting/bill/$oldgrp","/var/ipfire/accounting/bill/$newgrp")
}
sub delbillpos_single {
my $pos=$_[0];
my $grp=$_[1];
my $sql = "DELETE FROM BILLPOS WHERE GRP=? AND POS=?;";
$dbh=&connectdb;
my $sth = $dbh->prepare( $sql )or die "Could not prepare DELETE POS from BILLINGPOS $!";
$sth->execute( $grp,$pos ) or die "Could not execute DELETE from BILLINGHOST $!";
$dbh=&closedb;
}
sub delbillpos {
my $grp=$_[0];
my $sql = "DELETE FROM BILLPOS WHERE GRP=?;";
$dbh=&connectdb;
my $sth = $dbh->prepare( $sql )or die "Could not prepare DELETE POS from BILLINGPOS $!";
$sth->execute( $grp ) or die "Could not execute DELETE from BILLINGHOST $!";
$dbh=&closedb;
}
sub listhosts{
my $name=$_[0];
my $a;
my $res=$dbh->selectall_arrayref("SELECT * FROM BILLINGHOST WHERE GRP='".$name."';");
foreach my $gzu (@$res){
my ($x,$y)=@$gzu;
$a.= "|$y";
}
return $a;
}
sub checkusergrp {
$dbh=connectdb;
my $res=$dbh->selectall_arrayref("SELECT * FROM BILLINGHOST;");
$dbh->disconnect();
return $res;
}
sub getmonth{
#GET : 1. month 2. year
#GIVES: 1.day of given month AND last day of given month in seconds since 1.1.1970
($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst)=localtime();
my $jahr=$_[1];
my $monat=$_[0]-1 if($_[0]);
my $tag=1;
my $time1=timelocal(0,0,0,$tag,$monat,$jahr);
my $time2=timelocal(0,0,0,$tag,($monat+1),$jahr);
--$time2;
return ($time1,$time2);
}
sub GetTaValues {
$dbh=&connectdb;
my $from = $_[0]; #unixtimestamp
my $till = $_[1]; #unixtimestamp
my $grp = $_[2]; #Billgroupname
my $all = $dbh->selectall_arrayref("SELECT bh.HOST,SUM(ac.BYTES) sbytes,bh.GRP FROM ACCT ac ,BILLINGHOST bh WHERE ac.NAME=bh.HOST AND bh.GRP=? AND ac.TIME_RUN between ? AND ? GROUP BY bh.GRP,bh.HOST;", undef, $grp, $from, $till) or die "Could not fetch Groupdata $!";
my $nri1 = @$all;
my @return;
my $cnt=0;
if ($nri1 eq "0"){
$return[$cnt]="999";
}
else
{
foreach my $row (@$all){
my ($bytes,$billgrp,$host) = @$row;
$return[$cnt]="$bytes,$billgrp,$host";
$cnt++;
}
}
&closedb;
return @return;
}
sub getTaAddress {
my $grp=$_[0];
my $type=$_[1];
$dbh=&connectdb;
my $res = $dbh->selectall_arrayref("select * from ACCT_ADDR,BILLINGGRP where (BILLINGGRP.HOST=ACCT_ADDR.COMPANY AND BILLINGGRP.NAME=? AND ACCT_ADDR.TYPE=?) or (BILLINGGRP.CUST=ACCT_ADDR.COMPANY and BILLINGGRP.NAME=? AND ACCT_ADDR.TYPE=?);", undef, $grp,$type,$grp,$type);
&closedb;
return $res;
}
sub checkbillgrp {
my $comp=$_[0];
$dbh=&connectdb;
my $res=$dbh->selectall_arrayref("SELECT NAME,HOST,CUST FROM BILLINGGRP;");
&closedb;
return $res;
}
sub pdf2 {
my @billar = @{$_[0]}; #DATA from sendbill (just host/values)
my $month = $_[1];
$month = '0'.$month if $month < 10;
my $year = $_[2];
my $mwst = $_[3];
my @address_cust= @{$_[4]}; #Array which contains customer and hoster adresses and some additional info from billgroup
my @address_host= @{$_[5]};
my @billpos = @{$_[6]};
my $grp = $_[7];
my $cur = $_[8]; #(Eur,USD,...)
my $preview = $_[9];
my $no = &getBillNr;
my $name = $month."-".$year."-".$no.".pdf";
my $path ="/var/ipfire/accounting/bill/";
my $filename = "$path/$grp/$name";
my @summen; #Used for counting the sums
my $x = 500;
my $y = 1;
my $zwsum;
my $pages = 0;
my $anzbillpos = @billpos;
my $anz = (@billar+$anzbillpos)/18; #Total pages
$anz = ceil($anz); #round the $anz value
my $aktpage=1;
my $sum=0;
my $sum1=0;
my $lines;
my $title;
my $txt;
my $txt1;
my $txt2;
my $txt3;
my $txt4;
my $txt5;
my $fnt;
my $fnt1;
my $fulldate = strftime('%d.%m.%Y',localtime(time()));
my($company_host,$type_host,$name1_host,$str_host,$str_nr_host,$plz_host,$city_host,$bank,$iban,$bic,$blz,$kto,$email,$internet,$hrb,$stnr,$tel_host,$fax_host,$ccmail,$billgrp,$text,$host,$cust,$cent);
my($company_cust,$type_cust,$name1_cust,$str_cust,$str_nr_cust,$plz_cust,$city_cust);
#First of all check if directory exists, else create it
if(! -d "$path/$grp" && $preview ne 'on'){
mkdir("$path/$grp",0777);
}
#Check if we are creating a preview or a real bill
if($preview eq 'on'){
$filename="$path/".tempfile( SUFFIX => ".pdf", );
}
####################################################################
#Prepare DATA from arrays
####################################################################
#Get HOSTER for this grp
foreach my $addrline (@address_host){
($company_host,$type_host,$name1_host,$str_host,$str_nr_host,$plz_host,$city_host,$bank,$iban,$bic,$blz,$kto,$email,$internet,$hrb,$stnr,$tel_host,$fax_host,$ccmail,$billgrp,$text,$host,$cust,$cent)=@$addrline;
}
#Get CUST for this grp
foreach my $addrline_cust (@address_cust){
($company_cust,$type_cust,$name1_cust,$str_cust,$str_nr_cust,$plz_cust,$city_cust)=@$addrline_cust;
}
#Generate PDF File
my $pdf = PDF::API2->new(-file => $filename);
$pdf->mediabox('A4');
my $page = $pdf->page;
$fnt = $pdf->corefont('Helvetica');
$fnt1 = $pdf->corefont('HelveticaBold');
#Set lines
$lines = $page->gfx;
$title = $page->gfx;
$lines->strokecolor('grey');
$lines->linewidth('0.5');
#Fill BILL DATA into PDF
setlocale(LC_ALL, "$mainsettings{'LANGUAGE'}_$uplang");
foreach (@billar) {
my ($a1,$a2) = split( /\,/, $_ );
$a2=sprintf"%.2f",($a2/1024/1024);
my $sum=(($a2)*$cent);
$sum = sprintf"%.2f",($sum);
# Seitenwechsel ermitteln
if ($y % 18 == 0) {
$txt1->translate(390, 120);
$txt1->text($Lang::tr{'acct pdf zwsum'}); #Pos
$zwsum=sprintf("%.2f",($zwsum));
$txt1->translate(540, 120);
$txt1->text_right("$zwsum".decode('utf8',$cur)); #Pos
$zwsum=0;
$pages++;
$aktpage++;
$x=500;
$page=$pdf->page;
#draw lines
$lines = $page->gfx;
$title = $page->gfx;
$lines->strokecolor('grey');
$lines->linewidth('0.5');
}
#TITLES
$title->linewidth(14);
$title->move(385, 168);
$title->line(545, 168); #Title of SUMBOX
$title->move(60, 523);
$title->line(545, 523);#Bottom horiz. line of Title
# Generate Tables
$lines->move(59, 745);
$lines->line(545, 745);
$lines->move(59, 563);
$lines->line(545, 563);
# Addressbox
$lines->move(61, 710);
$lines->line(61, 715, 66, 715); #TL
$lines->move(61, 610);
$lines->line(61, 605, 66, 605); #BL
$lines->move(285, 715);
$lines->line(290, 715, 290, 710); #TR
$lines->move(290, 610);
$lines->line(290, 605, 285, 605); #BR
# Table for positions
$lines->move(60, 530);
$lines->line(60, 200); #First vert. line POS
$lines->move(90, 523);
$lines->line(90, 200); #Second vert. line
$lines->move(280, 523);
$lines->line(280, 200); #third vert. line
$lines->move(385, 523);
$lines->line(385, 200); #third vert. line
$lines->move(430, 523);
$lines->line(430, 200); #fourth vert. line
$lines->move(545, 530);
$lines->line(545, 200); #fifth vert. line
$lines->move(60, 200);
$lines->line(545, 200); #Bottom horizontal line
#SUM BOX
$lines->move(385, 175);
$lines->line(385, 115); #Left vert. line of SUMBOX
$lines->move(545, 175);
$lines->line(545, 115); #Right vert. line of SUMBOX
$lines->move(385, 115);
$lines->line(545, 115); #Bottom horiz. line of SUMBOX
#Lines on right side after sender and after "bank"
$lines->move(420, 723);
$lines->line(545, 723);# Line "Sender"
$lines->move(420, 648);
$lines->line(545, 648);# Line "Bank"
$lines->move(420, 600);
$lines->line(545, 600);# Line HRB/USTID
#Make lines Visible
$lines->stroke;
$title->stroke;
if (-f "/srv/web/ipfire/html/accounting/logo/$grp/logo.png"){
#Image LOGO
my $gfx = $page->gfx;
my $image = $pdf->image_png("/srv/web/ipfire/html/accounting/logo/$grp/logo.png");
my $width= $image->width;
my $height= $image->height;
$gfx->image($image, (545+($width/2))-$width, 750,0.5);
}
#Set Fonts
$txt = $page->text;
$txt1 = $page->text;
$txt2 = $page->text;
$txt3 = $page->text;
$txt4 = $page->text;
$txt5 = $page->text;
$txt->textstart; #Begin Text
$txt->font($fnt, 10); #Set fontsize for font1
$txt1->font($fnt, 8); #Set fontsize for font2
$txt2->font($fnt1, 10); #Set fontsize for font3
$txt3->font($fnt1, 16); #Set fontsize for font4
$txt4->font($fnt, 6); #Set fontsize for font5
$txt5->font($fnt1, 6); #Set fontsize for font6
#if $cent not set, set it to 0.5
if(!$cent){$cent='0.005';}
#if MWst not set, set it to 19%
if(!$mwst){$mwst='19';}
# Titles
$txt1->translate(65,520);
$txt1->text($Lang::tr{'acct pos'}); #Pos
$txt1->translate(95, 520);
$txt1->text($Lang::tr{'acct name'}); #Host/Name
$txt1->translate(285, 520);
$txt1->text($Lang::tr{'acct amount'}); #Traffic
$txt1->translate(390, 520);
$txt1->text($Lang::tr{'acct cent1'}); #Price /MB
$txt1->translate(435, 520);
$txt1->text($Lang::tr{'acct pdf price'}); #Sum
####################################################################
#Fill Recipient address
my $rec_name= "$company_cust";
my $rec_name1="$name1_cust";
my $rec_str = "$str_cust $str_nr_cust";
my $rec_city = "$plz_cust $city_cust";
#INSERT RECIPIENT
my $o=675;
$txt2->translate(78, 685);
$txt2->text(decode('utf8',$rec_name));
if($rec_name1){
$txt1->translate(78, $o);
$txt1->text(decode('utf8',$rec_name1));
$o=$o-15;
}else{
$o=$o-15;
}
$txt1->translate(78, $o);
$txt1->text(decode('utf8',$rec_str));
$o=$o-10;
$txt1->translate(78, $o);
$txt1->text(decode('utf8',$rec_city));
# INSERT SENDER
my $send_name= "$company_host";
my $send_str = "$str_host $str_nr_host";
my $send_city = "$plz_host $city_host";
my $send_bank ="$bank";
$txt5->translate(420, 725);
$txt5->text(decode('utf8',$Lang::tr{'acct pdf prov'}));
$txt5->translate(420, 715);
$txt5->text(decode('utf8',$send_name));
my $j=705;
if($name1_host){
$txt4->translate(420, $j);
$txt4->text(decode('utf8',$name1_host));
$j=$j-8;
}
$txt4->translate(420, $j);
$txt4->text(decode('utf8',$send_str)); #STR
$j=$j-8;
$txt4->translate(420, $j);
$txt4->text(decode('utf8',$send_city)); #PLZ.City
#Print optional Values tel,fax
my $i=680;
if($tel_host){
$txt4->translate(420, $i);
$txt4->text($Lang::tr{'acct tel'}); #Tel
$txt4->translate(480, $i);
$txt4->text($tel_host); #Telnr
$i=$i-8;
}
if($fax_host){
$txt4->translate(420, $i);
$txt4->text($Lang::tr{'acct fax'}); #Fax
$txt4->translate(480, $i);
$txt4->text($fax_host); #Faxnr
$i=$i-8;
}
if($internet){
$txt4->translate(420, $i);
$txt4->text($Lang::tr{'acct inet'}); #Internet
$txt4->translate(480, $i);
$txt4->text($internet); #www-address
$i=$i-8;
}
$txt5->translate(420, 650);
$txt5->text(decode('utf8',$Lang::tr{'acct bank'})); #"BANK"
$txt4->lead(7);
$txt4->translate(420, 640);
$txt4->paragraph(decode('utf8',$bank), 130, 20, -align => "justify"); #Bankname
if($iban){
$txt4->translate(420, 625);
$txt4->text($Lang::tr{'acct iban'}); #iban
$txt4->translate(480, 625);
$txt4->text(decode('utf8',$iban)); #iban
$txt4->translate(420, 619);
$txt4->text($Lang::tr{'acct bic'}); #bic
$txt4->translate(480, 619);
$txt4->text(decode('utf8',$bic)); #bic
}
if($blz){
$txt4->translate(420, 613);
$txt4->text($Lang::tr{'acct blz'}); #blz
$txt4->translate(420, 607);
$txt4->text($Lang::tr{'acct kto'}); #kto
$txt4->translate(480, 613);
$txt4->text(decode('utf8',$blz)); #blz
$txt4->translate(480, 607);
$txt4->text(decode('utf8',$kto)); #kto
}
#Print USTID and optional HRB
$txt4->translate(420, 590);
$txt4->text($Lang::tr{'acct ustid'}); #USTID
$txt4->translate(480, 590);
$txt4->text($stnr); #ustid
if($hrb){
$txt4->translate(420, 580);
$txt4->text($Lang::tr{'acct hrb'}); #USTID
$txt4->translate(480, 580);
$txt4->text($hrb); #ustid
}
################################################################
#Print Date, Pages ....
$txt3->translate(59, 545);
$txt3->text($Lang::tr{'acct pdf billtxt'});
$txt1->translate(160, 545);
$txt1->text("$no $Lang::tr{'acct billnr'}");
$txt1->translate(60, 532);
$txt1->text("$Lang::tr{'acct pdf time'} $month/$year");
$txt1->translate(545, 550);
$txt1->text_right("$Lang::tr{'acct pdf date'} $fulldate");
$txt1->translate(545, 532);
$txt1->text_right("$Lang::tr{'acct pdf page'} $aktpage / $anz");
if ($a1 eq '999'){last;}
#Print DATA from array to Position table
$txt1->translate(80, $x);
$txt1->text_right($y);
$txt1->translate(95, $x);
$txt1->text($a1);
$txt1->translate(380, $x);
$txt1->text_right("$a2 MB");
$txt1->translate(425, $x);
$txt1->text_right("$cent ".decode('utf8',$cur));
$txt1->translate(540, $x);
$txt1->text_right("$sum ".decode('utf8',$cur));
#Build SUMMARY
$summen[$y-1]="$y,$a2,$sum";
$zwsum=$zwsum+$sum;
$x=$x-15;
$y++;
}
#Print extra billpositions
foreach my $line (@billpos){
my ($grp,$amount,$art,$price)=@$line;
#Print DATA from array to Position table
$txt1->translate(80, $x);
$txt1->text_right($y);
$txt1->translate(95, $x);
$txt1->text(decode('utf8',$art));
$txt1->translate(380, $x);
$txt1->text_right($amount." pcs");
$txt1->translate(540, $x);
$txt1->text_right("$price ".decode('utf8',$cur));
#Build SUMMARY
my $zu=$amount * $price;
$summen[$y-1]="$y,'0',$zu";
$zwsum=$zwsum+$zu;
$x=$x-15;
$y++;
}
foreach (@summen){
my ($a1,$a2,$a3) = split( /\,/, $_ );
$sum=$sum+$a2;
$sum1=$sum1+$a3;
}
# Last Line in positiontable prints the sum of all traffic (therefor txt2 which is BOLD)
$txt2->translate(95, 205);
$txt2->text($Lang::tr{'acct pdf sum1'}); #SUM
$txt2->translate(427, 205);
$txt2->text_right($cent); #cent
$txt2->translate(380, 205);
$txt2->text_right("$sum MB"); #MB
$sum1=sprintf("%.2f",($sum1));
$txt2->translate(540, 205);
$txt2->text_right("$sum1 ".decode('utf8',$cur)); #SUM Eur
$txt->translate(390, 150);
$txt->text($Lang::tr{'acct pdf sum1'});
$txt->translate(540, 150);
$txt->text_right("$sum1 ".decode('utf8',$cur));
$txt->translate(390, 135);
my $endsum=$sum1;
$txt->text("$Lang::tr{'acct mwst_name'} $mwst%");
my $sum1=sprintf("%.2f",($sum1/100*$mwst));
$txt->translate(540, 135);
$txt->text_right("$sum1 ".decode('utf8',$cur));
$txt2->translate(390, 120);
$txt2->text($Lang::tr{'acct sum total'});
my $endsum=sprintf("%.2f",($sum1+$endsum));
$txt2->translate(540, 120);
$txt2->text_right("$endsum ".decode('utf8',$cur));
#Print the optional Billtext if any
$txt4->translate(60, 170);
$txt4->paragraph(decode('utf8',$text), 300, 40, -align => "justify"); #Bankname
#Watermark if preview
if ($preview eq 'on'){
my $eg_trans = $pdf->egstate();
$eg_trans->transparency(0.9);
$txt5->egstate($eg_trans);
$txt5->textlabel(80, 400, $fnt, 60, "PDF preview", -rotate => 40);
$txt5->textlabel(150, 330, $fnt, 60, "IPFire accounting", -rotate => 40);
}
$txt->textend; #END Text
$pdf->save; #Save pdf
$pdf->end( ); #END
if ($preview ne 'on'){
&fillBill($path.$grp,$name,$no,$grp);
}
if($preview eq 'on'){
return $filename;
}
return '0';
}
sub getBillNr {
$dbh=&connectdb;
my $year1=$year+1900;
my $no1;
my $res=$dbh->selectall_arrayref("SELECT MAX(NO) FROM BILLS;");
foreach my $row (@$res){
($no1) = @$row;
}
if(!$no1){$no1=$year1."1000";}
$no1++;
return $no1;
}
sub fillBill {
my $path=$_[0];
my $name=$_[1];
my $no=$_[2];
my $grp=$_[3];
my $sth = $dbh->prepare("INSERT INTO BILLS (NO,GRP,PATH,NAME,DATE) VALUES (?,?,?,?,?);");
my $year1=$year+1900;
++$mon;
$sth->execute($no,$grp,$path,$name,"$mday.$mon.$year1");
$sth->finish();
$dbh->disconnect();
}
sub getbills {
my $grp=shift;
$dbh=&connectdb;
my $res=$dbh->selectall_arrayref("SELECT * FROM BILLS WHERE GRP=?;",undef, $grp);
$dbh->disconnect();
return $res;
}
sub pngsize {
my $Buffer = shift;
my ($width,$height) = ( undef, undef );
if ($Buffer =~ /IHDR(.{8})/) {
my $PNG = $1;
($width,$height) = unpack( "NN", $PNG );
} else {
$width=$Lang::tr{'acct invalid png'};
};
return ($width,$height);
}
sub gifsize {
my ($GIF)=@_;
my ($type,$a,$b,$c,$d,$s,$width,$height) ;
$type=substr($GIF,0,6);
if(!($type =~ m/GIF8[7,9]a/) || (length($s=substr($GIF, 6, 4))!=4) ){
return;
}
($a,$b,$c,$d)=unpack("C"x4,$s);
$width= $b<<8|$a;
$height= $d<<8|$c;
return ($width,$height);
}
sub jpegsize {
my ($JPEG)=@ _ ;
my ($count)=2 ;
my ($length)=length($JPEG) ;
my ($ch)="" ;
my ($c1,$c2,$a,$b,$c,$d,$width,$height) ;
while (($ch ne "\xda") && ($count<$length)) {
while (($ch ne "\xff") && ($count < $length)) {
$ch=substr($JPEG,$count,1);
$count++;
}
while (($ch eq "\xff") && ($count<$length)) {
$ch=substr($JPEG,$count,1);
$count++;
}
if ((ord($ch) >= 0xC0) && (ord($ch) <= 0xC3)) {
$count+=3;
($a,$b,$c,$d)=unpack("C"x4,substr($JPEG,$count,4));
$width=$c<<8|$d;
$height=$a<<8|$b;
return($width,$height);
}else {
($c1,$c2)= unpack("C"x2,substr($JPEG,$count,2));
$count += $c1<<8|$c2;
}
}
}
sub time{
($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst)=localtime();
$hour=sprintf("%02d",$hour);
$min=sprintf("%02d",$min);
$sec=sprintf("%02d",$sec);
$year +=1900;
$mday=sprintf("%02d",$mday);
$mon=sprintf("%02d",$mon+1);
my $res="$mday.$mon.$year $hour:$min:$sec - ";
return $res;
}
sub logger{
my $settings=shift;
my $msg=shift;
#open LOGFILE
if ($settings eq 'on'){
open ACCTLOG,">>/var/log/accounting.log" || print "could not open /var/log/accounting.log ";
print ACCTLOG &time."$msg";
close (ACCTLOG);
}
}
sub updateccaddr {
my $addr=shift;
my $cust=shift;
$dbh=&connectdb;
$dbh->do("UPDATE ACCT_ADDR SET CCMAIL=? WHERE COMPANY=? ;",undef, $addr, $cust);
$dbh->disconnect();
}
return 1;

View File

@@ -0,0 +1,134 @@
# Added for Squid accounting
%tr = (
%tr,
'acct action' => 'Aktion',
'acct activate' => 'Aktivieren',
'acct addresses' => 'Adressverwaltung',
'acct bank' => 'Bank',
'acct bic' => 'BIC',
'acct billarchive' => 'Rechnungsarchiv',
'acct billgroup' => 'Rechnungsgruppen',
'acct billgroupexists' => 'Eine Abrechnungsgruppe mit diesem Namen existiert bereits',
'acct billtext1' => 'Rechnungstext',
'acct billnr' => '(Rechnungsnummer immer angeben)',
'acct billoverview' => 'Rechnungsübersicht',
'acct blz' => 'BLZ',
'acct ccmail' => 'E-Mail Kopie an',
'acct currency' => 'Währung (EUR,USD)',
'acct traffic' => 'Traffic',
'acct amount' => 'Anzahl',
'acct cent' => 'Preis je MB (z.B 0.003)',
'acct cent1' => 'Preis MB',
'acct city' => 'Ort',
'acct config' => 'Konfiguration',
'acct commit' => 'Ausführen',
'acct company' => 'Firma',
'acct companyexists' => 'Eine Firma mit diesem Namen existiert bereits',
'acct companytype' => 'Typ',
'acct customer' => 'Kunde',
'acct cust empty' => 'Noch keine Kunden-Adressen angelegt',
'acct dbsize' => 'Datenbankgröße',
'acct dbmaintenance' => 'Datenbank-Wartung',
'acct delbefore' => 'Alle Einträge löschen vor',
'acct deladr' => 'Löschen',
'acct edit' => 'Bearbeiten',
'acct edit_addr' => 'Anlegen/Bearbeiten',
'acct email' => 'E-Mail',
'acct emptydb' => 'Datenbank leeren (alles)',
'acct emptydbtraf' => 'Datenbank leeren (nur Trafficdaten)',
'acct empty field' => 'Feld darf nicht leer sein: ',
'acct entries' => 'Einträge',
'acct err custdel' => 'Die Adresse kann nicht gelöscht werden, weil sie als Kunde in einer Rechnungsgruppe verwendet wird - Rechnungsgruppe',
'acct err hostdel' => 'Die Adresse kann nicht gelöscht werden, weil sie als Hoster in einer Rechnungsgruppe verwendet wird - Rechnungsgruppe',
'acct exst_cust_addr' => 'Kunden-Adressen',
'acct exst_host_addr' => 'Hoster-Adressen',
'acct expert' => 'Wartungsbereich aktivieren',
'acct expdelbefore' => 'Löschen',
'acct fax' => 'Fax',
'acct fix billpos' => 'Feste Rechnungspositionen der Rechnungsgruppe',
'acct gb' => 'GB',
'acct generated' => 'Erzeugt',
'acct hint billgrp' => 'Bitte zuerst mindestens eine Hoster-Adresse und eine Kunden-Adresse anlegen',
'acct hint_hoster' => 'Muss nur ausgefüllt werden, wenn Typ "Hoster"',
'acct hrb' => 'HRB-Nr',
'acct hoster' => 'Hoster',
'acct hosts' => 'Hostübersicht',
'acct host empty' => 'Noch keine Hoster-Adressen angelegt',
'acct host detail' => 'Host-Details',
'acct iban' => 'IBAN',
'acct inet' => 'Internet',
'acct interval' => 'Checkintervall',
'acct invalid' => 'Ungültiger Wert für',
'acct invalid billpos' => 'Es müssen alle Felder für Extra-Rechnungspositionen ausgefüllt sein',
'acct invalid mailip' => 'Ungültige IP-Adresse für Mailserver',
'acct invalid mailfqdn' => 'Ungültiger FQDN für Mailserver',
'acct invalid mailport' => 'Ungültiger Port für Mailserver',
'acct invalid png' => 'Ungültige PNG Datei',
'acct invalid pngsize' => 'Ungültige PNG Größe',
'acct kb' => 'KB',
'acct kto' => 'KTO',
'acct latestdb' => 'Letzter DB-Eintrag',
'acct logging' => 'Logging (/var/log/accounting.log) aktivieren',
'acct logo' => 'Aktuelles Logo',
'acct logo upload' => 'Logo Hochladen (PNG, max. 400x150)',
'acct maintenance' => 'Wartung',
'acct mailaddr' => 'Mailserver-Adresse',
'acct mailport' => 'Mailserver-Port',
'acct mailuser' => 'Benutzername',
'acct mailpass' => 'Passwort',
'acct mailrcpt' => 'E-Mail-Empfänger',
'acct mailsender' => 'E-Mail Absender',
'acct mailtxt' => 'Text der Rechnungsmails',
'acct mb' => 'MB',
'acct members' => 'Mitglieder',
'acct menu' => 'Proxy-Abrechnung',
'acct month' => 'Monat',
'acct multiuser' => 'User dürfen in mehreren Gruppen sein',
'acct mwst_name' => 'USt.',
'acct mwst' => 'Mehrwertsteuer in %',
'acct name1' => 'Name 1',
'acct name2' => 'Name 2',
'acct nr' => 'RG-Nr.',
'acct oldestdb' => 'Erster DB-Eintrag',
'acct optional' => 'Diese Felder sind optional',
'acct parameter' => 'Parameter',
'acct path' => 'Pfad',
'acct pdf billtxt' => 'Rechnung',
'acct pdf date' => 'Datum',
'acct pdf zwsum' => 'Zwischensumme',
'acct pdf page' => 'Seite',
'acct pdf prov' => 'Absender',
'acct pdf sum1' => 'Summe',
'acct pdf price' => 'Preis',
'acct pdf time' => 'Abrechnung',
'acct plz' => 'PLZ',
'acct preview' => 'Rechnungsvorschau',
'acct price pp' => 'Einzelpreis',
'acct proxy_enable' => 'Bitte zuerst Proxy aktivieren',
'acct pos' => 'Pos.',
'acct sum total' => 'Gesamtsumme',
'acct name' => 'Bezeichnung',
'acct no data' => 'Keine Daten vorhanden',
'acct rrdsize' => 'Größe des Rechnungs-Verzeichnisses',
'acct settings' => 'Accounting-Einstellungen',
'acct skipurl' => 'Diese URLs nicht bewerten',
'acct status' => 'Status',
'acct str' => 'Straße',
'acct str_nr' => 'Nr.',
'acct subject' => 'Betreff der Rechnungsmails',
'acct sum' => 'Summe',
'acct task' => 'Aufgabe',
'acct tb' => 'TB',
'acct tel' => 'Telefon',
'acct tls' => 'Benutze TLS',
'acct traffic monthly' => 'Monatliches Datenvolumen',
'acct title' => 'Webproxy-Abrechnung',
'acct usemail' => 'Mailversand aktivieren',
'acct usermulti' => 'befindet sich bereits in Gruppe',
'acct ustid' => 'USt-ID',
'acct edit settings' => 'Einstellungen bearbeiten',
'acct value' => 'Wert',
'acct view' => 'Anzeigen',
'acct year' => 'Jahr'
);
# End Squid accounting

View File

@@ -0,0 +1,134 @@
# Added for Squid accounting
%tr = (
%tr,
'acct action' => 'Action',
'acct activate' => 'Activate',
'acct addresses' => 'Address Management',
'acct bank' => 'Bank',
'acct bic' => 'BIC',
'acct billarchive' => 'Bill Archive',
'acct billgroup' => 'Billing Groups',
'acct billgroupexists' => 'A billing group with this name already exists',
'acct billtext1' => 'Bill text',
'acct billnr' => '(always state bill number)',
'acct billoverview' => 'Bill overview',
'acct blz' => 'Bank code',
'acct ccmail' => 'E-Mail CC-Addresses',
'acct currency' => 'Currency (EUR,USD)',
'acct traffic' => 'Traffic',
'acct amount' => 'Amount',
'acct cent' => 'Price/MB (e.g. 0.003)',
'acct cent1' => 'Price MB',
'acct city' => 'City',
'acct config' => 'Configuration',
'acct commit' => 'Execute',
'acct company' => 'Company',
'acct companyexists' => 'A Company with this name already exists',
'acct companytype' => 'Type',
'acct customer' => 'Customer',
'acct cust empty' => 'No Customer addresses defined',
'acct dbsize' => 'Database size',
'acct dbmaintenance' => 'Database maintenance',
'acct delbefore' => 'Delete all entries before',
'acct deladr' => 'Delete',
'acct edit' => 'Edit',
'acct edit_addr' => 'Add / Edit',
'acct email' => 'E-Mail',
'acct emptydb' => 'Erase Database (all data)',
'acct emptydbtraf' => 'Erase Database (only traffic data)',
'acct empty field' => 'Field must not be empty: ',
'acct entries' => 'Entries',
'acct err custdel' => 'Address can not be deleted. It is defined as customer in a Bill group - Bill group',
'acct err hostdel' => 'Address can not be deleted. It is defined as provider in a Bill group - Bill group',
'acct exst_cust_addr' => 'Customer addresses',
'acct exst_host_addr' => 'Provider addresses',
'acct expert' => 'Activate maintenance area',
'acct expdelbefore' => 'Delete',
'acct fax' => 'Faximile',
'acct fix billpos' => 'Fixed bill positions of bill group',
'acct gb' => 'GB',
'acct generated' => 'Generated',
'acct hint billgrp' => 'You have to define a provider and a customer address first',
'acct hint_hoster' => 'Has only to be filled when type "provider"',
'acct hrb' => 'HRB-No',
'acct hoster' => 'Provider',
'acct hosts' => 'Host Overview',
'acct host empty' => 'No provider addresses defined',
'acct host detail' => 'Host Details',
'acct iban' => 'IBAN',
'acct inet' => 'Internet',
'acct interval' => 'Checkintervall',
'acct invalid' => 'Invalid value for',
'acct invalid billpos' => 'You have to fill in all fields for fixed bill positions',
'acct invalid mailip' => 'Invalid IP address for mailserver',
'acct invalid mailfqdn' => 'Invalid FQDN for mailserver',
'acct invalid mailport' => 'Invalid port for mailserver',
'acct invalid png' => 'Invalid PNG file',
'acct invalid pngsize' => 'Invalid PNG size',
'acct kb' => 'KB',
'acct kto' => 'Account Number',
'acct latestdb' => 'Last DB entry',
'acct logging' => 'Activate Logging (/var/log/accounting.log)',
'acct logo' => 'Actual Logo',
'acct logo upload' => 'Upload Logo (PNG, max. 400x150)',
'acct maintenance' => 'Maintenance',
'acct mailaddr' => 'Mailserver address',
'acct mailport' => 'Mailserver port',
'acct mailuser' => 'Username',
'acct mailpass' => 'Password',
'acct mailrcpt' => 'E-Mail Recipient',
'acct mailsender' => 'E-Mail Sender',
'acct mailtxt' => 'Text for bill mail',
'acct mb' => 'MB',
'acct members' => 'Members',
'acct menu' => 'Proxy Accounting',
'acct month' => 'Month',
'acct multiuser' => 'User can be in multiple groups',
'acct mwst_name' => 'VAT',
'acct mwst' => 'Tax rate',
'acct name1' => 'Name 1',
'acct name2' => 'Name 2',
'acct nr' => 'RG-No.',
'acct oldestdb' => 'Fist DB Entry',
'acct optional' => 'These fields are optional',
'acct parameter' => 'Parameter',
'acct path' => 'Path',
'acct pdf billtxt' => 'Bill',
'acct pdf date' => 'Date',
'acct pdf zwsum' => 'subtotal',
'acct pdf page' => 'Page',
'acct pdf prov' => 'Sender',
'acct pdf sum1' => 'Sum',
'acct pdf price' => 'Price',
'acct pdf time' => 'Accounting',
'acct plz' => 'Postcode',
'acct preview' => 'Bill preview',
'acct price pp' => 'Unit price',
'acct proxy_enable' => 'Please actiavte proxy first',
'acct pos' => 'Pos.',
'acct sum total' => 'Total',
'acct name' => 'Description',
'acct no data' => 'No Data available',
'acct rrdsize' => 'Size of Bill directory',
'acct settings' => 'Accounting settings',
'acct skipurl' => 'Skip these URLs (Intranet)',
'acct status' => 'Status',
'acct str' => 'Steet',
'acct str_nr' => 'No.',
'acct subject' => 'Subject',
'acct sum' => 'Sum',
'acct task' => 'Task',
'acct tb' => 'TB',
'acct tel' => 'Telephone',
'acct tls' => 'Use TLS',
'acct traffic monthly' => 'Monthly data volume',
'acct title' => 'Webproxy Accounting',
'acct usemail' => 'Send bills via Mail',
'acct usermulti' => 'is already in group',
'acct ustid' => 'USt-ID',
'acct edit settings' => 'Edit settings',
'acct value' => 'Value',
'acct view' => 'Show',
'acct year' => 'Year'
);
# End Squid accounting

265
src/squid-accounting/acct.pl Executable file
View File

@@ -0,0 +1,265 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2014 IPFire Team <alexander.marx@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/>. #
# #
###############################################################################
###########
# Modules #
###########
use Time::Local;
use File::ReadBackwards;
use strict;
#use warnings;
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/accounting/acct-lib.pl";
require "${General::swroot}/lang.pl";
#############
# Variables #
#############
my $count = 0;
my $dbh;
my $logfile = "/var/log/squid/access.log";
my $line = '';
my $checktime = 3600; #1 hour = 3600 sec
my $starttime = time;
my ($time,$elapsed,$ip,$state,$bytes,$method,$url,$user,$peerstate,$type); #split logfileline into variables
my $name;
my $name1;
my $settingsfile = "${General::swroot}/accounting/settings.conf";
my $proxyenabled = "${General::swroot}/proxy/enable";
my %counter = ();
my %counterip = ();
my %settings = ();
my %toplist = ();
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydat,$isdst)=localtime();
my $skipurlcount=0;
my $skipurlsum=0;
&General::readhash("$settingsfile", \%settings);
my $skipurl=$settings{'SKIPURLS'};
$skipurl="'".$skipurl."'";
my ($mini,$max)=&ACCT::getminmax;
my $now = localtime;
my $proxylog;
my $proxysrv;
########
# Main #
########
&checkproxy;
#If we have a disabled file and the proxy is off, we don't need to check anything, exit!
if((! -f $proxyenabled || $proxylog eq $Lang::tr{'stopped'}) && -f "${General::swroot}/accounting/disabled"){
&ACCT::logger($settings{'LOG'}," Proxy or proxylogging disabled - exiting with no data collection\n");
exit 0;
}
#If proxy was turned off within last hour, we need to check missing minutes and write a disabled file
if ((! -f $proxyenabled || $proxylog eq $Lang::tr{'stopped'}) && ! -f "${General::swroot}/accounting/disabled"){
$checktime = (time-$max);
open (FH,">${General::swroot}/accounting/disabled");
close (FH);
&ACCT::logger($settings{'LOG'}," Proxy or proxylogging was disabled during last hour - just checking meantime and disabling data collection\n");
}
#If proxy is on, we are doing a normal run. maybe we had a disabled file, so delete it here
if (-f $proxyenabled && $proxylog eq $Lang::tr{'running'}){
#check if we are running again after the was shutdown and reenabled
if (-f "${General::swroot}/accounting/disabled"){
unlink("${General::swroot}/accounting/disabled");
}
#Find out if the month changed
$dbh=&ACCT::connectdb;
my $m=sprintf("%d",(localtime((time-3600)))[4]+1);
&ACCT::logger($settings{'LOG'},"month before one hour $m, now is ".($mon+1)."\n");
if ($m < ($mon+1) || $m == '12' && ($mon+1) == '1'){
#Logrotate
my $year1=$year+1900;
system ("tar", "cfz", "/var/log/accounting-$m-$year1.tar.gz", "/var/log/accounting.log");
unlink ("/var/log/accounting.log");
open (FH,">/var/log/accounting.log");
close (FH);
chmod 0755, "/var/log/accounting.log";
#move all db entries older than 2 months to second table and cumulate them hourly
&ACCT::movedbdata;
&ACCT::logger($settings{'LOG'},"New Month. Old trafficvalues moved to ACCT_HIST Table\n");
if ($settings{'USEMAIL'} eq 'on'){
&ACCT::logger($settings{'LOG'},"Mailserver is activated - Now sending bills via mail...\n");
my $res=&ACCT::getbillgroups;
foreach my $line (@$res){
my ($grp) = @$line;
&sendbill($grp,$settings{'MWST'},$settings{'CURRENCY'});
}
}else{
&ACCT::logger($settings{'LOG'},"Mailserver is deactivated - We are NOT sending bills via mail...\n");
}
}
&ACCT::logger($settings{'LOG'},"Start reading last hour of access.log\n");
&readlog;
&fill_db;
&ACCT::closedb;
$skipurlsum=sprintf("%.2f",$skipurlsum/(1024*1024));
&ACCT::logger($settings{'LOG'},"skipped: $skipurlcount Adressen\n");
&ACCT::logger($settings{'LOG'},"skipped: $skipurlsum MB\n") if ($skipurl);
}
#############
# functions #
#############
sub checkproxy{
if(-f "${General::swroot}/proxy/enable"){
$proxysrv=$Lang::tr{'running'};
}else{
$proxysrv=$Lang::tr{'stopped'};
}
my $srce = "${General::swroot}/proxy/squid.conf";
my $string1 = 'access\.log';
open(FH, $srce);
while(my $line = <FH>) {
if($line =~ m/$string1/) {
$proxylog=$Lang::tr{'running'};
}
}
close FH;
return;
}
sub readlog{
my $url1;
my $user1;
$count = 0;
my $urlcnt=0;
&ACCT::logger($settings{'LOG'},"Start: $now. Reading data back till: ".localtime(($starttime-$checktime)).".\n");
#Open Logfile and begin to read the file backwards
my $bw = File::ReadBackwards->new( $logfile ) or die "can't read $logfile $!" ;
while( defined( $line = $bw->readline ) ) {
undef $url1;
chomp $line;
#Divide $line into single variables to get timestamp and check if we are within hte desired timerange
($time,$elapsed,$ip,$state,$bytes,$method,$url,$user,$peerstate,$type)=split(m/\s+/, $line);
$count += $bytes;
$time = substr($time, 0, -4);
if (($time > ($starttime-$checktime))){
#Skip DENIED stated lines (can be reactivated later)
next if ($state =~ m/DENIED/);
#extract site name
if ($url =~ m/([a-z]+:\/\/)??([a-z0-9\-]+\.){1}(([a-z0-9\-]+\.){0,})([a-z0-9\-]+){1}(:[0-9]+)?\/(.*)/o) {
$url=$2.$3.$5;
} else {
my ($a,$b)=split(":",$url);
$url=$a;
}
#Skip special URLs like intranet and webservers from local network
if ($url =~ m/$skipurl/o) {
$skipurlcount++;
$skipurlsum+=$bytes;
next;
};
#Increase urlcounter
$urlcnt++;
#Get Data for accounting
$counter{$user}{'bytes'} += $bytes if ($user ne '-');
$counter{$ip}{'bytes'} += $bytes;
}else{
#If we are out of timewindow, break
last;
}
}
$count=sprintf("%.2f",$count/(1024*1024));
&ACCT::logger($settings{'LOG'},"got $count MB from $urlcnt URLs this run.\n");
$bw->close;
}
sub fill_db{
my $tim=time();
#Fill ACCT table with accounting information
foreach my $name (sort keys %counter){
foreach my $bytes (keys %{ $counter{$name} }) {
$dbh->do("insert into ACCT (TIME_RUN,NAME,BYTES) values ('$tim','$name','$counter{$name}{$bytes}');");
}
}
}
sub sendbill {
my $rggrp=$_[0];
my $mwst=$_[1];
my $cur = $_[2];
my @now = localtime(time);
$now[5] = $now[5] + 1900;
my $actmonth = $now[4];
my $month = '0'.$actmonth if $actmonth < 10;
my $actyear = $now[5];
my ($from,$till)=&ACCT::getmonth($actmonth,$actyear); #FIXME month and year as variables!
my @billar = &ACCT::GetTaValues($from,$till,$rggrp);
my $address_cust = &ACCT::getTaAddress($rggrp,'CUST');
my $address_host = &ACCT::getTaAddress($rggrp,'HOST');
my $billpos = &ACCT::getextrabillpos($rggrp);
my $no = &ACCT::getBillNr;
my $back = &ACCT::pdf2(\@billar,$actmonth,$actyear,$mwst,$address_cust,$address_host,$billpos,$rggrp,$cur);
my ($company_cust,$type_cust,$name1_cust,$str_cust,$str_nr_cust,$plz_cust,$city_cust,$bank,$iban,$bic,$blz,$kto,$email,$internet,$hrb,$stnr,$tel_host,$fax_host,$ccmail,$billgrp,$text,$host,$cust,$cent);
foreach my $addrline_cust (@$address_cust){
($company_cust,$type_cust,$name1_cust,$str_cust,$str_nr_cust,$plz_cust,$city_cust,$bank,$iban,$bic,$blz,$kto,$email,$internet,$hrb,$stnr,$tel_host,$fax_host,$ccmail,$billgrp,$text,$host,$cust,$cent)=@$addrline_cust;
}
if ($back eq '0'){
&ACCT::logger($settings{'LOG'},"Bill for $company_cust successfully created.\n");
my $file="'/var/ipfire/accounting/bill/$rggrp/$month-$actyear-$no.pdf'";
$settings{'MAILTXT'} =~ tr/\|/\r\n/ ;
my $cmd = "/usr/local/bin/sendEmail ";
$cmd .= " -f $settings{'MAILSENDER'}"; #Sender
$cmd .= " -t $email"; #Recipient
if ($ccmail){
$cmd .= " -cc $ccmail";
}
#Send Mail via TLS?
if ($settings{'TLS'} eq 'on'){
$cmd .= " -o tls=yes"; #TLS
}
$cmd .= " -u '$settings{'MAILSUB'}'"; #Subject
$cmd .= " -m '$settings{'MAILTXT'}'"; #Mailtext
$cmd .= " -s $settings{'MAILSRV'}:$settings{'MAILPORT'}"; #Mailserver:port
$cmd .= " -a $file";
my $res=system ($cmd);
if ($res == 0){
&ACCT::logger($settings{'LOG'},"Bill for $company_cust successfully sent.\n");
}elsif ($res > 0){
&ACCT::logger($settings{'LOG'},"ERROR: Bill for $company_cust NOT sent.\n");
}
return 0;
}else{
&ACCT::logger($settings{'LOG'},"ERROR Bill for $company_cust could not be created.\n");
my $cmd = "/usr/local/bin/sendEmail ";
$cmd .= " -f $settings{'MAILSENDER'}";
$cmd .= " -t $settings{'MAILSENDER'}";
$cmd .= " -u Fehler Squid Accounting";
$cmd .= " -m 'Die Rechnung konnte nicht erzeugt und per Mail versendet werden' $company_cust";
$cmd .= " -s $settings{'MAILSRV'}:$settings{'MAILPORT'}";
my $res=system ($cmd);
return 0;
}
}

View File

@@ -0,0 +1,5 @@
/var/ipfire/accounting/settings.conf
/var/ipfire/accounting/bill
/srv/web/ipfire/html/accounting
/var/ipfire/accounting/acct.db
/var/log/accounting.log

View File

@@ -0,0 +1,49 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2014 IPFire Team <alexander.marx@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/>. #
# #
###############################################################################
use DBI;
###############################################################################
my $dbh;
my $dsn="dbi:SQLite:dbname=/var/ipfire/accounting/acct.db";
###############################################################################
$dbh = DBI->connect($dsn, "", "",{RaiseError => 1, AutoCommit => 1})or die "ERROR $!";
$dbh->do('CREATE TABLE ACCT (TIME_RUN "NUM",NAME "TXT",BYTES "NUM");');
$dbh->do('CREATE TABLE ACCT_HIST (TIME_RUN "NUM",NAME "TXT",BYTES "NUM");');
$dbh->do('CREATE TABLE ACCT_ADDR (COMPANY "TXT",TYPE "TXT",NAME1 "TXT", STR "TXT", NR "TXT", POSTCODE "NUM", CITY "TXT",BANK "TXT",IBAN "TXT",BIC "TXT",BLZ "NUM",ACCOUNT "NUM", EMAIL "TXT",INTERNET "TXT", HRB "TXT", USTID "TXT", TEL "TXT", FAX "TXT", CCMAIL "TXT");');
$dbh->do('CREATE TABLE BILLINGGRP (NAME "TXT",BILLTEXT "TXT",HOST "TXT",CUST "TXT",CENT "NUM");');
$dbh->do('CREATE TABLE BILLINGHOST (GRP "TXT",HOST "TXT");');
$dbh->do('CREATE TABLE BILLPOS (GRP "TXT",AMOUNT "INT", POS "TXT", PRICE "NUM");');
$dbh->do('CREATE TABLE BILLS (NO "NUM", PATH "TXT", NAME "TXT", DATE "NUM", GRP "TXT");');
$dbh->disconnect();
exit 0;