From 9f94a17eacd85144a1aee14929688b33e9393fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20F=C3=BCrmann?= Date: Tue, 17 Feb 2015 19:40:07 +0100 Subject: [PATCH] Server initialization and domain management (without ssl for now) --- install/apps/metronome-init | 62 +++ .../mod_auth_external/authenticate_isp.php | 65 +++ .../mod_auth_external/authenticate_isp.sh | 38 ++ .../mod_auth_external/isuser_isp.php | 44 ++ .../mod_auth_external/mod_auth_external.lua | 118 +++++ .../apps/metronome_libs/mod_discoitems.lua | 24 + .../mod_webpresence/icons/status_away.png | Bin 0 -> 948 bytes .../mod_webpresence/icons/status_chat.png | Bin 0 -> 920 bytes .../mod_webpresence/icons/status_dnd.png | Bin 0 -> 822 bytes .../mod_webpresence/icons/status_offline.png | Bin 0 -> 905 bytes .../mod_webpresence/icons/status_online.png | Bin 0 -> 920 bytes .../mod_webpresence/icons/status_xa.png | Bin 0 -> 954 bytes .../mod_webpresence/mod_webpresence.lua | 118 +++++ install/dist/conf/debian60.conf.php | 4 + install/dist/lib/debian60.lib.php | 4 + install/install.php | 19 + install/lib/installer_base.lib.php | 64 ++- install/sql/incremental/upd_0081.sql | 55 +++ install/sql/ispconfig3.sql | 59 +++ install/tpl/metronome_conf_global.master | 65 +++ install/tpl/metronome_conf_main.master | 3 + install/tpl/server.ini.master | 9 + interface/web/admin/form/server.tform.php | 6 + .../web/admin/form/server_config.tform.php | 80 ++++ interface/web/admin/lib/lang/en_server.lng | 2 + .../web/admin/lib/lang/en_server_config.lng | 14 + .../web/admin/lib/lang/en_server_list.lng | 2 + interface/web/admin/list/server.list.php | 9 + .../templates/server_config_xmpp_edit.htm | 73 +++ .../admin/templates/server_edit_services.htm | 6 + interface/web/admin/templates/server_list.htm | 3 + interface/web/client/form/client.tform.php | 100 ++++ interface/web/client/lib/lang/en_client.lng | 21 + .../client/templates/client_edit_limits.htm | 64 +++ interface/web/js/xmpp_domain_muc.js | 26 ++ interface/web/js/xmpp_domain_registration.js | 25 + interface/web/mail/form/xmpp_domain.tform.php | 284 ++++++++++++ .../web/mail/lib/lang/en_xmpp_domain.lng | 28 ++ .../lib/lang/en_xmpp_domain_admin_list.lng | 8 + .../web/mail/lib/lang/en_xmpp_domain_list.lng | 7 + interface/web/mail/lib/module.conf.php | 24 + interface/web/mail/list/xmpp_domain.list.php | 109 +++++ .../mail/templates/xmpp_domain_admin_list.htm | 60 +++ .../web/mail/templates/xmpp_domain_edit.htm | 124 +++++ .../templates/xmpp_domain_edit_modules.htm | 52 +++ .../mail/templates/xmpp_domain_edit_muc.htm | 87 ++++ .../web/mail/templates/xmpp_domain_list.htm | 74 +++ interface/web/mail/xmpp_domain_del.php | 102 ++++ interface/web/mail/xmpp_domain_edit.php | 436 ++++++++++++++++++ interface/web/mail/xmpp_domain_list.php | 28 ++ server/conf/metronome_conf_global.master | 48 ++ server/conf/metronome_conf_host.master | 138 ++++++ server/conf/metronome_conf_main.master | 3 + server/conf/metronome_conf_status.master | 12 + server/mods-available/xmpp_module.inc.php | 109 +++++ server/plugins-available/xmpp_plugin.inc.php | 232 ++++++++++ server/server.sh | 1 + 57 files changed, 3147 insertions(+), 1 deletion(-) create mode 100644 install/apps/metronome-init create mode 100644 install/apps/metronome_libs/mod_auth_external/authenticate_isp.php create mode 100644 install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh create mode 100644 install/apps/metronome_libs/mod_auth_external/isuser_isp.php create mode 100644 install/apps/metronome_libs/mod_auth_external/mod_auth_external.lua create mode 100644 install/apps/metronome_libs/mod_discoitems.lua create mode 100644 install/apps/metronome_libs/mod_webpresence/icons/status_away.png create mode 100644 install/apps/metronome_libs/mod_webpresence/icons/status_chat.png create mode 100644 install/apps/metronome_libs/mod_webpresence/icons/status_dnd.png create mode 100644 install/apps/metronome_libs/mod_webpresence/icons/status_offline.png create mode 100644 install/apps/metronome_libs/mod_webpresence/icons/status_online.png create mode 100644 install/apps/metronome_libs/mod_webpresence/icons/status_xa.png create mode 100644 install/apps/metronome_libs/mod_webpresence/mod_webpresence.lua create mode 100644 install/sql/incremental/upd_0081.sql create mode 100644 install/tpl/metronome_conf_global.master create mode 100644 install/tpl/metronome_conf_main.master create mode 100644 interface/web/admin/templates/server_config_xmpp_edit.htm create mode 100644 interface/web/js/xmpp_domain_muc.js create mode 100644 interface/web/js/xmpp_domain_registration.js create mode 100644 interface/web/mail/form/xmpp_domain.tform.php create mode 100644 interface/web/mail/lib/lang/en_xmpp_domain.lng create mode 100644 interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng create mode 100644 interface/web/mail/lib/lang/en_xmpp_domain_list.lng create mode 100644 interface/web/mail/list/xmpp_domain.list.php create mode 100644 interface/web/mail/templates/xmpp_domain_admin_list.htm create mode 100644 interface/web/mail/templates/xmpp_domain_edit.htm create mode 100644 interface/web/mail/templates/xmpp_domain_edit_modules.htm create mode 100644 interface/web/mail/templates/xmpp_domain_edit_muc.htm create mode 100644 interface/web/mail/templates/xmpp_domain_list.htm create mode 100644 interface/web/mail/xmpp_domain_del.php create mode 100644 interface/web/mail/xmpp_domain_edit.php create mode 100644 interface/web/mail/xmpp_domain_list.php create mode 100644 server/conf/metronome_conf_global.master create mode 100644 server/conf/metronome_conf_host.master create mode 100644 server/conf/metronome_conf_main.master create mode 100644 server/conf/metronome_conf_status.master create mode 100644 server/mods-available/xmpp_module.inc.php create mode 100644 server/plugins-available/xmpp_plugin.inc.php diff --git a/install/apps/metronome-init b/install/apps/metronome-init new file mode 100644 index 0000000000..e10ef3c32e --- /dev/null +++ b/install/apps/metronome-init @@ -0,0 +1,62 @@ +#! /bin/sh +# +# metronome Start/stop metronome server +# + +### BEGIN INIT INFO +# Provides: metronome +# Required-Start: $remote_fs $network $named $time +# Required-Stop: $remote_fs $network $named $time +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Starts metronome server +# Description: Starts metronome server, an XMPP server written in Lua. +### END INIT INFO + +METRONOME=/usr/bin/metronomectl +PIDDIR=/var/run/metronome +NAME=metronome + +test -e $METRONOME || exit 0 + +start() +{ + mkdir $PIDDIR -p + chown metronome:metronome $PIDDIR + chmod 750 $PIDDIR + + $METRONOME start >> /dev/null +} + +stop() +{ + $METRONOME stop >> /dev/null +} + +case "$1" in + start) + echo -n "Starting Metronome..." + start & + ;; + stop) + echo -n "Stopping Metronome..." + stop & + ;; + restart) + echo -n "Restarting Metronome..." + stop & + start & + ;; + *) + echo "Usage: $0 {start|stop|restart}" >&2 + exit 1 + ;; +esac + +if [ $? -eq 0 ]; then + echo . +else + echo " failed!" +fi + +exit 0 diff --git a/install/apps/metronome_libs/mod_auth_external/authenticate_isp.php b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.php new file mode 100644 index 0000000000..7c59f3759b --- /dev/null +++ b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.php @@ -0,0 +1,65 @@ + 'f47kmm5Yh5hJzSws2KTS', + 'weirdempire.de' => 'scNDcU37gQ7MCMeBgaJX' +); + +$arg_email = ''; +$arg_password = ''; + +if(count($argv) == 4){ + $arg_email = $argv[1].'@'.$argv[2]; + $arg_password = $argv[3]; +} +$client = new SoapClient(null, array('location' => $soap_location, 'uri' => $soap_uri)); +try { + //* Login to the remote server + if($session_id = $client->login($username,$password)) { + //var_dump($client->mail_alias_get($session_id, array('source' => 'blablubb@divepage.net', 'type' => 'alias', 'active' => 'y'))); + // Is Mail Alias? + $alias = $client->mail_alias_get($session_id, array('source' => $arg_email, 'type' => 'alias', 'active' => 'y')); + if(count($alias)) + $arg_email = $alias[0]['destination']; + $mailbox = $client->mail_user_get($session_id, array('email' => $arg_email)); + if(count($mailbox)){ + $password = $mailbox[0]['password']; + echo checkAuth($argv[1], $argv[2], $arg_password, $password);//intval(crypt($arg_password, $password) == $password); + } + else + echo 0; + //* Logout + $client->logout($session_id); + } + else + echo 0; +} catch (SoapFault $e) { + echo 0; +} + +function checkAuth($user, $domain, $pw, $pw_mailbox){ + global $auth_keys; + if(crypt($pw, $pw_mailbox) == $pw_mailbox) + return intval(1); + + if(array_key_exists($domain, $auth_keys)){ + $datetime = new DateTime(); + $datetime->setTimezone(new DateTimeZone("UTC")); + for($t = $datetime->getTimestamp(); $t >= $datetime->getTimestamp()-30; $t--){ + $pw_api = md5($domain.'@'.$auth_keys[$domain].'@'.$user.'@'.$t); + if($pw_api == $pw) + return intval(1); + } + } + return intval(0); +} +?> \ No newline at end of file diff --git a/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh new file mode 100644 index 0000000000..c4832f4433 --- /dev/null +++ b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +IFS=":" +AUTH_OK=1 +AUTH_FAILED=0 +LOGFILE="/var/log/metronome/auth.log" +USELOG=true + +while read ACTION USER HOST PASS ; do + + [ $USELOG == true ] && { echo "Date: $(date) Action: $ACTION User: $USER Host: $HOST" >> $LOGFILE; } + + case $ACTION in + "auth") + if [ `/usr/bin/php /usr/lib/metronome/spicy-modules/mod_auth_external/authenticate_isp.php $USER $HOST $PASS` == 1 ] ; then + echo $AUTH_OK + [ $USELOG == true ] && { echo "AUTH OK" >> $LOGFILE; } + else + echo $AUTH_FAILED + [ $USELOG == true ] && { echo "AUTH FAILED" >> $LOGFILE; } + fi + ;; + "isuser") + if [ `/usr/bin/php /usr/lib/metronome/spicy-modules/mod_auth_external/isuser_isp.php $USER $HOST` == 1 ] ; then + echo $AUTH_OK + [ $USELOG == true ] && { echo "AUTH OK" >> $LOGFILE; } + else + echo $AUTH_FAILED + [ $USELOG == true ] && { echo "AUTH FAILED" >> $LOGFILE; } + fi + ;; + *) + echo $AUTH_FAILED + [ $USELOG == true ] && { echo "NO ACTION GIVEN" >> $LOGFILE; } + ;; + esac + +done diff --git a/install/apps/metronome_libs/mod_auth_external/isuser_isp.php b/install/apps/metronome_libs/mod_auth_external/isuser_isp.php new file mode 100644 index 0000000000..d37053270e --- /dev/null +++ b/install/apps/metronome_libs/mod_auth_external/isuser_isp.php @@ -0,0 +1,44 @@ + $soap_location, 'uri' => $soap_uri)); +try { + //* Login to the remote server + if($session_id = $client->login($username,$password)) { + //var_dump($client->mail_alias_get($session_id, array('source' => 'blablubb@divepage.net', 'type' => 'alias', 'active' => 'y'))); + // Is Mail Alias? + $alias = $client->mail_alias_get($session_id, array('source' => $arg_email, 'type' => 'alias', 'active' => 'y')); + if(count($alias)) + $arg_email = $alias[0]['destination']; + $mailbox = $client->mail_user_get($session_id, array('email' => $arg_email)); + if(count($mailbox)){ + echo 1; + //$password = $mailbox[0]['password']; + //echo intval(crypt($arg_password, $password) == $password); + } + else + echo 0; + //* Logout + $client->logout($session_id); + } + else + echo 0; +} catch (SoapFault $e) { + echo 0; +} +?> \ No newline at end of file diff --git a/install/apps/metronome_libs/mod_auth_external/mod_auth_external.lua b/install/apps/metronome_libs/mod_auth_external/mod_auth_external.lua new file mode 100644 index 0000000000..c86400610e --- /dev/null +++ b/install/apps/metronome_libs/mod_auth_external/mod_auth_external.lua @@ -0,0 +1,118 @@ +local nodeprep = require "util.encodings".stringprep.nodeprep; +local lpc = require "lpc"; + +local config = require "core.configmanager"; +local log = module._log; +local host = module.host; +local script_type = config.get(host, "external_auth_protocol") or "generic"; +assert(script_type == "ejabberd" or script_type == "generic"); +local command = config.get(host, "external_auth_command") or ""; +assert(type(command) == "string"); +assert(not host:find(":")); +local usermanager = require "core.usermanager"; +local jid_bare = require "util.jid".bare; +local new_sasl = require "util.sasl".new; + +local pid; +local readfile; +local writefile; + +local function send_query(text) + if pid and lpc.wait(pid,1) ~= nil then + log("debug","error, process died, force reopen"); + pid=nil; + end + if not pid then + log("debug", "Opening process " .. command); + pid, writefile, readfile = lpc.run(command); + end + if not pid then + log("debug", "Process failed to open"); + return nil; + end + + writefile:write(text); + writefile:flush(); + if script_type == "ejabberd" then + return readfile:read(4); + elseif script_type == "generic" then + return readfile:read(); + end +end + +function do_query(kind, username, password) + if not username then return nil, "not-acceptable"; end + username = nodeprep(username); + if not username then return nil, "jid-malformed"; end + + local query = (password and "%s:%s:%s:%s" or "%s:%s:%s"):format(kind, username, host, password); + local len = #query + if len > 1000 then return nil, "policy-violation"; end + + if script_type == "ejabberd" then + local lo = len % 256; + local hi = (len - lo) / 256; + query = string.char(hi, lo)..query; + end + if script_type == "generic" then + query = query..'\n'; + end + + local response = send_query(query); + if (script_type == "ejabberd" and response == "\0\2\0\0") or + (script_type == "generic" and response == "0") then + return nil, "not-authorized"; + elseif (script_type == "ejabberd" and response == "\0\2\0\1") or + (script_type == "generic" and response == "1") then + return true; + else + log("debug", "Nonsense back"); + return nil, "internal-server-error"; + end +end + +function new_external_provider(host) + local provider = { name = "external" }; + + function provider.test_password(username, password) + return do_query("auth", username, password); + end + + function provider.set_password(username, password) + return do_query("setpass", username, password); + end + + function provider.user_exists(username) + return do_query("isuser", username); + end + + function provider.create_user(username, password) return nil, "Account creation/modification not available."; end + + function provider.get_sasl_handler() + local testpass_authentication_profile = { + plain_test = function(sasl, username, password, realm) + return usermanager.test_password(username, realm, password), true; + end, + }; + return new_sasl(module.host, testpass_authentication_profile); + end + + function provider.is_admin(jid) + local admins = config.get(host, "admins"); + if admins ~= config.get("*", "admins") then + if type(admins) == "table" then + jid = jid_bare(jid); + for _,admin in ipairs(admins) do + if admin == jid then return true; end + end + elseif admins then + log("error", "Option 'admins' for host '%s' is not a table", host); + end + end + return usermanager.is_admin(jid); + end + + return provider; +end + +module:add_item("auth-provider", new_external_provider(host)); \ No newline at end of file diff --git a/install/apps/metronome_libs/mod_discoitems.lua b/install/apps/metronome_libs/mod_discoitems.lua new file mode 100644 index 0000000000..f05b904907 --- /dev/null +++ b/install/apps/metronome_libs/mod_discoitems.lua @@ -0,0 +1,24 @@ +-- * Metronome IM * +-- +-- This file is part of the Metronome XMPP server and is released under the +-- ISC License, please see the LICENSE file in this source package for more +-- information about copyright and licensing. +-- +-- As per the sublicensing clause, this file is also MIT/X11 Licensed. +-- ** Copyright (c) 2009, Waqas Hussain + +local st = require "util.stanza"; + +local result_query = st.stanza("query", {xmlns = "http://jabber.org/protocol/disco#items"}); +for _, item in ipairs(module:get_option("disco_items") or {}) do + result_query:tag("item", {jid = item[1], name = item[2]}):up(); +end + +module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) + local stanza = event.stanza; + local query = stanza.tags[1]; + if stanza.attr.type == "get" and not query.attr.node then + event.origin.send(st.reply(stanza):add_child(result_query)); + return true; + end +end, 100); diff --git a/install/apps/metronome_libs/mod_webpresence/icons/status_away.png b/install/apps/metronome_libs/mod_webpresence/icons/status_away.png new file mode 100644 index 0000000000000000000000000000000000000000..0de5c6ab3d35e958b2c2c9fa9ee6e5876312b54b GIT binary patch literal 948 zcmV;l155mgP)*sU#JepF9xjFpi<1dH&*($&0tPbjKK|H0#rd|Dym~9=~^ZBK- zbGzC-yt{5wxNLFa=+nzG+x(``0F-p`vJReOGa7fjv$t};?MarraO%VvcNXui+Z2Ab zc;a$-iMCXj7MgA_iya$jr;+Jt?!*%OIGopiF8Ofe)QK}n06Y?!`l`HGEfrP(JunY_ z-hA|64!S>xumT9vV)(9L$2UQWeX-IA18o4}z^<}w8;jE0HN%H6O@tM|2;`s#b7r8= zL}~^f{FF=A#VfSjSk9W9k)5wRU;d~tReD!A;0c646FQn$sd_VSuNx%j zgRqfWCh{z|P)SKD<KWE7c7kVzzXr!C3B<~Dx5(8b^{$JrjSQPKrq%GQK2KCMN^V(Eo_ z69sgBc#zhk&AfN=5T4Sg-+LI>b@`<6HI7sz@EivvB>=b6zNitieFOPsCi3F)5%$!- z%158J(5hf~=oafYJV{N}6YQ%PM|U$w#|A(ujS)LApodE$e};(HRTQN}bYzh4FaAw^ zLn9kDZf0-8>ud>LU_~g6m$Bi$H6Fi_uezgo^?L7LL!*bj{CdS>dE+Zr=GzSP_tAB2 zg7{>dp>qd#?x9Ik)&XYVU^2iL*9zKue!ae5Q%X@?vsEjyulLnPMoSm_GaS2`N6)au zk!Qx3S@}$Q<3T?AJv0;#7Og(t*&UlbMs>|rL);l?tGqw9qhiUFurwD#%%I7v$#?zp zRr}2ar~TpkYR`9e$Nu-Kds$nys?v{L`#_GpD%Z>wj!ye--@I#HmcrL@+$DHi3p2pKey{piC67(I&w7*W40lyU(UA}K6MAl4+&=mayV7(EwVeII`~vKc@F)NSI^K=n$$(jK%fMr$ux`_Q@w ztvrC6mKGZ=&2IMZjc+>e>c-Ci)aR|+cfYhRFZ_^awM}auHtj_z50J&OVp!IFPM^NP zh7Ipv7!D$lCj6DT^rderD|C5T?!}b_hD~9hZ~)8Dx)7xbP|8Jrf1GHviiU>0^!9e~ z>~m@AcO_lv*+jEpw`Xg?LdXGGAcJKkfh@`76sJzzrnB=$x_iE2b?I-^)L4jQC@sy@ z8Y`A(%0)7Cca2b7JWc&GPL#|87Dtc%z{!(m85l#>)q`(bi@lk^s^Gm)`U`9$H&3 z5R26j3U$!g*}+=>Ab~&%%Ss?J1;DML72KVmkKp@tzR0zrl$ls1hYwfE)vI9<5g8sH zlE%h$l1P?`nea&5R1!ClxQQHUD#`_F9^Q?J(DKpx(ESHmCS!T>+Uw;KiCmFAdmfR$ z#|tEGy8c6P6Y1(Mkag?Vek~#(B8UhdobdPE{>v`^M3H^_i{z)D^%4{}k)BI#*|OC) z`s7n}-X&N>c%!MR?cz6{`Fjs+OVGezo&?`5l&X#8;RPrn|G#RX&08M}EYF(_R#ePZ uFLPymqht2i$cXKxVRv2|?7#Kp;_bh*VwXTL_!Tn%0000`8bWHC5+ah88qqRn1%uG& zQcS>)O*AW4Ao#$6ck%vS9(bOkM1-CC@Ri0pd&=&tEz9Rq??+mg<*upy)XM9hfAsy2U+>&i z+wkexqr=ZOmp_|ougzo%B?uu1u8fpLU^&=$`-y#57AFs$xO#csKZZ}w937ro{^Rb8 z;n8@SX%eFW@GjCTBSpv4X$LxO&$oL=7k)eP+@Y(N=fwaVXs%v(!L`O~eTJ-_U~L7v zUPP%t41#xp>nW!Ge0XrJo?ilvC;sNOnU^;nelS>5Dz7KxeTI77VAJYAj6(2&_Yv;| z?;>`qeCCrIU(OrT-a0!Nz1G^I6NNFFTAmEG&1m_Fx5mtw+ua~GJNp2j(ca}MwQ ze`fDJpPoO@#@rkOJvVB$0wDw;#)!2RYc2n$4Cn_QD5cG&N>*y68$5URT|Uk;v;veu z0f-<1L_tJ|5!RaPoB>*?T`{dRTb%8=L$9tck=8WEYLY}DKn#NGRauwaK)2%&fv6Rm zefeUt|M1iIv*x2yL!Cm$P_?Scw1Rp?pezDK5!i0>cl-9r{o$eam56Y>G5N(C_ZE(2 zI+7S&S>KiMzx`jU=UjYh?Aon+zrU#g%E^fn*C)mo)|2!fd(|t8xC?yHU+2om@KQQ9 za%$JdcTCouZNV+~{U%S69;Xu4MMBpMUt};?CW_0VwBr-clcF`v3p{07*qoM6N<$g4nQ! A4FCWD literal 0 HcmV?d00001 diff --git a/install/apps/metronome_libs/mod_webpresence/icons/status_offline.png b/install/apps/metronome_libs/mod_webpresence/icons/status_offline.png new file mode 100644 index 0000000000000000000000000000000000000000..12db2af7dd86308f5abed00e3930d7f961e1ecc3 GIT binary patch literal 905 zcmV;419tq0P)DbaPEbUMxW_&6gYBRGzO@B5fW zFg`H!@q0C%>wm55hMLJ_n4FwsaBz_J_I5@`N3m_2?(S~l@i?heist5KbX`YEsU04d zzEKsFn*gy`jQRO_rlzLo=;&Z&Wrd!e9;TW3iqqHf*4 z0Yys5M|VH?-j3WD_B@YVE{CeBw6(RNX&S!oBZT1m{2br+sjV}4@y}mBZmp+>RDf{Q zdUSYP_(M^krKJViwh=<$y6zPq%d!Xr3|{2^&P5vP6IbuK{Oq}Gc&q+a;qc$3*X0Xg zS;04!CWOz+!-D)Xn^}oOt)5?g{`KgMRaJH8{o9`iUpz64z-?8jX>#4l%X0bkmRh5( fq&N4zyPo|Isjz3R!I6nX00000NkvXXu0mjf4oJCl literal 0 HcmV?d00001 diff --git a/install/apps/metronome_libs/mod_webpresence/icons/status_online.png b/install/apps/metronome_libs/mod_webpresence/icons/status_online.png new file mode 100644 index 0000000000000000000000000000000000000000..fb257c3144736fd691d81ac82242f7d51f909679 GIT binary patch literal 920 zcmV;J184k+P)vhH8 z7nhD)JG**T`48N8ct_-JduBA-GrtSJ*LNKkX-S-#gD>Ng8!xW^=Fz{}UK=}k#$EyU zy}cun>iPR>;fZ3i&;>#j07zRRmnC-9#xWi2tj)%2(LcLV+qRCKJmU(0+16ZQv8&Lm z8Y)^qL#um`K@HVVQFRq1uMi##GaJse-D*so01(^X@7|T|ntNGj0-+03zxohR=mLSD zd9<0ypC{=U?;ySD-mAT@Kl_v@iPB*!WD7+oC_+JK!ecX36wT|^e_l^wFo9thl&vyL zttEBN&3~X(0<|r;;JPljcp@!Jz^lc$VBeN~#Cl@%?dfBB_cRz#4w|jPsmMbs54XP*)KmE?U-*_*jCwG;dbga3l|qyyuZlsm0=3c6;{*-2+RkF{_wH0Cjj3Dz^v<@`LN&rag)ycKGH+!-`QHe2cY{REu1UALo4Y5@CG#uBi0|F0 z{ZUSxn0q|`O5w4Buv8mV4`i4+4Zk+Hk6a3Uzo~J<{)uzR{6nrnu(-ldf@P|izNq=lxIHpFLiWTEVPV4m}8 zntOR)j+04Pq>?7Nti#ytMR7T4W1BgLoMB^R9O`6)^u=kS(I^1HV34loc5sjYhUH+J z*Q?W#B)e*Zfu1#~R1gV-fKLq{kvHDqflUp(*wck!7<4`T41rK3@BVO-yBFekfXTvw zStYJ&Guez?0dU&!ptrTry0x9p4t_-5&)@UY$zdi&M%c6e0Cyh$k>>h(cFxCG)V(uO zb{CXi)%+(Ath; z8KdUG*(>GS&R-zG^+k+jCnyFk=V=@*TrsPb6m7rd7_IG%O7`5$;qcX1+xmsLteVzM zG3`+q59Eu90{^l6J63m}7(NxdMZS@m`@)YZnQV7aIve)p%;H7WJ$F@ACxzzzcIvl3 c`]].. + tostring( + stanza("html") + :tag("head") + :tag("title"):text("XMPP Status Page for "..jid):up():up() + :tag("body") + :tag("div", { id = jid_hash.."_status", class = "xmpp_status" }) + :tag("img", { id = jid_hash.."_img", class = "xmpp_status_image xmpp_status_"..status, + src = "data:image/png;base64,"..b64(require_resource("status_"..status..".png")) }):up() + :tag("span", { id = jid_hash.."_status_name", class = "xmpp_status_name" }) + :text("\194\160"..status):up() + :tag("span", { id = jid_hash.."_status_message", class = "xmpp_status_message" }) + :text(message and "\194\160"..message.."" or "") + ) + }; + end; + statuses[status].text = function() + return { status_code = 200, headers = { content_type = "text/plain" }, + body = status + }; + end; + statuses[status].message = function() + return { status_code = 200, headers = { content_type = "text/plain" }, + body = (message and message or "") + }; + end; + statuses[status].json = function() + return { status_code = 200, headers = { content_type = "application/json" }, + body = json({ + jid = jid, + show = status, + status = (message and message or "null") + }) + }; + end; + statuses[status].xml = function() + return { status_code = 200, headers = { content_type = "application/xml" }, + body = [[]].. + tostring( + stanza("result") + :tag("jid"):text(jid):up() + :tag("show"):text(status):up() + :tag("status"):text(message) + ) + }; + end + + if ((type == "") or (not statuses[status][type])) then + type = "image" + end; + + return statuses[status][type](); +end + +module:provides("http", { + default_path = "/status"; + route = { + ["GET /*"] = handle_request; + }; +}); diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index a3819966b9..e18faa4967 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -222,5 +222,9 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; +//* Metronome XMPP +$conf['xmpp']['installed'] = false; +$conf['xmpp']['init_script'] = 'metronome'; + ?> diff --git a/install/dist/lib/debian60.lib.php b/install/dist/lib/debian60.lib.php index 584e6aa91c..fab5628a77 100644 --- a/install/dist/lib/debian60.lib.php +++ b/install/dist/lib/debian60.lib.php @@ -154,6 +154,10 @@ class installer extends installer_base { */ } + public function configure_xmpp() { + parent::configure_xmpp(); + } + } ?> diff --git a/install/install.php b/install/install.php index 91759f2284..3aedfefa85 100644 --- a/install/install.php +++ b/install/install.php @@ -347,6 +347,13 @@ if($install_mode == 'standard') { } */ + //* Configure XMPP + if($conf['xmpp']['installed'] == true){ + $conf['services']['xmpp'] = true; + swriteln('Configuring Metronome XMPP Server'); + $inst->configure_xmpp(); + } + //* Configure ISPConfig swriteln('Installing ISPConfig'); @@ -398,6 +405,7 @@ if($install_mode == 'standard') { //if($conf['squid']['installed'] == true && $conf['squid']['init_script'] != '' && is_file($conf['init_scripts'].'/'.$conf['squid']['init_script'])) system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); if($conf['nginx']['installed'] == true && $conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'restart').' &> /dev/null'); if($conf['ufw']['installed'] == true && $conf['ufw']['init_script'] != '') system($inst->getinitcommand($conf['ufw']['init_script'], 'restart').' &> /dev/null'); + if($conf['xmpp']['installed'] == true && $conf['xmpp']['init_script'] != '') system($inst->getinitcommand($conf['xmpp']['init_script'], 'restart').' &> /dev/null'); } else { @@ -408,6 +416,7 @@ if($install_mode == 'standard') { $conf['services']['db'] = true; $conf['services']['firewall'] = false; $conf['services']['proxy'] = false; + $conf['services']['xmpp'] = false; //** Get Server ID @@ -639,6 +648,16 @@ if($install_mode == 'standard') { $inst->configure_firewall(); }*/ + //** Configure XMPP + if($conf['xmpp']['installed'] == true){ + if(strtolower($inst->simple_query('Configure Metronome XMPP Server', array('y', 'n'), 'y', 'configure_xmpp')) == 'y'){ + $conf['services']['xmpp'] = true; + swriteln('Configuring Metronome XMPP Server'); + $inst->configure_xmpp(); + if($conf['xmpp']['installed'] == true && $conf['xmpp']['init_script'] != '') system($inst->getinitcommand($conf['xmpp']['init_script'], 'restart').' &> /dev/null'); + } + } + //** Configure ISPConfig :-) $install_ispconfig_interface_default = ($conf['mysql']['master_slave_setup'] == 'y')?'n':'y'; if(strtolower($inst->simple_query('Install ISPConfig Web Interface', array('y', 'n'), $install_ispconfig_interface_default,'install_ispconfig_web_interface')) == 'y') { diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index ae64463c17..688cfdb6ef 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -155,6 +155,7 @@ class installer_base { if(is_installed('fail2ban-server')) $conf['fail2ban']['installed'] = true; if(is_installed('vzctl')) $conf['openvz']['installed'] = true; if(is_dir("/etc/Bastille")) $conf['bastille']['installed'] = true; + if(is_installed('metronome') && is_installed('metronomectl')) $conf['xmpp']['installed'] = true; if ($conf['services']['web'] && (($conf['apache']['installed'] && is_file($conf['apache']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost")) || ($conf['nginx']['installed'] && is_file($conf['nginx']["vhost_conf_enabled_dir"]."/000-ispconfig.vhost")))) $this->ispconfig_interface_installed = true; } @@ -1308,6 +1309,66 @@ class installer_base { } + public function configure_xmpp() { + global $conf; + + if($conf['xmpp']['installed'] == false) return; + //* Create the logging directory for xmpp server + if(!@is_dir('/var/log/metronome')) mkdir('/var/log/metronome', 0755, true); + chown('/var/log/metronome', 'metronome'); + if(!@is_dir('/var/run/metronome')) mkdir('/var/run/metronome', 0755, true); + chown('/var/run/metronome', 'metronome'); + if(!@is_dir('/var/lib/metronome')) mkdir('/var/lib/metronome', 0755, true); + chown('/var/lib/metronome', 'metronome'); + if(!@is_dir('/etc/metronome/hosts')) mkdir('/etc/metronome/hosts', 0755, true); + if(!@is_dir('/etc/metronome/status')) mkdir('/etc/metronome/status', 0755, true); + unlink('/etc/metronome/metronome.cfg.lua'); + + $row = $this->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".$conf["server_id"].""); + $server_name = $row["server_name"]; + + $tpl = new tpl('metronome_conf_main.master'); + wf('/etc/metronome/metronome.cfg.lua', $tpl->grab()); + unset($tpl); + + $tpl = new tpl('metronome_conf_global.master'); + $tpl->setVar('xmpp_admins',''); + wf('/etc/metronome/global.cfg.lua', $tpl->grab()); + unset($tpl); + + // Copy isp libs + if(!@is_dir('/usr/lib/metronome/isp-modules')) mkdir('/usr/lib/metronome/isp-modules', 0755, true); + caselog('cp -rf apps/metronome_libs/* /usr/lib/metronome/isp-modules/', __FILE__, __LINE__); + + // Copy init script + caselog('cp -f apps/metronome-init /etc/init.d/metronome', __FILE__, __LINE__); + caselog('chmod u+x /etc/init.d/metronome', __FILE__, __LINE__); + + exec($this->getinitcommand('xmpp', 'restart')); + + + + /*// Dont just copy over the virtualhost template but add some custom settings + $tpl = new tpl('apache_apps.vhost.master'); + + $tpl->setVar('apps_vhost_port',$conf['web']['apps_vhost_port']); + $tpl->setVar('apps_vhost_dir',$conf['web']['website_basedir'].'/apps'); + $tpl->setVar('apps_vhost_basedir',$conf['web']['website_basedir']); + $tpl->setVar('apps_vhost_servername',$apps_vhost_servername); + $tpl->setVar('apache_version',getapacheversion()); + + + // comment out the listen directive if port is 80 or 443 + if($conf['web']['apps_vhost_ip'] == 80 or $conf['web']['apps_vhost_ip'] == 443) { + $tpl->setVar('vhost_port_listen','#'); + } else { + $tpl->setVar('vhost_port_listen',''); + } + + wf($vhost_conf_dir.'/apps.vhost', $tpl->grab()); + unset($tpl);*/ + } + public function configure_apache() { global $conf; @@ -1969,8 +2030,9 @@ class installer_base { $vserver_server_enabled = ($conf['openvz']['installed'])?1:0; $proxy_server_enabled = ($conf['services']['proxy'])?1:0; $firewall_server_enabled = ($conf['services']['firewall'])?1:0; + $xmpp_server_enabled = ($conf['services']['xmpp'])?1:0; - $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled' WHERE server_id = ".intval($conf['server_id']); + $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled', xmpp_server = '.$xmpp_server_enabled.' WHERE server_id = ".intval($conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { $this->dbmaster->query($sql); diff --git a/install/sql/incremental/upd_0081.sql b/install/sql/incremental/upd_0081.sql new file mode 100644 index 0000000000..f525e7295f --- /dev/null +++ b/install/sql/incremental/upd_0081.sql @@ -0,0 +1,55 @@ +ALTER TABLE `server` ADD COLUMN `xmpp_server` tinyint(1) NOT NULL default '0' AFTER `firewall_server`; + +ALTER TABLE `client` + ADD COLUMN `limit_xmpp_domain` int(11) NOT NULL DEFAULT '-1', + ADD COLUMN `limit_xmpp_user` int(11) NOT NULL DEFAULT '-1', + ADD COLUMN `limit_xmpp_muc` ENUM( 'n', 'y' ) NOT NULL default 'n', + ADD COLUMN `limit_xmpp_anon` ENUM( 'n', 'y' ) NOT NULL default 'n', + ADD COLUMN `limit_xmpp_auth_options` varchar(255) NOT NULL DEFAULT 'plain,hashed,isp', + ADD COLUMN `limit_xmpp_vjud` ENUM( 'n', 'y' ) NOT NULL default 'n', + ADD COLUMN `limit_xmpp_proxy` ENUM( 'n', 'y' ) NOT NULL default 'n', + ADD COLUMN `limit_xmpp_status` ENUM( 'n', 'y' ) NOT NULL default 'n', + ADD COLUMN `limit_xmpp_pastebin` ENUM( 'n', 'y' ) NOT NULL default 'n', + ADD COLUMN `limit_xmpp_httparchive` ENUM( 'n', 'y' ) NOT NULL default 'n'; + + +CREATE TABLE `xmpp_domain` ( + `domain_id` int(11) unsigned NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) NOT NULL default '', + `sys_perm_group` varchar(5) NOT NULL default '', + `sys_perm_other` varchar(5) NOT NULL default '', + `server_id` int(11) unsigned NOT NULL default '0', + `domain` varchar(255) NOT NULL default '', + + `auth_method` ENUM( 'isp', 'plain', 'hashed' ) NOT NULL default 'hashed', + `public_registration` ENUM( 'n', 'y' ) NOT NULL default 'n', + `registration_url` varchar(255) NOT NULL DEFAULT '', + `registration_message` varchar(255) NOT NULL DEFAULT '', + `domain_admins` text, + + `use_pubsub` enum('n','y') NOT NULL DEFAULT 'n', + `use_proxy` enum('n','y') NOT NULL DEFAULT 'n', + `use_anon_host` enum('n','y') NOT NULL DEFAULT 'n', + + `use_vjud` enum('n','y') NOT NULL DEFAULT 'n', + `vjud_opt_mode` enum('in', 'out') NOT NULL DEFAULT 'in', + + `use_muc_host` enum('n','y') NOT NULL DEFAULT 'n', + `muc_name` varchar(30) NOT NULL DEFAULT '' + `muc_restrict_room_creation` enum('n', 'y', 'm') NOT NULL DEFAULT 'm', + `muc_admins` text, + `use_pastebin` enum('n','y') NOT NULL DEFAULT 'n', + `pastebin_expire_after` int(3) NOT NULL DEFAULT 48, + `pastebin_trigger` varchar(10) NOT NULL DEFAULT '!paste', + `use_http_archive` enum('n','y') NOT NULL DEFAULT 'n', + `http_archive_show_join` enum('n', 'y') NOT NULL DEFAULT 'n', + `http_archive_show_status` enum('n', 'y') NOT NULL DEFAULT 'n', + `use_status_host` enum('n','y') NOT NULL DEFAULT 'n', + + `active` enum('n','y') NOT NULL DEFAULT 'n', + PRIMARY KEY (`domain_id`), + KEY `server_id` (`server_id`,`domain`), + KEY `domain_active` (`domain`,`active`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; \ No newline at end of file diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 8b791657f9..1f5b4180f9 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -184,6 +184,16 @@ CREATE TABLE `client` ( `limit_spamfilter_wblist` int(11) NOT NULL DEFAULT '0', `limit_spamfilter_user` int(11) NOT NULL DEFAULT '0', `limit_spamfilter_policy` int(11) NOT NULL DEFAULT '0', + `limit_xmpp_domain` int(11) NOT NULL DEFAULT '-1', + `limit_xmpp_user` int(11) NOT NULL DEFAULT '-1', + `limit_xmpp_muc` ENUM( 'n', 'y' ) NOT NULL default 'n', + `limit_xmpp_anon` ENUM( 'n', 'y' ) NOT NULL default 'n', + `limit_xmpp_auth_options` varchar(255) NOT NULL DEFAULT 'plain,hashed,isp', + `limit_xmpp_vjud` ENUM( 'n', 'y' ) NOT NULL default 'n', + `limit_xmpp_proxy` ENUM( 'n', 'y' ) NOT NULL default 'n', + `limit_xmpp_status` ENUM( 'n', 'y' ) NOT NULL default 'n', + `limit_xmpp_pastebin` ENUM( 'n', 'y' ) NOT NULL default 'n', + `limit_xmpp_httparchive` ENUM( 'n', 'y' ) NOT NULL default 'n', `default_webserver` int(11) unsigned NOT NULL DEFAULT '1', `web_servers` blob, `limit_web_ip` text, @@ -1201,6 +1211,7 @@ CREATE TABLE `server` ( `vserver_server` tinyint(1) NOT NULL default '0', `proxy_server` tinyint(1) NOT NULL default '0', `firewall_server` tinyint(1) NOT NULL default '0', + `xmpp_server` tinyint(1) NOT NULL default '0', `config` text, `updated` bigint(20) unsigned NOT NULL default '0', `mirror_server_id` int(11) unsigned NOT NULL default '0', @@ -1950,6 +1961,54 @@ CREATE TABLE `web_traffic` ( PRIMARY KEY (`hostname`,`traffic_date`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; +-- -------------------------------------------------------- + +-- +-- Table structure for table `xmpp_domain` +-- + +CREATE TABLE `xmpp_domain` ( + `domain_id` int(11) unsigned NOT NULL auto_increment, + `sys_userid` int(11) unsigned NOT NULL default '0', + `sys_groupid` int(11) unsigned NOT NULL default '0', + `sys_perm_user` varchar(5) NOT NULL default '', + `sys_perm_group` varchar(5) NOT NULL default '', + `sys_perm_other` varchar(5) NOT NULL default '', + `server_id` int(11) unsigned NOT NULL default '0', + `domain` varchar(255) NOT NULL default '', + + `auth_method` ENUM( 'isp', 'plain', 'hashed' ) NOT NULL default 'hashed', + `public_registration` ENUM( 'n', 'y' ) NOT NULL default 'n', + `registration_url` varchar(255) NOT NULL DEFAULT '', + `registration_message` varchar(255) NOT NULL DEFAULT '', + `domain_admins` text, + + `use_pubsub` enum('n','y') NOT NULL DEFAULT 'n', + `use_proxy` enum('n','y') NOT NULL DEFAULT 'n', + `use_anon_host` enum('n','y') NOT NULL DEFAULT 'n', + + `use_vjud` enum('n','y') NOT NULL DEFAULT 'n', + `vjud_opt_mode` enum('in', 'out') NOT NULL DEFAULT 'in', + + `use_muc_host` enum('n','y') NOT NULL DEFAULT 'n', + `muc_name` varchar(30) NOT NULL DEFAULT '', + `muc_restrict_room_creation` enum('n', 'y', 'm') NOT NULL DEFAULT 'm', + `muc_admins` text, + `use_pastebin` enum('n','y') NOT NULL DEFAULT 'n', + `pastebin_expire_after` int(3) NOT NULL DEFAULT 48, + `pastebin_trigger` varchar(10) NOT NULL DEFAULT '!paste', + `use_http_archive` enum('n','y') NOT NULL DEFAULT 'n', + `http_archive_show_join` enum('n', 'y') NOT NULL DEFAULT 'n', + `http_archive_show_status` enum('n', 'y') NOT NULL DEFAULT 'n', + `use_status_host` enum('n','y') NOT NULL DEFAULT 'n', + + `active` enum('n','y') NOT NULL DEFAULT 'n', + PRIMARY KEY (`domain_id`), + KEY `server_id` (`server_id`,`domain`), + KEY `domain_active` (`domain`,`active`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + + -- -------------------------------------------------------- -- -------------------------------------------------------- -- DB-DATA diff --git a/install/tpl/metronome_conf_global.master b/install/tpl/metronome_conf_global.master new file mode 100644 index 0000000000..68f4c59b6b --- /dev/null +++ b/install/tpl/metronome_conf_global.master @@ -0,0 +1,65 @@ +pidfile = "/var/run/metronome/metronome.pid"; +metronome_max_files_soft = 200000; +metronome_max_files_hard = 300000; +plugin_paths = { + "/usr/lib/metronome/isp-modules", +}; +use_libevent = true; +log = { + debug = "/var/log/metronome/metronome.dbg", + info = "/var/log/metronome/metronome.log", + error = "/var/log/metronome/metronome.err", +}; +use_ipv6 = true; +http_ports = { + 5290, +}; +https_ports = { + 5291, +}; +pastebin_ports = { + 5292, +}; +bosh_ports = { + 5280, +}; +admins = { + {tmpl_var xmpp_admins} +}; +modules_enabled = { + "saslauth", + "tls", + "dialback", + "disco", + "discoitems", + "version", + "uptime", + "time", + "ping", + "admin_adhoc", + "admin_telnet", + "bosh", + "posix", + "announce", + "offline", + "webpresence", + "mam", + "stream_management", + "message_carbons" +}; +modules_disabled = { +}; +bosh_max_inactivity = 30; +consider_bosh_secure = true; +cross_domain_bosh = true; +allow_registration = false; +ssl = { + key = "/etc/metronome/certs/localhost.key", + certificate = "/etc/metronome/certs/localhost.cert", +}; +c2s_require_encryption = false; +s2s_secure = true; +s2s_insecure_domains = { + "gmail.com", +}; +authentication = "internal_plain"; diff --git a/install/tpl/metronome_conf_main.master b/install/tpl/metronome_conf_main.master new file mode 100644 index 0000000000..f9c8fbdd65 --- /dev/null +++ b/install/tpl/metronome_conf_main.master @@ -0,0 +1,3 @@ +Include "/etc/metronome/global.cfg.lua" +Include "/etc/metronome/hosts/*.lua" +Include "/etc/metronome/status/*.lua" diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 7805988a71..20dca2d42f 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -145,3 +145,12 @@ do_not_try_rescue_httpd=n do_not_try_rescue_mysql=n do_not_try_rescue_mail=n +[xmpp] +xmpp_use_ispv6=n +xmpp_bosh_max_inactivity=30 +xmpp_server_admins=admin@service.com, superuser@service.com +xmpp_modules_enabled=saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons +xmpp_port_http=5290 +xmpp_port_https=5291 +xmpp_port_pastebin=5292 +xmpp_port_bosh=5280 diff --git a/interface/web/admin/form/server.tform.php b/interface/web/admin/form/server.tform.php index a2eac6c3b7..1bf079e1b0 100644 --- a/interface/web/admin/form/server.tform.php +++ b/interface/web/admin/form/server.tform.php @@ -102,6 +102,12 @@ $form["tabs"]['services'] = array ( 'default' => '0', 'value' => array(0 => 0, 1 => 1) ), + 'xmpp_server' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'CHECKBOX', + 'default' => '0', + 'value' => array(0 => 0, 1 => 1) + ), 'mirror_server_id' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 6f1c889bb5..351d4de86c 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1318,6 +1318,86 @@ $form["tabs"]['fastcgi'] = array( ); +$form["tabs"]['xmpp'] = array( + 'title' => "XMPP", + 'width' => 80, + 'template' => "templates/server_config_xmpp_edit.htm", + 'fields' => array( + //################################# + // Begin Datatable fields + //################################# + 'xmpp_use_ipv6' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'xmpp_bosh_max_inactivity' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '30', + 'validators' => array(0 => array('type' => 'ISINT', + 'errmsg' => 'ip_address_error_wrong'), + array('type'=>'RANGE', 'range'=>'15:360', 'errmsg' => 'xmpp_bosh_timeout_range_wrong') + ), + 'value' => '', + 'width' => '15' + ), + + 'xmpp_server_admins' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'admin@service.com, superuser@service.com', + 'value' => '', + 'width' => '15' + ), + + 'xmpp_modules_enabled' => array( + 'datatype' => 'TEXT', + 'formtype' => 'TEXT', + 'default' => "saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons", + 'value' => '', + 'separator' => "," + ), + + 'xmpp_port_http' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '5290', + 'validators' => array(0 => array('type' => 'ISINT')), + 'value' => '5290', + 'width' => '15' + ), + 'xmpp_port_https' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '5291', + 'validators' => array(0 => array('type' => 'ISINT')), + 'value' => '5291', + 'width' => '15' + ), + 'xmpp_port_pastebin' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '5292', + 'validators' => array(0 => array('type' => 'ISINT')), + 'value' => '5292', + 'width' => '15' + ), + 'xmpp_port_bosh' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '5280', + 'validators' => array(0 => array('type' => 'ISINT')), + 'value' => '5280', + 'width' => '15' + ), + //################################# + // ENDE Datatable fields + //################################# + ) +); + $form["tabs"]['jailkit'] = array( 'title' => "Jailkit", 'width' => 80, diff --git a/interface/web/admin/lib/lang/en_server.lng b/interface/web/admin/lib/lang/en_server.lng index 4130201b7c..1f36bc718e 100644 --- a/interface/web/admin/lib/lang/en_server.lng +++ b/interface/web/admin/lib/lang/en_server.lng @@ -12,4 +12,6 @@ $wb["firewall_server_txt"] = 'Firewall-Server'; $wb["active_txt"] = 'Active'; $wb["mirror_server_id_txt"] = 'Is mirror of Server'; $wb["- None -"] = '- None -'; +// New for XMPP +$wb['xmpp_server_txt'] = 'XMPP Server'; ?> \ No newline at end of file diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index 8affba0c14..aac7390659 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -264,4 +264,18 @@ $wb['php_ini_check_minutes_txt'] = 'Check php.ini every X minutes for changes'; $wb['php_ini_check_minutes_error_empty'] = 'Please specify a value how often php.ini should be checked for changes.'; $wb['php_ini_check_minutes_info_txt'] = '0 = no check'; $wb['enable_spdy_txt'] = 'Makes SPDY available'; + +// New for XMPP +$wb['xmpp_server_txt'] = 'XMPP Server'; +$wb['xmpp_use_ipv6_txt'] = 'Use IPv6'; +$wb['xmpp_bosh_max_inactivity_txt'] = 'Max. BOSH inactivity time'; +$wb['xmpp_bosh_timeout_range_wrong'] = 'Please enter a bosh timeout range between 15 - 360'; +$wb['xmpp_module_saslauth'] = 'saslauth'; +$wb['xmpp_server_admins_txt'] = 'Server Admins (JIDs)'; +$wb['xmpp_modules_enabled_txt'] = 'Serverwide enabled plugins (one per line)'; +$wb['xmpp_ports_txt'] = 'Component ports'; +$wb['xmpp_port_http_txt'] = 'HTTP'; +$wb['xmpp_port_https_txt'] = 'HTTPS'; +$wb['xmpp_port_pastebin_txt'] = 'Pastebin'; +$wb['xmpp_port_bosh_txt'] = 'BOSH'; ?> diff --git a/interface/web/admin/lib/lang/en_server_list.lng b/interface/web/admin/lib/lang/en_server_list.lng index 164468e700..89a81fa43b 100644 --- a/interface/web/admin/lib/lang/en_server_list.lng +++ b/interface/web/admin/lib/lang/en_server_list.lng @@ -10,4 +10,6 @@ $wb["vserver_server_txt"] = 'VServer'; $wb["proxy_server_txt"] = 'Proxy'; $wb["firewall_server_txt"] = 'Firewall'; $wb["add_new_record_txt"] = 'Add new Server'; +// New for XMPP +$wb['xmpp_server_txt'] = 'XMPP'; ?> \ No newline at end of file diff --git a/interface/web/admin/list/server.list.php b/interface/web/admin/list/server.list.php index 0309b7a3c1..0290632405 100644 --- a/interface/web/admin/list/server.list.php +++ b/interface/web/admin/list/server.list.php @@ -110,4 +110,13 @@ $liste['item'][] = array( 'field' => 'vserver_server', 'width' => '', 'value' => array('1' => "
Yes
", '0' => "
No
")); +$liste['item'][] = array( 'field' => 'xmpp_server', + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'op' => 'like', + 'prefix' => '%', + 'suffix' => '%', + 'width' => '', + 'value' => array('1' => "
Yes
", '0' => "
No
")); + ?> diff --git a/interface/web/admin/templates/server_config_xmpp_edit.htm b/interface/web/admin/templates/server_config_xmpp_edit.htm new file mode 100644 index 0000000000..acf019b9ff --- /dev/null +++ b/interface/web/admin/templates/server_config_xmpp_edit.htm @@ -0,0 +1,73 @@ + +

+ + + +
+ +
+ {tmpl_var name='xmpp_use_ipv6'} +
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
+
+

{tmpl_var name='xmpp_ports_txt'}

+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ + + +
+ + +
diff --git a/interface/web/admin/templates/server_edit_services.htm b/interface/web/admin/templates/server_edit_services.htm index aca706a0f7..4a648f4591 100644 --- a/interface/web/admin/templates/server_edit_services.htm +++ b/interface/web/admin/templates/server_edit_services.htm @@ -44,6 +44,12 @@ {tmpl_var name='vserver_server'} +
+ +
+ {tmpl_var name='xmpp_server'} +
+
{tmpl_var name='search_file_server'} + @@ -41,6 +43,7 @@ {tmpl_var name="file_server"} {tmpl_var name="db_server"} {tmpl_var name="vserver_server"} + {tmpl_var name="xmpp_server"} diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index 8d2ce89855..b5bf002b21 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -773,6 +773,106 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), + 'xmpp_servers' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'MULTIPLE', + 'separator' => ',', + 'default' => '1', + 'datasource' => array ( 'type' => 'CUSTOM', + 'class'=> 'custom_datasource', + 'function'=> 'client_servers' + ), + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'no_xmpp_server_error'), + 1 => array ( 'type' => 'CUSTOM', + 'class' => 'validate_client', + 'function' => 'check_used_servers', + 'errmsg'=> 'xmpp_servers_used'), + ), + 'value' => '', + 'name' => 'xmpp_servers' + ), + 'limit_xmpp_domain' => array( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'validators' => array ( 0 => array ( 'type' => 'ISINT', + 'errmsg'=> 'limit_xmpp_domain_error_notint'), + ), + 'default' => '-1', + 'value' => '', + 'separator' => '', + 'width' => '10', + 'maxlength' => '10', + 'rows' => '', + 'cols' => '' + ), + 'limit_xmpp_user' => array( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'validators' => array ( 0 => array ( 'type' => 'ISINT', + 'errmsg'=> 'limit_xmpp_user_error_notint'), + ), + 'default' => '-1', + 'value' => '', + 'separator' => '', + 'width' => '10', + 'maxlength' => '10', + 'rows' => '', + 'cols' => '' + ), + 'limit_xmpp_muc' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'limit_xmpp_anon' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'limit_xmpp_auth_options' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOXARRAY', + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'xmpp_auth_options_notempty'), + ), + 'default' => '', + 'separator' => ',', + 'valuelimit' => 'client:xmpp_auth_options', + 'value' => array('plain' => 'Plain', 'hashed' => 'Hashed', 'isp' => 'By Mail Account') + ), + 'limit_xmpp_vjud' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'limit_xmpp_proxy' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'limit_xmpp_status' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'limit_xmpp_pastebin' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'limit_xmpp_httparchive' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), 'default_webserver' => array ( 'datatype' => 'INTEGER', 'formtype' => 'SELECT', diff --git a/interface/web/client/lib/lang/en_client.lng b/interface/web/client/lib/lang/en_client.lng index e7e634bf08..786bd7cae2 100644 --- a/interface/web/client/lib/lang/en_client.lng +++ b/interface/web/client/lib/lang/en_client.lng @@ -132,6 +132,7 @@ $wb["bank_account_iban_txt"] = 'IBAN'; $wb["bank_account_swift_txt"] = 'BIC / Swift'; $wb["web_limits_txt"] = 'Web Limits'; $wb["email_limits_txt"] = 'Email Limits'; +$wb["xmpp_limits_txt"] = 'XMPP Limits'; $wb["database_limits_txt"] = 'Database Limits'; $wb["cron_job_limits_txt"] = 'Cron Job Limits'; $wb["dns_limits_txt"] = 'DNS Limits'; @@ -170,6 +171,26 @@ $wb["mail_servers_txt"] = 'Mailservers'; $wb["mail_servers_placeholder"] = 'Select mailservers'; $wb['no_mail_server_error'] = 'At least one mailserver must be selected.'; $wb['mail_servers_used'] = 'The server you are trying to remove from this client is used as a Mailserver. Be sure that this server is not used by this client before you remove it.'; + +$wb["xmpp_servers_txt"] = 'XMPP Servers'; +$wb["xmpp_servers_placeholder"] = 'Select XMPP Servers'; +$wb['no_xmpp_server_error'] = 'At least one XMPP Server must be selected.'; +$wb['xmpp_servers_used'] = 'The server you are trying to remove from this client is used as a XMPP Server. Be sure that this server is not used by this client before you remove it.'; +$wb['limit_xmpp_domain_error_notint'] = 'The XMPP domain limit must be a number.'; +$wb['limit_xmpp_user_error_notint'] = 'The XMPP user limit must be a number.'; +$wb['xmpp_auth_options_notempty'] = 'At least one XMPP auth method must be selected.'; +$wb['limit_xmpp_domain_txt'] = 'Max. number of XMPP domains'; +$wb['limit_xmpp_user_txt'] = 'Max. number of XMPP accounts'; +$wb['xmpp_auth_options_txt'] = 'Available Auth options'; +$wb['limit_xmpp_muc_txt'] = 'Multiuser chat available'; +$wb['limit_xmpp_pastebin_txt'] = 'Pastebin for MUC available'; +$wb['limit_xmpp_httparchive_txt'] = 'HTTP archive for MUC available'; +$wb['limit_xmpp_anon_txt'] = 'Anonymous host available'; +$wb['limit_xmpp_vjud_txt'] = 'VJUD user directory available'; +$wb['limit_xmpp_proxy_txt'] = 'Bytestream proxy available'; +$wb['limit_xmpp_status_txt'] = 'Status host available'; + + $wb['added_by_txt'] = 'Added by'; $wb['added_date_txt'] = 'Added date'; $wb['parent_client_id_txt'] = 'Client of reseller'; diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index b0dc73c144..ffb1708adc 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -209,6 +209,70 @@
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+ {tmpl_var name='xmpp_auth_options'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_muc'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_pastebin'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_httparchive'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_anon'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_vjud'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_proxy'} +
+
+
+ +
+ {tmpl_var name='limit_xmpp_status'} +
+
+ +
diff --git a/interface/web/js/xmpp_domain_muc.js b/interface/web/js/xmpp_domain_muc.js new file mode 100644 index 0000000000..90189288e8 --- /dev/null +++ b/interface/web/js/xmpp_domain_muc.js @@ -0,0 +1,26 @@ +$('document').ready(function(){ + $('#use_muc_host').on('change', function(e){ + if($(this).is(':checked')){ + $('#toggle-use-muc').addClass('in'); + $('#use_pastebin').trigger('change'); + $('#use_http_archive').trigger('change'); + }else{ + $('#toggle-use-muc').removeClass('in'); + } + }); + $('#use_pastebin').on('change', function(e){ + if($(this).is(':checked')){ + $('#toggle-use-pastebin').addClass('in'); + }else{ + $('#toggle-use-pastebin').removeClass('in'); + } + }); + $('#use_http_archive').on('change', function(e){ + if($(this).is(':checked')){ + $('#toggle-use-archive').addClass('in'); + }else{ + $('#toggle-use-archive').removeClass('in'); + } + }); + $('#use_muc_host').trigger('change'); +}) \ No newline at end of file diff --git a/interface/web/js/xmpp_domain_registration.js b/interface/web/js/xmpp_domain_registration.js new file mode 100644 index 0000000000..bde0874dc7 --- /dev/null +++ b/interface/web/js/xmpp_domain_registration.js @@ -0,0 +1,25 @@ +$('document').ready(function(){ + $('#auth_method').on('select2-selecting', function(e){ + val = e.choice ? e.choice.id : e.target.selectedIndex; + if(val == 2){ + //Mailbox + $('#toggle-auth-internal').removeClass('in'); + $('#toggle-registration-closed').removeClass('in'); + }else if(val != undefined){ + $('#toggle-auth-internal').addClass('in'); + $('#public_registration').trigger('change'); + }else{ + $('#toggle-auth-internal').removeClass('in'); + $('#toggle-registration-closed').removeClass('in'); + } + }); + $('#public_registration').on('change', function(e){ + if($(this).is(':checked')){ + $('#toggle-registration-closed').removeClass('in'); + }else{ + $('#toggle-registration-closed').addClass('in'); + } + }); + $('#public_registration').trigger('change'); + $('#auth_method').trigger('select2-selecting'); +}) \ No newline at end of file diff --git a/interface/web/mail/form/xmpp_domain.tform.php b/interface/web/mail/form/xmpp_domain.tform.php new file mode 100644 index 0000000000..cc1765f3cc --- /dev/null +++ b/interface/web/mail/form/xmpp_domain.tform.php @@ -0,0 +1,284 @@ + 0 id must match with id of current user +$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user +$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete +$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete +$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete + +$form["tabs"]['domain'] = array ( + 'title' => "Domain", + 'width' => 100, + 'template' => "templates/xmpp_domain_edit.htm", + 'fields' => array ( + //################################# + // Begin Datatable fields + //################################# + 'server_id' => array ( + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', + 'default' => '', + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT server_id,server_name FROM server WHERE xmpp_server = 1 AND mirror_server_id = 0 AND {AUTHSQL} ORDER BY server_name', + 'keyfield'=> 'server_id', + 'valuefield'=> 'server_name' + ), + 'value' => '' + ), + 'domain' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'filters' => array( 0 => array( 'event' => 'SAVE', + 'type' => 'IDNTOASCII'), + 1 => array( 'event' => 'SHOW', + 'type' => 'IDNTOUTF8'), + 2 => array( 'event' => 'SAVE', + 'type' => 'TOLOWER') + ), + 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', + 'errmsg'=> 'domain_error_empty'), + 1 => array ( 'type' => 'UNIQUE', + 'errmsg'=> 'domain_error_unique'), + 2 => array ( 'type' => 'REGEX', + 'regex' => '/^[\w\.\-]{2,255}\.[a-zA-Z0-9\-]{2,30}$/', + 'errmsg'=> 'domain_error_regex'), + ), + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255', + 'searchable' => 1 + ), + 'auth_method' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => '1', + 'value' => array(0 => 'Plain', 1 => 'Hashed', 2 => 'By Email Mailbox') + ), + 'public_registration' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'registration_url' => array ( + 'datatype' => 'VARCHAR', + 'validators' => array ( 0 => array ( 'type' => 'REGEX', + 'regex' => '@^(([\.]{0})|((ftp|https?)://([-\w\.]+)+(:\d+)?(/([\w/_\.\,\-\+\?\~!:%]*(\?\S+)?)?)?)|(\[scheme\]://([-\w\.]+)+(:\d+)?(/([\w/_\.\-\,\+\?\~!:%]*(\?\S+)?)?)?)|(/(?!.*\.\.)[\w/_\.\-]{1,255}/))$@', + 'errmsg'=> 'redirect_error_regex'), + ), + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'registration_message' => array( + 'datatype' => 'TEXT', + 'formtype' => 'TEXT', + 'default' => "Please visit our website for information on registration.", + 'value' => '' + ), + 'domain_admins' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'admin@service.com, superuser@service.com', + 'value' => '', + 'width' => '15', + 'maxlength' => '3' + ), + + 'active' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + //################################# + // ENDE Datatable fields + //################################# + ) +); + + +$form["tabs"]['features'] = array ( + 'title' => "Modules", + 'width' => 100, + 'template' => "templates/xmpp_domain_edit_modules.htm", + 'fields' => array ( + //################################# + // Begin Datatable fields + //################################# + 'use_anon_host' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'use_pubsub' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'use_vjud' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'vjud_opt_mode' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => '0', + 'value' => array(0 => 'Opt-In', 1 => 'Opt-Out') + ), + 'use_proxy' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'use_status_host' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + //################################# + // ENDE Datatable fields + //################################# + ) +); + +$form["tabs"]['muc'] = array ( + 'title' => "MUC", + 'width' => 100, + 'template' => "templates/xmpp_domain_edit_muc.htm", + 'fields' => array ( + //################################# + // Begin Datatable fields + //################################# + 'use_muc_host' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'muc_name' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '' + ), + 'muc_restrict_room_creation' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => '1', + 'value' => array(0 => 'Everyone', 1 => 'Members', 2 => 'Admins') + ), + 'muc_admins' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'admin@service.com, superuser@service.com', + 'value' => '', + 'width' => '15', + 'maxlength' => '3' + ), + 'use_pastebin' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'pastebin_expire_after' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '48', + 'validators' => array(0 => array('type' => 'ISINT'), + array('type'=>'RANGE', 'range'=>'1:168') + ), + 'value' => '', + 'width' => '15' + ), + 'pastebin_trigger' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '!paste', + 'value' => '', + 'width' => '15' + ), + 'use_http_archive' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'http_archive_show_join' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'http_archive_show_status' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + //################################# + // ENDE Datatable fields + //################################# + ) +); + + +?> diff --git a/interface/web/mail/lib/lang/en_xmpp_domain.lng b/interface/web/mail/lib/lang/en_xmpp_domain.lng new file mode 100644 index 0000000000..1151f5cd44 --- /dev/null +++ b/interface/web/mail/lib/lang/en_xmpp_domain.lng @@ -0,0 +1,28 @@ + diff --git a/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng new file mode 100644 index 0000000000..a3d1736d7b --- /dev/null +++ b/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/interface/web/mail/lib/lang/en_xmpp_domain_list.lng b/interface/web/mail/lib/lang/en_xmpp_domain_list.lng new file mode 100644 index 0000000000..f8c2fb9b8e --- /dev/null +++ b/interface/web/mail/lib/lang/en_xmpp_domain_list.lng @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/interface/web/mail/lib/module.conf.php b/interface/web/mail/lib/module.conf.php index 2ca9b7aca9..7f828d1fc9 100644 --- a/interface/web/mail/lib/module.conf.php +++ b/interface/web/mail/lib/module.conf.php @@ -148,6 +148,30 @@ if($app->auth->get_client_limit($userid, 'fetchmail') != 0) 'items' => $items); } +//**** XMPP Menu +$items = array(); + +if($app->auth->get_client_limit($userid, 'xmppdomain') != 0) +{ + $items[] = array( 'title' => 'XMPP Domain', + 'target' => 'content', + 'link' => 'mail/xmpp_domain_list.php', + 'html_id' => 'xmpp_domain_list'); +} + +if($app->auth->get_client_limit($userid, 'xmppaccount') != 0) +{ + $items[] = array( 'title' => 'XMPP Account', + 'target' => 'content', + 'link' => 'mail/xmpp_account_list.php', + 'html_id' => 'xmpp_account_list'); +} + +if(count($items)) + $module['nav'][] = array( 'title' => 'Jabber / XMPP', + 'open' => 1, + 'items' => $items); + //**** Statistics menu diff --git a/interface/web/mail/list/xmpp_domain.list.php b/interface/web/mail/list/xmpp_domain.list.php new file mode 100644 index 0000000000..21257e4283 --- /dev/null +++ b/interface/web/mail/list/xmpp_domain.list.php @@ -0,0 +1,109 @@ + "active", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('y' => "
Yes
", 'n' => "
No
")); + + +if($_SESSION['s']['user']['typ'] == 'admin') { + $liste["item"][] = array( 'field' => "sys_groupid", + 'datatype' => "INTEGER", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT groupid, name FROM sys_group WHERE groupid != 1 ORDER BY name', + 'keyfield'=> 'groupid', + 'valuefield'=> 'name' + ), + 'width' => "", + 'value' => ""); +} + + +$liste["item"][] = array( 'field' => "server_id", + 'datatype' => "INTEGER", + 'formtype' => "SELECT", + 'op' => "like", + 'prefix' => "", + 'suffix' => "", + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT a.server_id, a.server_name FROM server a, xmpp_domain b WHERE (a.server_id = b.server_id) AND ({AUTHSQL-B}) ORDER BY a.server_name', + 'keyfield'=> 'server_id', + 'valuefield'=> 'server_name' + ), + 'width' => "", + 'value' => ""); + +$liste["item"][] = array( 'field' => "domain", + 'datatype' => "VARCHAR", + 'filters' => array( 0 => array( 'event' => 'SHOW', + 'type' => 'IDNTOUTF8') + ), + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "%", + 'suffix' => "%", + 'width' => "", + 'value' => ""); + + +?> diff --git a/interface/web/mail/templates/xmpp_domain_admin_list.htm b/interface/web/mail/templates/xmpp_domain_admin_list.htm new file mode 100644 index 0000000000..ccda2d5032 --- /dev/null +++ b/interface/web/mail/templates/xmpp_domain_admin_list.htm @@ -0,0 +1,60 @@ + + + +

{tmpl_var name="toolsarea_head_txt"}

+ + + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
+ +
{tmpl_var name="active"}{tmpl_var name="sys_groupid"}{tmpl_var name="server_id"}{tmpl_var name="domain"} + +
{tmpl_var name='globalsearch_noresults_text_txt'}
+
+ + \ No newline at end of file diff --git a/interface/web/mail/templates/xmpp_domain_edit.htm b/interface/web/mail/templates/xmpp_domain_edit.htm new file mode 100644 index 0000000000..c735eff94b --- /dev/null +++ b/interface/web/mail/templates/xmpp_domain_edit.htm @@ -0,0 +1,124 @@ + +

+ + + + +
+ + +
+ + + +
+
+
+ +
+ +
+
+
+ + + + +
+ + +
+ + + +
+
+
+
+
+ + + +
+ +
+
+
+
+ +
+ + +
+ +
+
+ + + + + +
+ +
+
+ +
+
+ +
+ {tmpl_var name='public_registration'} +
+
+
+
+
+ +
+ +
+
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ {tmpl_var name='active'} +
+
+ + + +
+ + +
+ diff --git a/interface/web/mail/templates/xmpp_domain_edit_modules.htm b/interface/web/mail/templates/xmpp_domain_edit_modules.htm new file mode 100644 index 0000000000..f6d988fea2 --- /dev/null +++ b/interface/web/mail/templates/xmpp_domain_edit_modules.htm @@ -0,0 +1,52 @@ + +

+ + + +
+ +
+ {tmpl_var name='use_anon_host'} +
+
+
+ +
+ {tmpl_var name='use_pubsub'} +
+
+
+ +
+ {tmpl_var name='use_vjud'} +
+
+
+ +
+
+
+ +
+ {tmpl_var name='use_proxy'} +
+
+
+ +
+ {tmpl_var name='use_status_host'} +
+
+ + + + + +
+ + +
diff --git a/interface/web/mail/templates/xmpp_domain_edit_muc.htm b/interface/web/mail/templates/xmpp_domain_edit_muc.htm new file mode 100644 index 0000000000..533362df51 --- /dev/null +++ b/interface/web/mail/templates/xmpp_domain_edit_muc.htm @@ -0,0 +1,87 @@ + +

+ + + +
+ +
+ {tmpl_var name='use_muc_host'} +
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+
+ +
+
+
+ +
+ +
+ {tmpl_var name='use_pastebin'} +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+ {tmpl_var name='use_http_archive'} +
+
+
+
+ +
+ {tmpl_var name='http_archive_show_join'} +
+
+
+ +
+ {tmpl_var name='http_archive_show_status'} +
+
+
+ +
+ + + + +
+ + +
+ diff --git a/interface/web/mail/templates/xmpp_domain_list.htm b/interface/web/mail/templates/xmpp_domain_list.htm new file mode 100644 index 0000000000..79579142d7 --- /dev/null +++ b/interface/web/mail/templates/xmpp_domain_list.htm @@ -0,0 +1,74 @@ + +

+ + + +
+
+
+
+ {tmpl_var name="datalog_changes_txt"} +
    + +
  • {tmpl_var name="text"}: {tmpl_var name="count"}
  • +
    +
+ {tmpl_var name="datalog_changes_end_txt"} +
+

+
+
+

{tmpl_var name="toolsarea_head_txt"}

+ + + + + + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
+ +
{tmpl_var name="active"}{tmpl_var name="server_id"}{tmpl_var name="domain"} + +
{tmpl_var name='globalsearch_noresults_text_txt'}
+
+ + \ No newline at end of file diff --git a/interface/web/mail/xmpp_domain_del.php b/interface/web/mail/xmpp_domain_del.php new file mode 100644 index 0000000000..3dcc859764 --- /dev/null +++ b/interface/web/mail/xmpp_domain_del.php @@ -0,0 +1,102 @@ +auth->check_module_permissions('mail'); + +// Loading classes +$app->uses('tpl,tform,tform_actions'); +$app->load('tform_actions'); + +class page_action extends tform_actions { + + function onBeforeDelete() { + global $app; $conf; + + $domain = $this->dataRecord['domain']; + + // Before we delete the email domain, + // we will delete all depending records. + // TODO: Delete xmpp accounts in filesystem + // TODO: Delete xmpp accounts in isp + // TODO: Delete DNS Records +/* + // Delete all forwardings where the source or destination belongs to this domain + $records = $app->db->queryAllRecords("SELECT forwarding_id as id FROM mail_forwarding WHERE source like '%@".$app->db->quote($domain)."' OR (destination like '%@".$app->db->quote($domain)."' AND type != 'forward')"); + foreach($records as $rec) { + $app->db->datalogDelete('mail_forwarding', 'forwarding_id', $rec['id']); + } + + // Delete all fetchmail accounts where destination belongs to this domain + $records = $app->db->queryAllRecords("SELECT mailget_id as id FROM mail_get WHERE destination like '%@".$app->db->quote($domain)."'"); + foreach($records as $rec) { + $app->db->datalogDelete('mail_get', 'mailget_id', $rec['id']); + } + + // Delete all mailboxes where destination belongs to this domain + $records = $app->db->queryAllRecords("SELECT mailuser_id as id FROM mail_user WHERE email like '%@".$app->db->quote($domain)."'"); + foreach($records as $rec) { + $app->db->datalogDelete('mail_user', 'mailuser_id', $rec['id']); + } + + // Delete all spamfilters that belong to this domain + $records = $app->db->queryAllRecords("SELECT id FROM spamfilter_users WHERE email = '%@".$app->db->quote($domain)."'"); + foreach($records as $rec) { + $app->db->datalogDelete('spamfilter_users', 'id', $rec['id']); + } + + // Delete all mailinglists that belong to this domain + $records = $app->db->queryAllRecords("SELECT mailinglist_id FROM mail_mailinglist WHERE domain = '".$app->db->quote($domain)."'"); + foreach($records as $rec) { + $app->db->datalogDelete('mail_mailinglist', 'mailinglist_id', $rec['id']); + } +*/ + } + +} + +$page = new page_action; +$page->onDelete(); + +?> diff --git a/interface/web/mail/xmpp_domain_edit.php b/interface/web/mail/xmpp_domain_edit.php new file mode 100644 index 0000000000..d87778d110 --- /dev/null +++ b/interface/web/mail/xmpp_domain_edit.php @@ -0,0 +1,436 @@ +auth->check_module_permissions('mail'); + +// Loading classes +$app->uses('tpl,tform,tform_actions,tools_sites'); +$app->load('tform_actions'); + +class page_action extends tform_actions { + var $_xmpp_type = 'domain'; + + function onLoad() { + $show_type = 'server'; + if(isset($_GET['type']) && $_GET['type'] == 'modules') { + $show_type = 'modules'; + } elseif(isset($_GET['type']) && $_GET['type'] == 'muc') { + $show_type = 'muc'; + } + + $_SESSION['s']['var']['xmpp_type'] = $show_type; + $this->_xmpp_type = $show_type; + + parent::onLoad(); + } + + function onShowNew() { + global $app, $conf; + + // we will check only users, not admins + if($_SESSION["s"]["user"]["typ"] == 'user') { + if(!$app->tform->checkClientLimit('limit_xmppdomain')) { + $app->error($app->tform->wordbook["limit_xmppdomain_txt"]); + } + if(!$app->tform->checkResellerLimit('limit_xmppdomain')) { + $app->error('Reseller: '.$app->tform->wordbook["limit_xmppdomain_txt"]); + } + } else { + $settings = $app->getconf->get_global_config('xmpp'); + $app->tform->formDef['tabs']['domain']['fields']['server_id']['default'] = intval($settings['default_xmppserver']); + } + + parent::onShowNew(); + } + + function onShowEnd() { + global $app, $conf; + + $app->uses('ini_parser,getconf'); + $settings = $app->getconf->get_global_config('domains'); + + if($_SESSION["s"]["user"]["typ"] == 'admin' && $settings['use_domain_module'] != 'y') { + // Getting Clients of the user + $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND sys_group.client_id > 0 ORDER BY client.company_name, client.contact_name, sys_group.name"; + + $clients = $app->db->queryAllRecords($sql); + $client_select = ''; + if($_SESSION["s"]["user"]["typ"] == 'admin') $client_select .= ""; + //$tmp_data_record = $app->tform->getDataRecord($this->id); + if(is_array($clients)) { + foreach( $clients as $client) { + $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; + $client_select .= "\r\n"; + } + } + $app->tpl->setVar("client_group_id", $client_select); + + } elseif ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.client_id, client.contact_name, client.default_xmppserver, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname, sys_group.name FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id order by client.contact_name"); + + // Set the xmppserver to the default server of the client + $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = $client[default_xmppserver]"); + $app->tpl->setVar("server_id", ""); + unset($tmp); + + if ($settings['use_domain_module'] != 'y') { + // Fill the client select field + $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$app->functions->intval($client['client_id'])." ORDER BY client.company_name, client.contact_name, sys_group.name"; + $clients = $app->db->queryAllRecords($sql); + $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ".$app->functions->intval($client['client_id'])); + $client_select = ''; + //$tmp_data_record = $app->tform->getDataRecord($this->id); + if(is_array($clients)) { + foreach( $clients as $client) { + $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; + $client_select .= "\r\n"; + } + } + $app->tpl->setVar("client_group_id", $client_select); + } + } + + if($_SESSION["s"]["user"]["typ"] != 'admin') + { + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client_xmpp = $app->db->queryOneRecord("SELECT xmpp_servers FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + $client_xmpp['xmpp_servers_ids'] = explode(',', $client_xmpp['xmpp_servers']); + + $only_one_server = count($client_xmpp['xmpp_servers_ids']) === 1; + $app->tpl->setVar('only_one_server', $only_one_server); + + if ($only_one_server) { + $app->tpl->setVar('server_id_value', $client_xmpp['xmpp_servers_ids'][0]); + } + + $sql = "SELECT server_id, server_name FROM server WHERE server_id IN (" . $client_xmpp['xmpp_servers'] . ");"; + $xmpp_servers = $app->db->queryAllRecords($sql); + + $options_xmpp_servers = ""; + + foreach ($xmpp_servers as $xmpp_server) { + $options_xmpp_servers .= ""; + } + + $app->tpl->setVar("client_server_id", $options_xmpp_servers); + unset($options_xmpp_servers); + + } + + /* + * Now we have to check, if we should use the domain-module to select the domain + * or not + */ + if ($settings['use_domain_module'] == 'y') { + /* + * The domain-module is in use. + */ + $domains = $app->tools_sites->getDomainModuleDomains("xmpp_domain", $this->dataRecord["domain"]); + $domain_select = ''; + if(is_array($domains) && sizeof($domains) > 0) { + /* We have domains in the list, so create the drop-down-list */ + foreach( $domains as $domain) { + $domain_select .= "\r\n"; + } + } + else { + /* + * We have no domains in the domain-list. This means, we can not add ANY new domain. + * To avoid, that the variable "domain_option" is empty and so the user can + * free enter a domain, we have to create a empty option! + */ + $domain_select .= "\r\n"; + } + $app->tpl->setVar("domain_option", $domain_select); + $app->tpl->setVar("domain_module", 1); + } else { + $app->tpl->setVar("domain_module", 0); + } + + + if($this->id > 0) { + //* we are editing a existing record + $app->tpl->setVar("edit_disabled", 1); + $app->tpl->setVar("server_id_value", $this->dataRecord["server_id"]); + } else { + $app->tpl->setVar("edit_disabled", 0); + } + + + parent::onShowEnd(); + } + + function onSubmit() { + global $app, $conf; + + /* check if the domain module is used - and check if the selected domain can be used! */ + $app->uses('ini_parser,getconf'); + $settings = $app->getconf->get_global_config('domains'); + if ($settings['use_domain_module'] == 'y') { + if ($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + $this->dataRecord['client_group_id'] = $app->tools_sites->getClientIdForDomain($this->dataRecord['domain']); + } + $domain_check = $app->tools_sites->checkDomainModuleDomain($this->dataRecord['domain']); + if(!$domain_check) { + // invalid domain selected + $app->tform->errorMessage .= $app->tform->lng("domain_error_empty")."
"; + } else { + $this->dataRecord['domain'] = $domain_check; + } + } + + if($_SESSION["s"]["user"]["typ"] != 'admin') { + // Get the limits of the client + $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); + $client = $app->db->queryOneRecord("SELECT limit_xmppdomain, default_xmppserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + // When the record is updated + if($this->id > 0) { + // restore the server ID if the user is not admin and record is edited + $tmp = $app->db->queryOneRecord("SELECT server_id FROM xmpp_domain WHERE domain_id = ".$app->functions->intval($this->id)); + $this->dataRecord["server_id"] = $tmp["server_id"]; + unset($tmp); + // When the record is inserted + } else { + $client['xmpp_servers_ids'] = explode(',', $client['xmpp_servers']); + + // Check if chosen server is in authorized servers for this client + if (!(is_array($client['xmpp_servers_ids']) && in_array($this->dataRecord["server_id"], $client['xmpp_servers_ids']))) { + $app->error($app->tform->wordbook['error_not_allowed_server_id']); + } + + if($client["limit_xmppdomain"] >= 0) { + $tmp = $app->db->queryOneRecord("SELECT count(domain_id) as number FROM xmpp_domain WHERE sys_groupid = $client_group_id"); + if($tmp["number"] >= $client["limit_xmppdomain"]) { + $app->error($app->tform->wordbook["limit_xmppdomain_txt"]); + } + } + } + + // Clients may not set the client_group_id, so we unset them if user is not a admin + if(!$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]); + } + + //* make sure that the xmpp domain is lowercase + if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + + // Read auth method + if(isset($this->dataRecord["auth_method"])) + switch($this->dataRecord["auth_method"]){ + case 0: + $this->dataRecord["auth_method"] = 'plain'; + break; + case 1: + $this->dataRecord["auth_method"] = 'hashed'; + break; + case 2: + $this->dataRecord["auth_method"] = 'isp'; + break; + } + // vjud opt mode + if(isset($this->dataRecord["vjud_opt_mode"])) + $this->dataRecord["vjud_opt_mode"] = $this->dataRecord["vjud_opt_mode"] == 0 ? 'in' : 'out'; + if(isset($this->dataRecord["muc_restrict_room_creation"])){ + switch($this->dataRecord["muc_restrict_room_creation"]){ + case 0: + $this->dataRecord["muc_restrict_room_creation"] = 'false'; + break; + case 1: + $this->dataRecord["muc_restrict_room_creation"] = 'member'; + break; + case 2: + $this->dataRecord["muc_restrict_room_creation"] = 'true'; + break; + } + } + + parent::onSubmit(); + } + + function onAfterInsert() { + global $app, $conf; + + // make sure that the record belongs to the client group and not the admin group when admin inserts it + // also make sure that the user can not delete domain created by a admin + if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { + $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE xmpp_domain SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE domain_id = ".$this->id); + } + if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { + $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE xmpp_domain SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE domain_id = ".$this->id); + } + + //* make sure that the xmpp domain is lowercase + if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + + // Insert DNS Records + $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + if ( isset($soa) && !empty($soa) ) $this->update_dns($this->dataRecord, $soa); + } + + function onBeforeUpdate() { + global $app, $conf; + + if($this->_xmpp_type == 'server') { + //* Check if the server has been changed + // We do this only for the admin or reseller users, as normal clients can not change the server ID anyway + if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + if (isset($this->dataRecord["server_id"])) { + $rec = $app->db->queryOneRecord("SELECT server_id from xmpp_domain WHERE domain_id = ".$this->id); + if($rec['server_id'] != $this->dataRecord["server_id"]) { + //* Add a error message and switch back to old server + $app->tform->errorMessage .= $app->lng('The Server can not be changed.'); + $this->dataRecord["server_id"] = $rec['server_id']; + } + unset($rec); + } + //* If the user is neither admin nor reseller + } else { + //* We do not allow users to change a domain which has been created by the admin + $rec = $app->db->queryOneRecord("SELECT sys_perm_group, domainfrom xmpp_domain WHERE domain_id = ".$this->id); + if(isset($this->dataRecord["domain"]) && $rec['domain'] != $this->dataRecord["domain"] && $app->tform->checkPerm($this->id, 'u')) { + //* Add a error message and switch back to old server + $app->tform->errorMessage .= $app->lng('The Domain can not be changed. Please ask your Administrator if you want to change the domain name.'); + $this->dataRecord["domain"] = $rec['domain']; + } + unset($rec); + } + } + + //* make sure that the xmpp domain is lowercase + if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + + } + + function onAfterUpdate() { + global $app, $conf; + + // Update DNS Records + // TODO: Update gets only triggered from main form. WHY? + // TODO: if(in_array($this->_xmpp_type, array('muc', 'modules'))){ + $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + if ( isset($soa) && !empty($soa) ) $this->update_dns($this->dataRecord, $soa); + //} + } + + + + private function update_dns($dataRecord, $new_rr) { + global $app, $conf; + + $rec = $app->db->queryOneRecord("SELECT use_pubsub, use_proxy, use_anon_host, use_vjud, use_muc_host from xmpp_domain WHERE domain_id = ".$this->id); + $required_hosts = array('xmpp'); + if($rec['use_pubsub']=='y') + $required_hosts[] = 'pubsub'; + if($rec['use_proxy']=='y') + $required_hosts[] = 'proxy'; + if($rec['use_anon_host']=='y') + $required_hosts[] = 'anon'; + if($rec['use_vjud']=='y') + $required_hosts[] = 'vjud'; + if($rec['use_muc_host']=='y') + $required_hosts[] = 'muc'; + + // purge old rr-record + $sql = "SELECT * FROM dns_rr WHERE zone = ? AND (name IN ? AND type = 'CNAME' OR name LIKE ? AND type = 'SRV') AND ? ORDER BY serial DESC"; + $rec = $app->db->queryAllRecords($sql, $new_rr['zone'], array('xmpp', 'pubsub', 'proxy', 'anon', 'vjud', 'muc'), '_xmpp-%', $app->tform->getAuthSQL('r')); + if (is_array($rec[1])) { + for ($i=0; $i < count($rec); ++$i) + $app->db->datalogDelete('dns_rr', 'id', $rec[$i]['id']); + } + + // create new cname rr-records + foreach($required_hosts AS $h){ + $rr = $new_rr; + $rr['name'] = $h; + $rr['type'] = 'CNAME'; + $rr['data'] = 'jalapeno.spicyweb.de.'; + $rr['aux'] = 0; + $rr['active'] = 'Y'; + $rr['stamp'] = date('Y-m-d H:i:s'); + $rr['serial'] = $app->validate_dns->increase_serial($new_rr['serial']); + $app->db->datalogInsert('dns_rr', $rr, 'id', $rr['zone']); + } + + //create new srv rr-records + $rr = $new_rr; + $rr['name'] = '_xmpp-client._tcp.'.$dataRecord['domain'].'.'; + $rr['type'] = 'SRV'; + $rr['data'] = '5 5222 jalapeno.spicyweb.de.'; + $rr['aux'] = 0; + $rr['active'] = 'Y'; + $rr['stamp'] = date('Y-m-d H:i:s'); + $rr['serial'] = $app->validate_dns->increase_serial($new_rr['serial']); + $app->db->datalogInsert('dns_rr', $rr, 'id', $rr['zone']); + $rr = $new_rr; + $rr['name'] = '_xmpp-server._tcp.'.$dataRecord['domain'].'.'; + $rr['type'] = 'SRV'; + $rr['data'] = '5 5269 jalapeno.spicyweb.de.'; + $rr['aux'] = 0; + $rr['active'] = 'Y'; + $rr['stamp'] = date('Y-m-d H:i:s'); + $rr['serial'] = $app->validate_dns->increase_serial($new_rr['serial']); + $app->db->datalogInsert('dns_rr', $rr, 'id', $rr['zone']); + + // Refresh zone + $zone = $app->db->queryOneRecord("SELECT id, serial FROM dns_soa WHERE active = 'Y' AND id = ?", $new_rr['zone']); + $new_serial = $app->validate_dns->increase_serial($zone['serial']); + $app->db->datalogUpdate('dns_soa', "serial = '".$new_serial."'", 'id', $zone['id']); + } + + +} + +$page = new page_action; +$page->onLoad(); + +?> diff --git a/interface/web/mail/xmpp_domain_list.php b/interface/web/mail/xmpp_domain_list.php new file mode 100644 index 0000000000..ff632e38ca --- /dev/null +++ b/interface/web/mail/xmpp_domain_list.php @@ -0,0 +1,28 @@ +auth->check_module_permissions('mail'); + +$app->uses('listform_actions'); + +// Limit the results to alias domains +// $app->listform_actions->SQLExtWhere = "type = 'local'"; + +$app->listform_actions->SQLOrderBy = 'ORDER BY xmpp_domain.domain'; +$app->listform_actions->onLoad(); + + +?> diff --git a/server/conf/metronome_conf_global.master b/server/conf/metronome_conf_global.master new file mode 100644 index 0000000000..71920caea1 --- /dev/null +++ b/server/conf/metronome_conf_global.master @@ -0,0 +1,48 @@ +pidfile = "/var/run/metronome/metronome.pid"; +metronome_max_files_soft = 200000; +metronome_max_files_hard = 300000; +plugin_paths = { + "/usr/lib/metronome/isp-modules", +}; +use_libevent = true; +log = { + debug = "/var/log/metronome/metronome.dbg", + info = "/var/log/metronome/metronome.log", + error = "/var/log/metronome/metronome.err", +}; +use_ipv6 = {tmpl_var name='ipv6'}; +http_ports = { + {tmpl_var name='port_http'}, +}; +https_ports = { + {tmpl_var name='port_https'}, +}; +pastebin_ports = { + {tmpl_var name='port_pastebin'}, +}; +bosh_ports = { + {tmpl_var name='port_bosh'}, +}; +admins = { +{tmpl_var name='server_admins'} +}; +modules_enabled = { +{tmpl_var name='modules_enabled'} +}; +modules_disabled = { +}; +bosh_max_inactivity = {tmpl_var name='bosh_timeout'}; +consider_bosh_secure = true; +cross_domain_bosh = true; +allow_registration = true; +-- TODO generate ssl key during setup +ssl = { + key = "/etc/metronome/certs/localhost.key", + certificate = "/etc/metronome/certs/localhost.cert", +}; +c2s_require_encryption = false; +s2s_secure = true; +s2s_insecure_domains = { + "gmail.com", +}; +authentication = "internal_plain"; \ No newline at end of file diff --git a/server/conf/metronome_conf_host.master b/server/conf/metronome_conf_host.master new file mode 100644 index 0000000000..66cbf0b60b --- /dev/null +++ b/server/conf/metronome_conf_host.master @@ -0,0 +1,138 @@ +VirtualHost "{tmpl_var name='domain'}" + enabled = {tmpl_var name='active'}; + authentication = "{tmpl_var name='auth_method'}"; + + external_auth_command = "/usr/lib/metronome/isp-modules/mod_auth_external/authenticate_isp.sh"; + + allow_registration = {tmpl_var name='public_registration'}; + + + registration_url = "{tmpl_var name='registration_url'}"; + registration_text = "{tmpl_var name='registration_message'}"; + + no_registration_whitelist = true; + + modules_enabled = { + "roster", + "private", + "vcard", + "privacy", + "pep", + + "register", + + "register_redirect", + + "admin_adhoc", + }; + disco_items = { + + { + "muc.{tmpl_var name='domain'}", + "{tmpl_var name='muc_name'}", + }, + + + { + "pubsub.{tmpl_var name='domain'}", + "{tmpl_var name='domain'} Publish/Subscribe", + }, + + + { + "proxy.{tmpl_var name='domain'}", + "{tmpl_var name='domain'} Bytestream Proxy", + }, + + + { + "vjud.{tmpl_var name='domain'}", + "{tmpl_var name='domain'} User Directory", + }, + + }; + + admins = { +{tmpl_var name='domain_admins'} + }; +-- TODO: SSL Certs for Hosts +-- ssl = { +-- key = "/var/lib/metronome/iplay-esports.de.key", +-- certificate = "/var/lib/metronome/iplay-esports.de.crt", +-- }; + + + +VirtualHost "anon.{tmpl_var name='domain'}" + enabled = true; + authentication = "anonymous"; + allow_anonymous_multiresourcing = true; + anonymous_jid_gentoken = "{tmpl_var name='domain'} Anonymous User"; + admins = { + }; + + + + +Component "muc.{tmpl_var name='domain'}" "muc" + modules_enabled = { + "muc_limits", + "muc_log", + + "muc_log_http", + + + "pastebin", + + }; + muc_event_rate = 0.7; + muc_burst_factor = 13; + muc_log_presences = false; + + muc_log_http_config = { + show_join = {tmpl_var name='archive_join'}, + show_status = {tmpl_var name='archive_status'}, + theme = "metronome", + url_base = "logs", + }; + + + pastebin_path = "/pastes/"; + pastebin_expire_after = {tmpl_var name='pastebin_expire'}; + pastebin_trigger = "{tmpl_var name='pastebin_trigger'}"; + + name = "{tmpl_var name='muc_name'}"; + restrict_room_creation = "{tmpl_var name='muc_restrict_room_creation'}"; + admins = { +{tmpl_var name='muc_admins'} + }; + + + + +Component "pubsub.{tmpl_var name='domain'}" "pubsub" + name = "{tmpl_var name='domain'} Publish/Subscribe"; + unrestricted_node_creation = false; + + + +Component "proxy.{tmpl_var name='domain'}" "proxy65" + proxy65_acl = { + "{tmpl_var name='domain'}", + }; + proxy65_interfaces = { + "*", + "::", + }; + proxy65_ports = { + 5000, + }; + + + + +Component "vjud.{tmpl_var name='domain'}" "vjud" + ud_disco_name = "{tmpl_var name='domain'} User Directory"; + synchronize_to_host_vcards = "{tmpl_var name='domain'}"; + vjud_mode = "{tmpl_var name='vjud_opt_mode'}"; + \ No newline at end of file diff --git a/server/conf/metronome_conf_main.master b/server/conf/metronome_conf_main.master new file mode 100644 index 0000000000..1103ca4d9c --- /dev/null +++ b/server/conf/metronome_conf_main.master @@ -0,0 +1,3 @@ +Include "/etc/metronome/global.cfg.lua" +Include "/etc/metronome/hosts/*.lua" +Include "/etc/metronome/status.cfg.lua" diff --git a/server/conf/metronome_conf_status.master b/server/conf/metronome_conf_status.master new file mode 100644 index 0000000000..daa8205491 --- /dev/null +++ b/server/conf/metronome_conf_status.master @@ -0,0 +1,12 @@ +Component "xmpp.{tmpl_var name='domain'}" "http" + modules_enabled = { + "server_status", + "webpresence" + }; + server_status_basepath = "/xmppd/"; + server_status_show_hosts = { +{tmpl_var name='status_hosts'} + }; + server_status_show_comps = { +{tmpl_var name='status_comps'} + }; \ No newline at end of file diff --git a/server/mods-available/xmpp_module.inc.php b/server/mods-available/xmpp_module.inc.php new file mode 100644 index 0000000000..145b7f0f58 --- /dev/null +++ b/server/mods-available/xmpp_module.inc.php @@ -0,0 +1,109 @@ +plugins->announceEvents($this->module_name, $this->actions_available); + + /* + As we want to get notified of any changes on several database tables, + we register for them. + + The following function registers the function "functionname" + to be executed when a record for the table "dbtable" is + processed in the sys_datalog. "classname" is the name of the + class that contains the function functionname. + */ + + $app->modules->registerTableHook('xmpp_domain', 'xmpp_module', 'process'); + + } + + /* + This function is called when a change in one of the registered tables is detected. + The function then raises the events for the plugins. + */ + + function process($tablename, $action, $data) { + global $app; + + switch ($tablename) { + case 'xmpp_domain': + if($action == 'i') $app->plugins->raiseEvent('xmpp_domain_insert', $data); + if($action == 'u') $app->plugins->raiseEvent('xmpp_domain_update', $data); + if($action == 'd') $app->plugins->raiseEvent('xmpp_domain_delete', $data); + break; + case 'xmpp_user': + if($action == 'i') $app->plugins->raiseEvent('xmpp_user_insert', $data); + if($action == 'u') $app->plugins->raiseEvent('xmpp_user_update', $data); + if($action == 'd') $app->plugins->raiseEvent('xmpp_user_delete', $data); + break; + } // end switch + } // end function + +} // end class + +?> diff --git a/server/plugins-available/xmpp_plugin.inc.php b/server/plugins-available/xmpp_plugin.inc.php new file mode 100644 index 0000000000..c4f70e30dd --- /dev/null +++ b/server/plugins-available/xmpp_plugin.inc.php @@ -0,0 +1,232 @@ +plugins->registerEvent('server_insert', 'xmpp_plugin', 'insert'); + $app->plugins->registerEvent('server_update', 'xmpp_plugin', 'update'); + $app->plugins->registerEvent('xmpp_domain_insert', 'xmpp_plugin', 'domainInsert'); + $app->plugins->registerEvent('xmpp_domain_update', 'xmpp_plugin', 'domainUpdate'); + $app->plugins->registerEvent('xmpp_domain_delete', 'xmpp_plugin', 'domainDelete'); + + } + + function insert($event_name, $data) { + global $app, $conf; + + $this->update($event_name, $data); + + } + + // The purpose of this plugin is to rewrite the main.cf file + function update($event_name, $data) { + global $app, $conf; + + // get the config + $app->uses("getconf,system,tpl"); + + + $old_ini_data = $app->ini_parser->parse_ini_string($data['old']['config']); + $xmpp_config = $app->getconf->get_server_config($conf['server_id'], 'xmpp'); + + $tpl = new tpl(); + $tpl->newTemplate('metronome_conf_global.master'); + + $tpl->setVar('ipv6', $xmpp_config['xmpp_use_ipv6']=='y'?'true':'false'); + $tpl->setVar('bosh_timeout', intval($xmpp_config['xmpp_bosh_max_inactivity'])); + $tpl->setVar('port_http', intval($xmpp_config['xmpp_port_http'])); + $tpl->setVar('port_https', intval($xmpp_config['xmpp_port_https'])); + $tpl->setVar('port_pastebin', intval($xmpp_config['xmpp_port_pastebin'])); + $tpl->setVar('port_bosh', intval($xmpp_config['xmpp_port_bosh'])); + $admins = ''; + foreach(explode(',', $xmpp_config['xmpp_server_admins']) AS $a) + $admins.= "\t\"".trim($a)."\",\n"; + $tpl->setVar('server_admins', $admins); + unset($admins); + $modules = ''; + foreach(explode(',', $xmpp_config['xmpp_modules_enabled']) AS $m) + $modules.= "\t\"".trim($m)."\",\n"; + $tpl->setVar('modules_enabled', $modules); + unset($modules); + $app->system->file_put_contents($this->xmpp_config_dir.'/global.cfg.lua', $tpl->grab()); + unset($tpl); + + return; + } + + function domainInsert($event_name, $data) { + global $app, $conf; + + $this->domainUpdate($event_name, $data); + + } + + function domainUpdate($event_name, $data){ + global $app, $conf; + + // get the config + $app->uses("getconf,system,tpl"); + + // Collections + $status_hosts = array($data['new']['domain']); + $status_comps = array(); + + // Create main host file + $tpl = new tpl(); + $tpl->newTemplate('metronome_conf_host.master'); + $tpl->setVar('domain', $data['new']['domain']); + $tpl->setVar('active', $data['new']['active'] == 'y' ? 'true' : 'false'); + $tpl->setVar('auth_method', $data['new']['auth_method'] == 'isp' ? 'external' : 'internal_'.$data['new']['auth_method']); + $tpl->setVar('public_registration', $data['new']['public_registration'] == 'y' ? 'true' : 'false'); + + $admins = array(); + foreach(explode(',',$data['new']['domain_admins']) AS $adm){ + $admins[] = trim($adm); + } + $tpl->setVar('domain_admins', "\t\t\"".implode("\",\n\t\t\"",$admins)."\"\n"); + + if($data['new']['use_pubsub']=='y'){ + $tpl->setVar('use_pubsub', 'true'); + $status_comps[] = 'pubsub.'.$data['new']['domain']; + }else{ + $tpl->setVar('use_pubsub', 'false'); + } + if($data['new']['use_proxy']=='y'){ + $tpl->setVar('use_proxy', 'true'); + $status_comps[] = 'proxy.'.$data['new']['domain']; + }else{ + $tpl->setVar('use_proxy', 'false'); + } + + if($data['new']['use_anon_host']=='y'){ + $tpl->setVar('use_anon_host', 'true'); + $status_hosts[] = 'anon.'.$data['new']['domain']; + }else{ + $tpl->setVar('use_anon_host', 'false'); + } + if($data['new']['use_vjud']=='y'){ + $tpl->setVar('use_vjud', 'true'); + $tpl->setVar('vjud_opt_mode', 'opt-'.$data['new']['vjud_opt_mode']); + $status_comps[] = 'vjud.'.$data['new']['domain']; + }else{ + $tpl->setVar('use_vjud', 'false'); + } + + $tpl->setVar('use_muc', $data['new']['use_muc_host']=='y'?'true':'false'); + if($data['new']['use_muc_host'] == 'y'){ + $status_comps[] = 'muc.'.$data['new']['domain']; + $tpl->setVar('muc_restrict_room_creation', $data['new']['muc_restrict_room_creation']); + $tpl->setVar('muc_name', strlen($data['new']['muc_name']) ? $data['new']['muc_name'] : $data['new']['domain'].' Chatrooms'); + $admins = array(); + foreach(explode(',',$data['new']['muc_admins']) AS $adm){ + $admins[] = trim($adm); + } + $tpl->setVar('muc_admins', "\t\t\"".implode("\",\n\t\t\"",$admins)."\"\n"); + $tpl->setVar('use_pastebin', $data['new']['use_pastebin']=='y'?'true':'false'); + $tpl->setVar('pastebin_expire', intval($data['new']['pastebin_expire_after'])); + $tpl->setVar('pastebin_trigger', $data['new']['pastebin_trigger']); + $tpl->setVar('use_archive', $data['new']['use_http_archive']=='y'?'true':'false'); + $tpl->setVar('archive_join', $data['new']['http_archive_show_join']=='y'?'true':'false'); + $tpl->setVar('archive_status', $data['new']['http_archive_show_status']=='y'?'true':'false'); + + } + + $app->system->file_put_contents($this->xmpp_config_dir.'/hosts/'.$data['new']['domain'].'.cfg.lua', $tpl->grab()); + unset($tpl); + + // Create status host file + if($data['new']['use_status_host']=='y'){ + $tpl = new tpl; + $tpl->newTemplate('metronome_conf_status.master'); + $tpl->setVar('domain', $data['new']['domain']); + $tpl->setVar('status_hosts', "\t\t\"".implode("\",\n\t\t\"",$status_hosts)."\"\n"); + $tpl->setVar('status_comps', "\t\t\"".implode("\",\n\t\t\"",$status_comps)."\"\n"); + $app->system->file_put_contents($this->xmpp_config_dir.'/status/'.$data['new']['domain'].'.cfg.lua', $tpl->grab()); + unset($tpl); + } + } + + function domainDelete($event_name, $data){ + global $app, $conf; + + // get the config + $app->uses("system"); + $domain = $data['old']['domain']; + $folder = str_replace('-', '%2d', str_replace('.', '%2e', $str = urlencode($domain))); + + // Remove config files + $app->system->unlink("/etc/metronome/hosts/$domain.cfg.lua"); + $app->system->unlink("/etc/metronome/status/$domain.cfg.lua"); + $app->system->unlink("/etc/metronome/certs/$domain.cert"); + $app->system->unlink("/etc/metronome/certs/$domain.key"); + $app->system->unlink("/etc/metronome/certs/$domain.csr"); + // Remove all stored data + var_dump('rm -rf /var/lib/metronome/'.$folder); + exec('rm -rf /var/lib/metronome/'.$folder); + exec('rm -rf /var/lib/metronome/*%2e'.$folder); + + $app->services->restartServiceDelayed('metronome', 'restart'); + } + +} // end class + +?> diff --git a/server/server.sh b/server/server.sh index 522e0d5f74..2f3d2fbb82 100755 --- a/server/server.sh +++ b/server/server.sh @@ -1,5 +1,6 @@ #!/bin/sh + PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin . /etc/profile -- GitLab