From cab4ba3af9dfd02c303d3b4714700269133f35bf Mon Sep 17 00:00:00 2001
From: Marius Cramer <m.cramer@pixcept.de>
Date: Tue, 31 Mar 2015 05:35:38 -0400
Subject: [PATCH] Merge branch 'Quest/ispconfig3-master'
---
install/apps/metronome_libs/mod_webpresence/icons/status_offline.png | 0
install/apps/metronome_libs/mod_discoitems.lua | 24
server/conf/metronome_conf_main.master | 3
server/conf/metronome_conf_ssl.master | 72
install/update.php | 9
install/apps/metronome_libs/mod_auth_external/db_isuser.php | 37
install/dist/conf/debian60.conf.php | 4
interface/web/client/lib/lang/en_client.lng | 19
interface/web/mail/xmpp_user_del.php | 72
install/apps/metronome_libs/mod_auth_external/mod_auth_external.lua | 118 +
install/lib/installer_base.lib.php | 123 +
install/sql/ispconfig3.sql | 96 +
install/sql/incremental/upd_dev_collection.sql | 94 +
interface/web/mail/templates/xmpp_domain_list.htm | 74
interface/web/admin/templates/server_list.htm | 3
interface/web/client/lib/lang/en_client_template.lng | 17
interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng | 8
install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh | 38
server/conf/metronome_conf_global.master | 48
interface/web/js/xmpp_domain_registration.js | 29
interface/web/mail/lib/lang/en_xmpp_domain.lng | 62
install/apps/metronome_libs/mod_auth_external/db_conf.inc.php | 6
interface/web/admin/templates/server_edit_services.htm | 6
install/tpl/metronome_conf_main.master | 3
interface/web/mail/form/xmpp_domain.tform.php | 432 +++++
install/apps/metronome_libs/mod_webpresence/icons/status_xa.png | 0
interface/web/mail/templates/xmpp_domain_admin_list.htm | 60
interface/web/js/xmpp_domain_muc.js | 26
interface/web/mail/xmpp_domain_del.php | 93 +
interface/web/mail/xmpp_user_edit.php | 172 ++
server/conf/metronome_conf_status.master | 12
interface/web/mail/templates/xmpp_domain_edit_muc.htm | 91 +
server/conf/metronome_conf_host.master | 135 +
interface/web/mail/lib/lang/en_xmpp_user_list.lng | 8
interface/web/client/form/reseller.tform.php | 99 +
interface/web/admin/lib/lang/en_server.lng | 2
interface/web/admin/lib/lang/en_server_list.lng | 2
interface/web/admin/form/server.tform.php | 6
interface/web/mail/templates/xmpp_user_edit.htm | 47
install/tpl/metronome_conf_ssl.master | 48
interface/web/mail/form/xmpp_user.tform.php | 127 +
interface/web/client/lib/lang/en_reseller.lng | 18
install/tpl/server.ini.master | 9
install/apps/metronome_libs/mod_webpresence/icons/status_away.png | 0
interface/web/admin/form/server_config.tform.php | 80
install/apps/metronome_libs/mod_webpresence/icons/status_chat.png | 0
interface/web/admin/templates/server_config_xmpp_edit.htm | 73
interface/web/admin/list/server.list.php | 9
interface/web/mail/lib/lang/en_xmpp_user.lng | 15
interface/web/client/templates/reseller_edit_limits.htm | 64
interface/web/mail/lib/module.conf.php | 24
interface/web/mail/xmpp_domain_list.php | 28
install/apps/metronome_libs/mod_webpresence/icons/status_dnd.png | 0
interface/web/mail/templates/xmpp_domain_edit.htm | 130 +
install/apps/metronome_libs/mod_webpresence/mod_webpresence.lua | 118 +
interface/web/mail/list/xmpp_domain.list.php | 109 +
interface/web/client/templates/client_template_edit_limits.htm | 65
interface/web/mail/templates/xmpp_domain_edit_modules.htm | 59
install/apps/metronome_libs/mod_webpresence/icons/status_online.png | 0
interface/web/mail/templates/xmpp_user_list.htm | 74
interface/web/client/templates/client_edit_limits.htm | 64
interface/web/client/form/client.tform.php | 99 +
interface/lib/classes/validate_client.inc.php | 4
server/mods-available/xmpp_module.inc.php | 130 +
install/apps/metronome_libs/mod_auth_external/db_auth.php | 58
interface/web/admin/lib/lang/en_server_config.lng | 14
interface/web/mail/list/xmpp_user.list.php | 62
install/apps/metronome-init | 75
server/server.sh | 1
install/install.php | 19
install/tpl/metronome_conf_global.master | 65
interface/web/mail/xmpp_domain_edit.php | 543 ++++++
interface/web/mail/xmpp_user_list.php | 39
interface/web/mail/templates/xmpp_domain_edit_ssl.htm | 100 +
interface/web/client/form/client_template.tform.php | 99 +
install/dist/lib/debian60.lib.php | 4
server/plugins-available/xmpp_plugin.inc.php | 397 ++++
interface/web/mail/lib/lang/en_xmpp_domain_list.lng | 7
78 files changed, 4,979 insertions(+), 1 deletions(-)
diff --git a/install/apps/metronome-init b/install/apps/metronome-init
new file mode 100644
index 0000000..78ba7ea
--- /dev/null
+++ b/install/apps/metronome-init
@@ -0,0 +1,75 @@
+#! /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
+}
+
+reload()
+{
+ &METRONOME reload >> /dev/null
+}
+
+restart()
+{
+ &METRONOME restart >> /dev/null
+}
+
+case "$1" in
+ start)
+ echo -n "Starting Metronome..."
+ start &
+ ;;
+ stop)
+ echo -n "Stopping Metronome..."
+ stop &
+ ;;
+ reload)
+ echo -n "Reloading Metronome config..."
+ reload &
+ ;;
+ restart)
+ echo -n "Restarting Metronome..."
+ restart &
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|reload|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.sh b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh
new file mode 100644
index 0000000..c5a0c8e
--- /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/isp-modules/mod_auth_external/db_auth.php $USER $HOST $PASS 2>/dev/null` == 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/isp-modules/mod_auth_external/db_isuser.php $USER $HOST 2>/dev/null` == 1 ] ; then
+ echo $AUTH_OK
+ [ $USELOG == true ] && { echo "ISUSER OK" >> $LOGFILE; }
+ else
+ echo $AUTH_FAILED
+ [ $USELOG == true ] && { echo "ISUSER FAILED" >> $LOGFILE; }
+ fi
+ ;;
+ *)
+ echo $AUTH_FAILED
+ [ $USELOG == true ] && { echo "UNKNOWN ACTION GIVEN: $ACTION" >> $LOGFILE; }
+ ;;
+ esac
+
+done
diff --git a/install/apps/metronome_libs/mod_auth_external/db_auth.php b/install/apps/metronome_libs/mod_auth_external/db_auth.php
new file mode 100644
index 0000000..086dcf6
--- /dev/null
+++ b/install/apps/metronome_libs/mod_auth_external/db_auth.php
@@ -0,0 +1,58 @@
+<?php
+ini_set('display_errors', false);
+require_once('db_conf.inc.php');
+
+try{
+ // Connect database
+ $db = new mysqli($db_host, $db_user, $db_pass, $db_name);
+ result_false(mysqli_connect_errno());
+
+ // Get arguments
+ $arg_email = '';
+ $arg_password = '';
+
+ result_false(count($argv) != 4);
+ $arg_email = $argv[1].'@'.$argv[2];
+ $arg_password = $argv[3];
+
+ // check for existing user
+ $dbmail = $db->real_escape_string($arg_email);
+ $result = $db->query("SELECT jid, password FROM xmpp_user WHERE jid LIKE '".$dbmail."' AND active='y' AND server_id='".$isp_server_id."'");
+ result_false($result->num_rows != 1);
+
+ $user = $result->fetch_object();
+
+ // check for domain autologin api key
+ $domain_key = 'f47kmm5Yh5hJzSws2KTS';
+
+ checkAuth($argv[1], $argv[2], $arg_password, $user->password, $domain_key);
+}catch(Exception $ex){
+ echo 0;
+ exit();
+}
+
+function result_false($cond = true){
+ if(!$cond) return;
+ echo 0;
+ exit();
+}
+function result_true(){
+ echo 1;
+ exit();
+}
+function checkAuth($user, $domain, $pw_arg, $pw_db, $domain_key){
+ if(crypt($pw_arg, $pw_db) == $pw_db)
+ result_true();
+
+ if($domain_key){
+ $datetime = new DateTime();
+ $datetime->setTimezone(new DateTimeZone("UTC"));
+ for($t = $datetime->getTimestamp(); $t >= $datetime->getTimestamp()-30; $t--){
+ $pw_api = md5($domain.'@'.$domain_key.'@'.$user.'@'.$t);
+ if($pw_api == $pw_arg)
+ result_true();
+ }
+ }
+ result_false();
+}
+?>
\ No newline at end of file
diff --git a/install/apps/metronome_libs/mod_auth_external/db_conf.inc.php b/install/apps/metronome_libs/mod_auth_external/db_conf.inc.php
new file mode 100644
index 0000000..1aba63d
--- /dev/null
+++ b/install/apps/metronome_libs/mod_auth_external/db_conf.inc.php
@@ -0,0 +1,6 @@
+<?php
+$db_user = '{mysql_server_ispconfig_user}';
+$db_pass = '{mysql_server_ispconfig_password}';
+$db_name = '{mysql_server_database}';
+$db_host = '{mysql_server_ip}';
+$isp_server_id = '{server_id}';
\ No newline at end of file
diff --git a/install/apps/metronome_libs/mod_auth_external/db_isuser.php b/install/apps/metronome_libs/mod_auth_external/db_isuser.php
new file mode 100644
index 0000000..7a7cf86
--- /dev/null
+++ b/install/apps/metronome_libs/mod_auth_external/db_isuser.php
@@ -0,0 +1,37 @@
+<?php
+ini_set('display_errors', false);
+require_once('db_conf.inc.php');
+
+try{
+ // Connect database
+ $db = new mysqli($db_host, $db_user, $db_pass, $db_name);
+ result_false(mysqli_connect_errno());
+
+ // Get arguments
+ $arg_email = '';
+
+ result_false(count($argv) != 3);
+ $arg_email = $argv[1].'@'.$argv[2];
+
+ // check for existing user
+ $dbmail = $db->real_escape_string($arg_email);
+ $result = $db->query("SELECT jid, password FROM xmpp_user WHERE jid LIKE '".$dbmail."' AND active='y' AND server_id='".$isp_server_id."'");
+ result_false($result->num_rows != 1);
+ result_true();
+
+}catch(Exception $ex){
+ echo 0;
+ exit();
+}
+
+function result_false($cond = true){
+ if(!$cond) return;
+ echo 0;
+ exit();
+}
+function result_true(){
+ echo 1;
+ exit();
+}
+
+?>
\ 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 0000000..c864006
--- /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 0000000..f05b904
--- /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 0000000..0de5c6a
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/icons/status_away.png
Binary files differ
diff --git a/install/apps/metronome_libs/mod_webpresence/icons/status_chat.png b/install/apps/metronome_libs/mod_webpresence/icons/status_chat.png
new file mode 100644
index 0000000..324f40b
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/icons/status_chat.png
Binary files differ
diff --git a/install/apps/metronome_libs/mod_webpresence/icons/status_dnd.png b/install/apps/metronome_libs/mod_webpresence/icons/status_dnd.png
new file mode 100644
index 0000000..015f3da
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/icons/status_dnd.png
Binary files differ
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 0000000..12db2af
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/icons/status_offline.png
Binary files differ
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 0000000..fb257c3
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/icons/status_online.png
Binary files differ
diff --git a/install/apps/metronome_libs/mod_webpresence/icons/status_xa.png b/install/apps/metronome_libs/mod_webpresence/icons/status_xa.png
new file mode 100644
index 0000000..321d35b
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/icons/status_xa.png
Binary files differ
diff --git a/install/apps/metronome_libs/mod_webpresence/mod_webpresence.lua b/install/apps/metronome_libs/mod_webpresence/mod_webpresence.lua
new file mode 100644
index 0000000..c1de0e0
--- /dev/null
+++ b/install/apps/metronome_libs/mod_webpresence/mod_webpresence.lua
@@ -0,0 +1,118 @@
+module:depends("http");
+
+local jid_split = require "util.jid".prepped_split;
+local b64 = require "util.encodings".base64.encode;
+local sha1 = require "util.hashes".sha1;
+local stanza = require "util.stanza".stanza;
+local json = require "util.json".encode_ordered;
+
+local function require_resource(name)
+ local icon_path = module:get_option_string("presence_icons", "icons");
+ local f, err = module:load_resource(icon_path.."/"..name);
+ if f then
+ return f:read("*a");
+ end
+ module:log("warn", "Failed to open image file %s", icon_path..name);
+ return "";
+end
+
+local statuses = { online = {}, away = {}, xa = {}, dnd = {}, chat = {}, offline = {} };
+
+local function handle_request(event, path)
+ local status, message;
+ local jid, type = path:match("([^/]+)/?(.*)$");
+ if jid then
+ local user, host = jid_split(jid);
+ if host and not user then
+ user, host = host, event.request.headers.host;
+ if host then host = host:gsub(":%d+$", ""); end
+ end
+ if user and host then
+ local user_sessions = hosts[host] and hosts[host].sessions[user];
+ if user_sessions then
+ status = user_sessions.top_resources[1];
+ if status and status.presence then
+ message = status.presence:child_with_name("status");
+ status = status.presence:child_with_name("show");
+ if not status then
+ status = "online";
+ else
+ status = status:get_text();
+ end
+ if message then
+ message = message:get_text();
+ end
+ end
+ end
+ end
+ end
+ status = status or "offline";
+
+ statuses[status].image = function()
+ return { status_code = 200, headers = { content_type = "image/png" },
+ body = require_resource("status_"..status..".png")
+ };
+ end;
+ statuses[status].html = function()
+ local jid_hash = sha1(jid, true);
+ return { status_code = 200, headers = { content_type = "text/html" },
+ body = [[<!DOCTYPE html>]]..
+ 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 = [[<?xml version="1.0" encoding="utf-8"?>]]..
+ 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 a381996..e18faa4 100644
--- a/install/dist/conf/debian60.conf.php
+++ b/install/dist/conf/debian60.conf.php
@@ -222,5 +222,9 @@
$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 584e6aa..fab5628 100644
--- a/install/dist/lib/debian60.lib.php
+++ b/install/dist/lib/debian60.lib.php
@@ -154,6 +154,10 @@
*/
}
+ public function configure_xmpp() {
+ parent::configure_xmpp();
+ }
+
}
?>
diff --git a/install/install.php b/install/install.php
index 91759f2..3aedfef 100644
--- a/install/install.php
+++ b/install/install.php
@@ -347,6 +347,13 @@
}
*/
+ //* 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($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 @@
$conf['services']['db'] = true;
$conf['services']['firewall'] = false;
$conf['services']['proxy'] = false;
+ $conf['services']['xmpp'] = false;
//** Get Server ID
@@ -639,6 +648,16 @@
$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 ae64463..62ff860 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -155,6 +155,7 @@
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,125 @@
}
+ public function configure_xmpp($options = '') {
+ 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__);
+ // Process db config
+ $full_file_name = '/usr/lib/metronome/isp-modules/mod_auth_external/db_conf.inc.php';
+ $content = rf($full_file_name);
+ $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
+ $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
+ $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
+ $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
+ $content = str_replace('{server_id}', $conf['server_id'], $content);
+ wf($full_file_name, $content);
+
+ if(!stristr($options, 'dont-create-certs')){
+ // Create SSL Certificate for localhost
+ echo "writing new private key to 'localhost.key'\n-----\n";
+ $ssl_country = $this->free_query('Country Name (2 letter code)', 'AU');
+ $ssl_locality = $this->free_query('Locality Name (eg, city)', '');
+ $ssl_organisation = $this->free_query('Organization Name (eg, company)', 'Internet Widgits Pty Ltd');
+ $ssl_organisation_unit = $this->free_query('Organizational Unit Name (eg, section)', '');
+ $ssl_domain = $this->free_query('Common Name (e.g. server FQDN or YOUR name)', $conf['hostname']);
+ $ssl_email = $this->free_query('Email Address', '');
+
+ $tpl = new tpl('metronome_conf_ssl.master');
+ $tpl->setVar('ssl_country',$ssl_country);
+ $tpl->setVar('ssl_locality',$ssl_locality);
+ $tpl->setVar('ssl_organisation',$ssl_organisation);
+ $tpl->setVar('ssl_organisation_unit',$ssl_organisation_unit);
+ $tpl->setVar('domain',$ssl_domain);
+ $tpl->setVar('ssl_email',$ssl_email);
+ wf('/etc/metronome/certs/localhost.cnf', $tpl->grab());
+ unset($tpl);
+ // Generate new key, csr and cert
+ exec("(cd /etc/metronome/certs && make localhost.key)");
+ exec("(cd /etc/metronome/certs && make localhost.csr)");
+ exec("(cd /etc/metronome/certs && make localhost.cert)");
+ exec('chmod 0400 /etc/metronome/certs/localhost.key');
+ exec('chown metronome /etc/metronome/certs/localhost.key');
+ }else{
+ echo "-----\n";
+ echo "Metronome XMPP SSL server certificate is not renewed. Run the following command manual as root to recreate it:\n";
+ echo "# (cd /etc/metronome/certs && make localhost.key && make localhost.csr && make localhost.cert && chmod 0400 localhost.key && chown metronome localhost.key)\n";
+ echo "-----\n";
+ }
+
+ // 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__);
+ caselog('update-rc.d metronome defaults', __FILE__, __LINE__);
+
+ exec($this->getinitcommand('xmpp', 'restart'));
+
+/*
+writing new private key to 'smtpd.key'
+-----
+You are about to be asked to enter information that will be incorporated
+into your certificate request.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:
+State or Province Name (full name) [Some-State]:
+Locality Name (eg, city) []:
+Organization Name (eg, company) [Internet Widgits Pty Ltd]:
+Organizational Unit Name (eg, section) []:
+Common Name (e.g. server FQDN or YOUR name) []:
+Email Address []:
+ * */
+
+ /*// 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 +2089,9 @@
$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_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql
index a05084e..6eea12b 100644
--- a/install/sql/incremental/upd_dev_collection.sql
+++ b/install/sql/incremental/upd_dev_collection.sql
@@ -40,3 +40,97 @@
ALTER TABLE `mail_forwarding` ADD `greylisting` ENUM( 'n', 'y' ) NOT NULL DEFAULT 'n' AFTER `active`;
ALTER TABLE `openvz_ip` CHANGE `ip_address` `ip_address` VARCHAR(39) DEFAULT NULL;
+
+-- XMPP Support
+
+ALTER TABLE `server` ADD COLUMN `xmpp_server` tinyint(1) NOT NULL default '0' AFTER `firewall_server`;
+
+ALTER TABLE `client`
+ ADD COLUMN `default_xmppserver` int(11) unsigned NOT NULL DEFAULT '1',
+ ADD COLUMN `xmpp_servers` blob,
+ 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 '',
+
+ `management_method` ENUM( 'normal', 'maildomain' ) NOT NULL default 'normal',
+ `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',
+
+ `ssl_state` varchar(255) NULL,
+ `ssl_locality` varchar(255) NULL,
+ `ssl_organisation` varchar(255) NULL,
+ `ssl_organisation_unit` varchar(255) NULL,
+ `ssl_country` varchar(255) NULL,
+ `ssl_email` varchar(255) NULL,
+ `ssl_request` mediumtext NULL,
+ `ssl_cert` mediumtext NULL,
+ `ssl_bundle` mediumtext NULL,
+ `ssl_key` mediumtext NULL,
+ `ssl_action` varchar(16) NULL,
+
+ `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 ;
+
+--
+-- Table structure for table `xmpp_user`
+--
+
+CREATE TABLE `xmpp_user` (
+ `xmppuser_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',
+ `jid` varchar(255) NOT NULL default '',
+ `password` varchar(255) NOT NULL default '',
+ `active` enum('n','y') NOT NULL DEFAULT 'n',
+ PRIMARY KEY (`xmppuser_id`),
+ KEY `server_id` (`server_id`,`jid`),
+ KEY `jid_active` (`jid`,`active`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+
+-- --------------------------------------------------------
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 9060f36..571d59d 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -184,6 +184,18 @@
`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',
+ `default_xmppserver` int(11) unsigned NOT NULL DEFAULT '1',
+ `xmpp_servers` blob,
+ `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 +1213,7 @@
`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',
@@ -1951,6 +1964,89 @@
) 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 '',
+
+ `management_method` ENUM( 'normal', 'maildomain' ) NOT NULL default 'normal',
+ `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',
+
+ `ssl_state` varchar(255) NULL,
+ `ssl_locality` varchar(255) NULL,
+ `ssl_organisation` varchar(255) NULL,
+ `ssl_organisation_unit` varchar(255) NULL,
+ `ssl_country` varchar(255) NULL,
+ `ssl_email` varchar(255) NULL,
+ `ssl_request` mediumtext NULL,
+ `ssl_cert` mediumtext NULL,
+ `ssl_bundle` mediumtext NULL,
+ `ssl_key` mediumtext NULL,
+ `ssl_action` varchar(16) NULL,
+
+ `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 ;
+
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `xmpp_user`
+--
+
+CREATE TABLE `xmpp_user` (
+ `xmppuser_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',
+ `jid` varchar(255) NOT NULL default '',
+ `password` varchar(255) NOT NULL default '',
+ `active` enum('n','y') NOT NULL DEFAULT 'n',
+ PRIMARY KEY (`xmppuser_id`),
+ KEY `server_id` (`server_id`,`jid`),
+ KEY `jid_active` (`jid`,`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 0000000..68f4c59
--- /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 0000000..f9c8fbd
--- /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/metronome_conf_ssl.master b/install/tpl/metronome_conf_ssl.master
new file mode 100644
index 0000000..922dfd2
--- /dev/null
+++ b/install/tpl/metronome_conf_ssl.master
@@ -0,0 +1,48 @@
+oid_section = new_oids
+
+[ new_oids ]
+
+# RFC 3920 section 5.1.1 defines this OID
+xmppAddr = 1.3.6.1.5.5.7.8.5
+
+# RFC 4985 defines this OID
+SRVName = 1.3.6.1.5.5.7.8.7
+
+[ req ]
+
+default_bits = 4096
+default_keyfile = {tmpl_var name='domain'}.key
+distinguished_name = distinguished_name
+req_extensions = v3_extensions
+x509_extensions = v3_extensions
+
+# ask about the DN?
+prompt = no
+
+[ distinguished_name ]
+
+commonName = {tmpl_var name='domain'}
+countryName = {tmpl_var name='ssl_country'}
+localityName = {tmpl_var name='ssl_locality'}
+organizationName = {tmpl_var name='ssl_organisation'}
+organizationalUnitName = {tmpl_var name='ssl_organisation_unit'}
+emailAddress = {tmpl_var name='ssl_email'}
+
+[ v3_extensions ]
+
+# for certificate requests (req_extensions)
+# and self-signed certificates (x509_extensions)
+
+basicConstraints = CA:FALSE
+keyUsage = digitalSignature,keyEncipherment
+extendedKeyUsage = serverAuth,clientAuth
+subjectAltName = @subject_alternative_name
+
+[ subject_alternative_name ]
+
+# See http://tools.ietf.org/html/draft-ietf-xmpp-3920bis#section-13.7.1.2 for more info.
+
+DNS.0 = {tmpl_var name='domain'}
+otherName.0 = xmppAddr;FORMAT:UTF8,UTF8:{tmpl_var name='domain'}
+otherName.1 = SRVName;IA5STRING:_xmpp-client.{tmpl_var name='domain'}
+otherName.2 = SRVName;IA5STRING:_xmpp-server.{tmpl_var name='domain'}
\ No newline at end of file
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index 7805988..20dca2d 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -145,3 +145,12 @@
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/install/update.php b/install/update.php
index 311c070..8e05318 100644
--- a/install/update.php
+++ b/install/update.php
@@ -392,6 +392,11 @@
$inst->configure_apps_vhost();
}
+ if($conf['services']['xmpp']) {
+ //** Configure Metronome XMPP
+ $inst->configure_xmpp('dont-create-certs');
+ }
+
//* Configure DBServer
swriteln('Configuring Database');
@@ -494,6 +499,10 @@
if($conf['bind']['installed'] == true && $conf['bind']['init_script'] != '') system($inst->getinitcommand($conf['bind']['init_script'], 'restart').' &> /dev/null');
}
+ if($conf['services']['xmpp']) {
+ if($conf['xmpp']['installed'] == true && $conf['xmpp']['init_script'] != '') system($inst->getinitcommand($conf['xmpp']['init_script'], 'restart').' &> /dev/null');
+ }
+
if($conf['services']['proxy']) {
// if($conf['squid']['installed'] == true && $conf['squid']['init_script'] != '' && is_executable($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');
diff --git a/interface/lib/classes/validate_client.inc.php b/interface/lib/classes/validate_client.inc.php
index 198701b..c67601b 100644
--- a/interface/lib/classes/validate_client.inc.php
+++ b/interface/lib/classes/validate_client.inc.php
@@ -122,6 +122,10 @@
case 'mail_servers':
$used_servers = $app->db->queryAllRecords('SELECT domain_id FROM mail_domain INNER JOIN sys_user ON mail_domain.sys_userid = sys_user.userid WHERE client_id = ' . $client_id . ' AND server_id NOT IN (' . implode(', ', $field_value) . ');');
break;
+
+ case 'xmpp_servers':
+ $used_servers = $app->db->queryAllRecords('SELECT domain_id FROM xmpp_domain INNER JOIN sys_user ON xmpp_domain.sys_userid = sys_user.userid WHERE client_id = ' . $client_id . ' AND server_id NOT IN (' . implode(', ', $field_value) . ');');
+ break;
}
if ($used_servers === null || count($used_servers))
diff --git a/interface/web/admin/form/server.tform.php b/interface/web/admin/form/server.tform.php
index a2eac6c..1bf079e 100644
--- a/interface/web/admin/form/server.tform.php
+++ b/interface/web/admin/form/server.tform.php
@@ -102,6 +102,12 @@
'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 6f1c889..351d4de 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"]['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 4130201..1f36bc7 100644
--- a/interface/web/admin/lib/lang/en_server.lng
+++ b/interface/web/admin/lib/lang/en_server.lng
@@ -12,4 +12,6 @@
$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 8affba0..aac7390 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_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 164468e..89a81fa 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["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 0309b7a..0290632 100644
--- a/interface/web/admin/list/server.list.php
+++ b/interface/web/admin/list/server.list.php
@@ -110,4 +110,13 @@
'width' => '',
'value' => array('1' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>", '0' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>"));
+$liste['item'][] = array( 'field' => 'xmpp_server',
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'op' => 'like',
+ 'prefix' => '%',
+ 'suffix' => '%',
+ 'width' => '',
+ 'value' => array('1' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>", '0' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>"));
+
?>
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 0000000..acf019b
--- /dev/null
+++ b/interface/web/admin/templates/server_config_xmpp_edit.htm
@@ -0,0 +1,73 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_use_ipv6_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='xmpp_use_ipv6'}
+ </div>
+</div>
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_bosh_max_inactivity_txt'}</label>
+ <div class="col-sm-3">
+ <input type="number" name="xmpp_bosh_max_inactivity" id="xmpp_bosh_max_inactivity" value="{tmpl_var name='xmpp_bosh_max_inactivity'}" class="form-control" />
+ </div>
+</div>
+
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_server_admins_txt'}</label>
+ <div class="col-sm-9">
+ <input type="text" name="xmpp_server_admins" id="xmpp_server_admins" value="{tmpl_var name='xmpp_server_admins'}" class="form-control" />
+ </div>
+</div>
+
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_modules_enabled_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="xmpp_modules_enabled" id="xmpp_modules_enabled" rows='3' cols='30'>{tmpl_var name='xmpp_modules_enabled'}</textarea></div>
+</div>
+<div class="col-sm-12">
+ <h4>{tmpl_var name='xmpp_ports_txt'}</h4>
+ <div class="col-sm-6">
+ <div class="form-group">
+ <label class="col-sm-6 control-label">{tmpl_var name='xmpp_port_http_txt'}</label>
+ <div class="col-sm-6">
+ <input type="number" name="xmpp_port_http" id="xmpp_port_http" value="{tmpl_var name='xmpp_port_http'}" class="form-control" />
+ </div>
+ </div>
+ </div>
+ <div class="col-sm-6">
+ <div class="form-group">
+ <label class="col-sm-6 control-label">{tmpl_var name='xmpp_port_https_txt'}</label>
+ <div class="col-sm-6">
+ <input type="number" name="xmpp_port_https" id="xmpp_port_https" value="{tmpl_var name='xmpp_port_https'}" class="form-control" />
+ </div>
+ </div>
+ </div>
+ <div class="col-sm-6">
+ <div class="form-group">
+ <label class="col-sm-6 control-label">{tmpl_var name='xmpp_port_pastebin_txt'}</label>
+ <div class="col-sm-6">
+ <input type="number" name="xmpp_port_pastebin" id="xmpp_port_pastebin" value="{tmpl_var name='xmpp_port_pastebin'}" class="form-control" />
+ </div>
+ </div>
+ </div>
+ <div class="col-sm-6">
+ <div class="form-group">
+ <label class="col-sm-6 control-label">{tmpl_var name='xmpp_port_bosh_txt'}</label>
+ <div class="col-sm-6">
+ <input type="number" name="xmpp_port_bosh" id="xmpp_port_bosh" value="{tmpl_var name='xmpp_port_bosh'}" class="form-control" />
+ </div>
+ </div>
+ </div>
+</div>
+
+<input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+<div class="clear"><div class="right">
+ <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="admin/server_config_edit.php">{tmpl_var name='btn_save_txt'}</button>
+ <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="admin/server_config_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+</div></div>
diff --git a/interface/web/admin/templates/server_edit_services.htm b/interface/web/admin/templates/server_edit_services.htm
index aca706a..4a648f4 100644
--- a/interface/web/admin/templates/server_edit_services.htm
+++ b/interface/web/admin/templates/server_edit_services.htm
@@ -45,6 +45,12 @@
</div>
</div>
<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_server_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='xmpp_server'}
+ </div>
+ </div>
+ <div class="form-group">
<label for="mirror_server_id" class="col-sm-3 control-label">{tmpl_var name='mirror_server_id_txt'}</label>
<div class="col-sm-9"><select name="mirror_server_id" id="server_id" class="form-control">
{tmpl_var name='mirror_server_id'}
diff --git a/interface/web/admin/templates/server_list.htm b/interface/web/admin/templates/server_list.htm
index ce568b8..016b0cd 100644
--- a/interface/web/admin/templates/server_list.htm
+++ b/interface/web/admin/templates/server_list.htm
@@ -16,6 +16,7 @@
<th data-column="file_server"><tmpl_var name="file_server_txt"></th>
<th data-column="db_server"><tmpl_var name="db_server_txt"></th>
<th data-column="vserver_server"><tmpl_var name="vserver_server_txt"></th>
+ <th data-column="vserver_server"><tmpl_var name="xmpp_server_txt"></th>
<th class="small-col text-right">{tmpl_var name='search_limit'}</th>
</tr>
<tr>
@@ -26,6 +27,7 @@
<td><select class="form-control" name="search_active">{tmpl_var name='search_file_server'}</select></td>
<td><select class="form-control" name="search_active">{tmpl_var name='search_db_server'}</select></td>
<td><select class="form-control" name="search_active">{tmpl_var name='search_vserver_server'}</select></td>
+ <td><select class="form-control" name="search_active">{tmpl_var name='search_xmpp_server'}</select></td>
<td class="text-right">
<button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="admin/server_list.php"><span class="icon icon-filter"></span></button>
</td>
@@ -41,6 +43,7 @@
<td>{tmpl_var name="file_server"}</td>
<td>{tmpl_var name="db_server"}</td>
<td>{tmpl_var name="vserver_server"}</td>
+ <td>{tmpl_var name="xmpp_server"}</td>
<td class="text-right">
<a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('admin/server_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></button>
</td>
diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php
index 8d2ce89..7507c18 100644
--- a/interface/web/client/form/client.tform.php
+++ b/interface/web/client/form/client.tform.php
@@ -773,6 +773,105 @@
'rows' => '',
'cols' => ''
),
+ 'default_xmppserver' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '1',
+ 'datasource' => array ( 'type' => 'CUSTOM',
+ 'class'=> 'custom_datasource',
+ 'function'=> 'client_servers'
+ ),
+ 'value' => '',
+ 'name' => 'default_xmppserver'
+ ),
+ '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' => '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_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/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php
index b1fd7d3..21f8596 100644
--- a/interface/web/client/form/client_template.tform.php
+++ b/interface/web/client/form/client_template.tform.php
@@ -322,6 +322,105 @@
'rows' => '',
'cols' => ''
),
+ 'default_xmppserver' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '1',
+ 'datasource' => array ( 'type' => 'CUSTOM',
+ 'class'=> 'custom_datasource',
+ 'function'=> 'client_servers'
+ ),
+ 'value' => '',
+ 'name' => 'default_xmppserver'
+ ),
+ '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' => '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_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/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php
index b70c765..75e9fa2 100644
--- a/interface/web/client/form/reseller.tform.php
+++ b/interface/web/client/form/reseller.tform.php
@@ -769,6 +769,105 @@
'rows' => '',
'cols' => ''
),
+ 'default_xmppserver' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'SELECT',
+ 'default' => '1',
+ 'datasource' => array ( 'type' => 'CUSTOM',
+ 'class'=> 'custom_datasource',
+ 'function'=> 'client_servers'
+ ),
+ 'value' => '',
+ 'name' => 'default_xmppserver'
+ ),
+ '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' => '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_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 e7e634b..663d276 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_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,24 @@
$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['limit_xmpp_domain_txt'] = 'Max. number of XMPP domains';
+$wb['limit_xmpp_user_txt'] = 'Max. number of XMPP accounts';
+$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/lib/lang/en_client_template.lng b/interface/web/client/lib/lang/en_client_template.lng
index 9aacf40..a65c1a5 100644
--- a/interface/web/client/lib/lang/en_client_template.lng
+++ b/interface/web/client/lib/lang/en_client_template.lng
@@ -98,4 +98,21 @@
$wb['client_limits_txt'] = 'Client Limits';
$wb['limit_database_quota_txt'] = 'Database quota';
$wb['limit_database_quota_error_notint'] = 'The database quota limit must be a number.';
+
+$wb["xmpp_limits_txt"] = 'XMPP Limits';
+$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['limit_xmpp_domain_txt'] = 'Max. number of XMPP domains';
+$wb['limit_xmpp_user_txt'] = 'Max. number of XMPP accounts';
+$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';
?>
diff --git a/interface/web/client/lib/lang/en_reseller.lng b/interface/web/client/lib/lang/en_reseller.lng
index e23657c..eb47bfd 100644
--- a/interface/web/client/lib/lang/en_reseller.lng
+++ b/interface/web/client/lib/lang/en_reseller.lng
@@ -172,6 +172,24 @@
$wb['customer_no_template_error_regex_txt'] = 'The customer No. template contains invalid characters';
$wb['customer_no_start_txt'] = 'Customer No. start value';
$wb['customer_no_counter_txt'] = 'Customer No. counter';
+
+$wb["xmpp_limits_txt"] = 'XMPP Limits';
+$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['limit_xmpp_domain_txt'] = 'Max. number of XMPP domains';
+$wb['limit_xmpp_user_txt'] = 'Max. number of XMPP accounts';
+$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['limit_domainmodule_error_notint'] = 'Domainmodule limit must be a number.';
diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm
index b0dc73c..ed150b4 100644
--- a/interface/web/client/templates/client_edit_limits.htm
+++ b/interface/web/client/templates/client_edit_limits.htm
@@ -209,6 +209,70 @@
<label for="limit_spamfilter_policy" class="col-sm-3 control-label">{tmpl_var name='limit_spamfilter_policy_txt'}</label>
<div class="col-sm-9"><input type="text" name="limit_spamfilter_policy" id="limit_spamfilter_policy" value="{tmpl_var name='limit_spamfilter_policy'}" class="form-control" /></div></div>
</div>
+ <div class="col-sm-3"></div><div class="col-sm-9"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-xmpp_limits" aria-expanded="false" aria-controls="toggle-xmpp_limits">{tmpl_var name='xmpp_limits_txt'}</button></div>
+ <div id="toggle-xmpp_limits" class="collapse">
+ <div class="form-group">
+ <label for="xmpp_servers" class="col-sm-3 control-label">{tmpl_var name='xmpp_servers_txt'}</label>
+ <div class="col-sm-9"><select data-placeholder="{tmpl_var name='xmpp_servers_placeholder'}" multiple name="xmpp_servers[]" id="xmpp_servers" class="form-control">
+ {tmpl_var name='xmpp_servers'}
+ </select></div>
+ </div>
+ <div class="form-group">
+ <label for="limit_xmpp_domain" class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_domain_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="limit_xmpp_domain" id="limit_xmpp_domain" value="{tmpl_var name='limit_xmpp_domain'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="limit_xmpp_user" class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_user_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="limit_xmpp_user" id="limit_xmpp_user" value="{tmpl_var name='limit_xmpp_user'}" class="form-control" /></div></div>
+ <!--<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_auth_options_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='xmpp_auth_options'}
+ </div>
+ </div>-->
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_muc_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_muc'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_pastebin_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_pastebin'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_httparchive_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_httparchive'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_anon_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_anon'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_vjud_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_vjud'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_proxy_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_proxy'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_status_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_status'}
+ </div>
+ </div>
+
+ </div>
<div class="col-sm-3"></div><div class="col-sm-9"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-database_limits" aria-expanded="false" aria-controls="toggle-database_limits">{tmpl_var name='database_limits_txt'}</button></div>
<div id="toggle-database_limits" class="collapse">
<div class="form-group">
diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm
index 6421d8f..abb6879 100644
--- a/interface/web/client/templates/client_template_edit_limits.htm
+++ b/interface/web/client/templates/client_template_edit_limits.htm
@@ -163,6 +163,71 @@
<label for="limit_spamfilter_policy" class="col-sm-3 control-label">{tmpl_var name='limit_spamfilter_policy_txt'}</label>
<div class="col-sm-9"><input type="text" name="limit_spamfilter_policy" id="limit_spamfilter_policy" value="{tmpl_var name='limit_spamfilter_policy'}" class="form-control" /></div></div>
</div>
+
+ <div class="col-sm-3"></div><div class="col-sm-9"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-xmpp_limits" aria-expanded="false" aria-controls="toggle-xmpp_limits">{tmpl_var name='xmpp_limits_txt'}</button></div>
+ <div id="toggle-xmpp_limits" class="collapse">
+ <div class="form-group">
+ <label for="xmpp_servers" class="col-sm-3 control-label">{tmpl_var name='xmpp_servers_txt'}</label>
+ <div class="col-sm-9"><select data-placeholder="{tmpl_var name='xmpp_servers_placeholder'}" multiple name="xmpp_servers[]" id="xmpp_servers" class="form-control">
+ {tmpl_var name='xmpp_servers'}
+ </select></div>
+ </div>
+ <div class="form-group">
+ <label for="limit_xmpp_domain" class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_domain_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="limit_xmpp_domain" id="limit_xmpp_domain" value="{tmpl_var name='limit_xmpp_domain'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="limit_xmpp_user" class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_user_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="limit_xmpp_user" id="limit_xmpp_user" value="{tmpl_var name='limit_xmpp_user'}" class="form-control" /></div></div>
+ <!--<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_auth_options_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='xmpp_auth_options'}
+ </div>
+ </div>-->
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_muc_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_muc'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_pastebin_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_pastebin'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_httparchive_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_httparchive'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_anon_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_anon'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_vjud_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_vjud'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_proxy_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_proxy'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_status_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_status'}
+ </div>
+ </div>
+
+ </div>
<div class="col-sm-3"></div><div class="col-sm-9"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-database_limits" aria-expanded="false" aria-controls="toggle-database_limits">{tmpl_var name='database_limits_txt'}</button></div>
<div id="toggle-database_limits" class="collapse">
<div class="form-group">
diff --git a/interface/web/client/templates/reseller_edit_limits.htm b/interface/web/client/templates/reseller_edit_limits.htm
index aaefaff..7644b95 100644
--- a/interface/web/client/templates/reseller_edit_limits.htm
+++ b/interface/web/client/templates/reseller_edit_limits.htm
@@ -211,6 +211,70 @@
<label for="limit_spamfilter_policy" class="col-sm-3 control-label">{tmpl_var name='limit_spamfilter_policy_txt'}</label>
<div class="col-sm-9"><input type="text" name="limit_spamfilter_policy" id="limit_spamfilter_policy" value="{tmpl_var name='limit_spamfilter_policy'}" class="form-control" /></div></div>
</div>
+ <div class="col-sm-3"></div><div class="col-sm-9"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-xmpp_limits" aria-expanded="false" aria-controls="toggle-xmpp_limits">{tmpl_var name='xmpp_limits_txt'}</button></div>
+ <div id="toggle-xmpp_limits" class="collapse">
+ <div class="form-group">
+ <label for="xmpp_servers" class="col-sm-3 control-label">{tmpl_var name='xmpp_servers_txt'}</label>
+ <div class="col-sm-9"><select data-placeholder="{tmpl_var name='xmpp_servers_placeholder'}" multiple name="xmpp_servers[]" id="xmpp_servers" class="form-control">
+ {tmpl_var name='xmpp_servers'}
+ </select></div>
+ </div>
+ <div class="form-group">
+ <label for="limit_xmpp_domain" class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_domain_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="limit_xmpp_domain" id="limit_xmpp_domain" value="{tmpl_var name='limit_xmpp_domain'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="limit_xmpp_user" class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_user_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="limit_xmpp_user" id="limit_xmpp_user" value="{tmpl_var name='limit_xmpp_user'}" class="form-control" /></div></div>
+ <!--<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='xmpp_auth_options_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='xmpp_auth_options'}
+ </div>
+ </div>-->
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_muc_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_muc'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_pastebin_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_pastebin'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_httparchive_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_httparchive'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_anon_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_anon'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_vjud_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_vjud'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_proxy_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_proxy'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='limit_xmpp_status_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='limit_xmpp_status'}
+ </div>
+ </div>
+
+ </div>
<div class="col-sm-3"></div><div class="col-sm-9"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-database_limits" aria-expanded="false" aria-controls="toggle-database_limits">{tmpl_var name='database_limits_txt'}</button></div>
<div id="toggle-database_limits" class="collapse">
<div class="form-group">
diff --git a/interface/web/js/xmpp_domain_muc.js b/interface/web/js/xmpp_domain_muc.js
new file mode 100644
index 0000000..9018928
--- /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 0000000..1ce239e
--- /dev/null
+++ b/interface/web/js/xmpp_domain_registration.js
@@ -0,0 +1,29 @@
+$('document').ready(function(){
+ // Not needed as long as maildomain hook is not implemented
+ return;
+ $('#management_method').on('select2-selecting', function(e){
+ val = e.choice ? e.choice.id : e.target.selectedIndex;
+ if(val == 0){
+ //normal
+ $('#toggle-management-normal').addClass('in');
+ $('#toggle-registration-closed').addClass('in');
+ $('#public_registration').trigger('change');
+ }else if(val != undefined){
+ //maildomain
+ $('#toggle-management-normal').removeClass('in');
+ $('#toggle-registration-closed').removeClass('in');
+ }else{
+ $('#toggle-management-normal').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');
+ $('#management_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 0000000..3fe62a2
--- /dev/null
+++ b/interface/web/mail/form/xmpp_domain.tform.php
@@ -0,0 +1,432 @@
+<?php
+
+/*
+ Form Definition
+
+ Tabledefinition
+
+ Datatypes:
+ - INTEGER (Forces the input to Int)
+ - DOUBLE
+ - CURRENCY (Formats the values to currency notation)
+ - VARCHAR (no format check, maxlength: 255)
+ - TEXT (no format check)
+ - DATE (Dateformat, automatic conversion to timestamps)
+
+ Formtype:
+ - TEXT (Textfield)
+ - TEXTAREA (Textarea)
+ - PASSWORD (Password textfield, input is not shown when edited)
+ - SELECT (Select option field)
+ - RADIO
+ - CHECKBOX
+ - CHECKBOXARRAY
+ - FILE
+
+ VALUE:
+ - Wert oder Array
+
+ Hint:
+ The ID field of the database table is not part of the datafield definition.
+ The ID field must be always auto incement (int or bigint).
+
+ Search:
+ - searchable = 1 or searchable = 2 include the field in the search
+ - searchable = 1: this field will be the title of the search result
+ - searchable = 2: this field will be included in the description of the search result
+
+
+*/
+
+$form["title"] = "XMPP Domain";
+$form["description"] = "";
+$form["name"] = "xmpp_domain";
+$form["action"] = "xmpp_domain_edit.php";
+$form["db_table"] = "xmpp_domain";
+$form["db_table_idx"] = "domain_id";
+$form["db_history"] = "yes";
+$form["tab_default"] = "domain";
+$form["list_default"] = "xmpp_domain_list.php";
+$form["auth"] = 'yes'; // yes / no
+
+$form["auth_preset"]["userid"] = 0; // 0 = id of the user, > 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
+
+$muc_available = $muc_pastebin_available = $muc_httparchive_available = $anon_available = $vjud_available = $proxy_available = $status_available = true;
+if(!$app->auth->is_admin()) {
+ $client_group_id = $_SESSION["s"]["user"]["default_group"];
+ $client = $app->db->queryOneRecord("SELECT limit_xmpp_muc, limit_xmpp_anon, limit_xmpp_vjud, limit_xmpp_proxy, limit_xmpp_status, limit_xmpp_pastebin, limit_xmpp_httparchive FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+ if($client['limit_xmpp_muc'] != 'y') $muc_available = false;
+ if($client['limit_xmpp_pastebin'] != 'y' || $client['limit_xmpp_muc'] != 'y') $muc_pastebin_available = false;
+ if($client['limit_xmpp_httparchive'] != 'y' || $client['limit_xmpp_muc'] != 'y') $muc_httparchive_available = false;
+ if($client['limit_xmpp_anon'] != 'y') $anon_available = false;
+ if($client['limit_xmpp_vjud'] != 'y') $vjud_available = false;
+ if($client['limit_xmpp_proxy'] != 'y') $proxy_available= false;
+ if($client['limit_xmpp_status'] != 'y') $status_available = false;
+}
+
+$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
+ ),
+ 'management_method' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '0',
+ 'value' => array(0 => 'Normal', 1 => 'By Mail Domain')
+ ),
+ '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' => "",
+ 'value' => ''
+ ),
+ 'domain_admins' => array(
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ '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_pubsub' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ )
+ //#################################
+ // ENDE Datatable fields
+ //#################################
+ )
+);
+if($anon_available)
+ $form['tabs']['features']['fields']['use_anon_host'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+if($vjud_available){
+ $form['tabs']['features']['fields']['use_vjud'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+ $form['tabs']['features']['fields']['vjud_opt_mode'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '0',
+ 'value' => array(0 => 'Opt-In', 1 => 'Opt-Out')
+ );
+}
+
+if($proxy_available)
+ $form['tabs']['features']['fields']['use_proxy'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+if($status_available)
+ $form['tabs']['features']['fields']['use_status_host'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+
+
+if($muc_available)
+ $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'
+ ),
+ //#################################
+ // ENDE Datatable fields
+ //#################################
+ )
+ );
+if($muc_available && $muc_pastebin_available){
+ $form['tabs']['muc']['fields']['use_pastebin'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+ $form['tabs']['muc']['fields']['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'
+ );
+ $form['tabs']['muc']['fields']['pastebin_trigger'] = array(
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '!paste',
+ 'value' => '',
+ 'width' => '15'
+ );
+}
+if($muc_available && $muc_httparchive_available){
+ $form['tabs']['muc']['fields']['use_http_archive'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+ $form['tabs']['muc']['fields']['http_archive_show_join'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+ $form['tabs']['muc']['fields']['http_archive_show_status'] = array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(0 => 'n', 1 => 'y')
+ );
+}
+
+$form["tabs"]['ssl'] = array (
+ 'title' => "SSL",
+ 'width' => 100,
+ 'template' => "templates/xmpp_domain_edit_ssl.htm",
+ 'readonly' => false,
+ 'fields' => array (
+ //#################################
+ // Begin Datatable fields
+ //#################################
+ 'ssl_state' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'REGEX',
+ 'regex' => '/^(([\.]{0})|([-a-zA-Z0-9._,&äöüÄÖÜ ]{1,255}))$/',
+ 'errmsg'=> 'ssl_state_error_regex'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'ssl_locality' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'REGEX',
+ 'regex' => '/^(([\.]{0})|([-a-zA-Z0-9._,&äöüÄÖÜ ]{1,255}))$/',
+ 'errmsg'=> 'ssl_locality_error_regex'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'ssl_organisation' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'REGEX',
+ 'regex' => '/^(([\.]{0})|([-a-zA-Z0-9._,&äöüÄÖÜ ]{1,255}))$/',
+ 'errmsg'=> 'ssl_organisation_error_regex'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'ssl_organisation_unit' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'validators' => array ( 0 => array ( 'type' => 'REGEX',
+ 'regex' => '/^(([\.]{0})|([-a-zA-Z0-9._,&äöüÄÖÜ ]{1,255}))$/',
+ 'errmsg'=> 'ssl_organistaion_unit_error_regex'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'ssl_country' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'datasource' => array ( 'type' => 'SQL',
+ 'querystring' => 'SELECT iso,printable_name FROM country ORDER BY printable_name',
+ 'keyfield'=> 'iso',
+ 'valuefield'=> 'printable_name'
+ ),
+ 'value' => ''
+ ),
+ 'ssl_email' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255',
+ 'validators' => array ( 0 => array ( 'type' => 'ISEMAIL',
+ 'errmsg'=> 'ssl_error_isemail')
+ ),
+ ),
+ 'ssl_key' => array (
+ 'datatype' => 'TEXT',
+ 'formtype' => 'TEXTAREA',
+ 'default' => '',
+ 'value' => '',
+ 'cols' => '30',
+ 'rows' => '10'
+ ),
+ 'ssl_request' => array (
+ 'datatype' => 'TEXT',
+ 'formtype' => 'TEXTAREA',
+ 'default' => '',
+ 'value' => '',
+ 'cols' => '30',
+ 'rows' => '10'
+ ),
+ 'ssl_cert' => array (
+ 'datatype' => 'TEXT',
+ 'formtype' => 'TEXTAREA',
+ 'default' => '',
+ 'value' => '',
+ 'cols' => '30',
+ 'rows' => '10'
+ ),
+ 'ssl_bundle' => array (
+ 'datatype' => 'TEXT',
+ 'formtype' => 'TEXTAREA',
+ 'default' => '',
+ 'value' => '',
+ 'cols' => '30',
+ 'rows' => '10'
+ ),
+ 'ssl_action' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'SELECT',
+ 'default' => '',
+ 'value' => array('' => 'none_txt', 'save' => 'save_certificate_txt', 'create' => 'create_certificate_txt', 'del' => 'delete_certificate_txt')
+ ),
+ //#################################
+ // ENDE Datatable fields
+ //#################################
+ )
+);
+
+
+?>
diff --git a/interface/web/mail/form/xmpp_user.tform.php b/interface/web/mail/form/xmpp_user.tform.php
new file mode 100644
index 0000000..c736078
--- /dev/null
+++ b/interface/web/mail/form/xmpp_user.tform.php
@@ -0,0 +1,127 @@
+<?php
+
+/*
+ Form Definition
+
+ Tabledefinition
+
+ Datatypes:
+ - INTEGER (Forces the input to Int)
+ - DOUBLE
+ - CURRENCY (Formats the values to currency notation)
+ - VARCHAR (no format check, maxlength: 255)
+ - TEXT (no format check)
+ - DATE (Dateformat, automatic conversion to timestamps)
+
+ Formtype:
+ - TEXT (Textfield)
+ - TEXTAREA (Textarea)
+ - PASSWORD (Password textfield, input is not shown when edited)
+ - SELECT (Select option field)
+ - RADIO
+ - CHECKBOX
+ - CHECKBOXARRAY
+ - FILE
+
+ VALUE:
+ - Wert oder Array
+
+ Hint:
+ The ID field of the database table is not part of the datafield definition.
+ The ID field must be always auto incement (int or bigint).
+
+ Search:
+ - searchable = 1 or searchable = 2 include the field in the search
+ - searchable = 1: this field will be the title of the search result
+ - searchable = 2: this field will be included in the description of the search result
+
+
+*/
+global $app;
+$app->uses('getconf');
+$global_config = $app->getconf->get_global_config();
+
+$form["title"] = "XMPP Account";
+$form["description"] = "";
+$form["name"] = "xmpp_user";
+$form["action"] = "xmpp_user_edit.php";
+$form["db_table"] = "xmpp_user";
+$form["db_table_idx"] = "xmppuser_id";
+$form["db_history"] = "yes";
+$form["tab_default"] = "xmppuser";
+$form["list_default"] = "xmpp_user_list.php";
+$form["auth"] = 'yes'; // yes / no
+
+$form["auth_preset"]["userid"] = 0; // 0 = id of the user, > 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"]['xmppuser'] = array(
+ 'title' => "XMPP Account",
+ 'width' => 100,
+ 'template' => "templates/xmpp_user_edit.htm",
+ 'fields' => array (
+ //#################################
+ // Begin Datatable fields
+ //#################################
+ 'server_id' => array (
+ 'datatype' => 'INTEGER',
+ 'formtype' => 'TEXT',
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'jid' => 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' => 'ISEMAIL',
+ 'errmsg'=> 'jid_error_isemail'),
+ 1 => array ( 'type' => 'UNIQUE',
+ 'errmsg'=> 'jid_error_unique'),
+ ),
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255',
+ 'searchable' => 1
+ ),
+ 'password' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'PASSWORD',
+ 'validators' => array(
+ 0 => array(
+ 'type' => 'CUSTOM',
+ 'class' => 'validate_password',
+ 'function' => 'password_check',
+ 'errmsg' => 'weak_password_txt'
+ )
+ ),
+ 'encryption'=> 'CRYPT',
+ 'default' => '',
+ 'value' => '',
+ 'width' => '30',
+ 'maxlength' => '255'
+ ),
+ 'active' => array (
+ 'datatype' => 'VARCHAR',
+ 'formtype' => 'CHECKBOX',
+ 'default' => 'y',
+ 'value' => array(1 => 'y', 0 => 'n')
+ ),
+ //#################################
+ // END 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 0000000..f1da77b
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_xmpp_domain.lng
@@ -0,0 +1,62 @@
+<?php
+$wb["server_id_txt"] = 'Server';
+$wb["client_group_id_txt"] = 'Client';
+$wb["domain_txt"] = 'Domain';
+$wb["type_txt"] = 'Type';
+$wb["active_txt"] = 'Active';
+$wb["client_txt"] = 'Client';
+$wb["management_method_txt"] = 'Management of user accounts';
+$wb["public_registration_txt"] = 'Enable public registration';
+$wb["registration_url_txt"] = 'Registration URL';
+$wb["registration_message_txt"] = 'Registration Message';
+$wb["domain_admins_txt"] = 'Domain Admins (JIDs)';
+$wb["use_pubsub_txt"] = 'Enable Pubsub';
+$wb["use_proxy_txt"] = 'Enable Bytestream Proxy';
+$wb["use_anon_host_txt"] = 'Enable Anonymous Host';
+$wb["use_vjud_txt"] = 'Enable VJUD User Directory';
+$wb["vjud_opt_mode_txt"] = 'VJUD Opt Mode';
+$wb["use_muc_host_txt"] = 'Enable Multi User Chatrooms';
+$wb["muc_name_txt"] = 'Name in MUC Service Discovery';
+$wb["muc_restrict_room_creation_txt"] = 'Permission to create chatrooms';
+$wb["muc_admins_txt"] = 'MUC Admins (JIDs)';
+$wb["use_pastebin_txt"] = 'Enable Pastebin';
+$wb["pastebin_expire_after_txt"] = 'Pastes expire after (hours)';
+$wb["pastebin_trigger_txt"] = 'Pastebin trigger';
+$wb["use_http_archive_txt"] = 'Enable HTTP chatroom archive';
+$wb["http_archive_show_join_txt"] = 'Show join messages in archive';
+$wb["http_archive_show_status_txt"] = 'Show status changes in archive';
+$wb["use_status_host_txt"] = 'Enable XML Status host';
+$wb["cant_change_domainname_txt"] = 'The Domain name of existing XMPP domain cannot be changed.';
+$wb["about_registration_url_txt"] = 'Link to your registration form.';
+$wb["about_registration_message_txt"] = 'Description about your account registration process.';
+$wb["no_corresponding_maildomain_txt"] = 'Corresponding mail domain for user management not found. Please create the mail domain first.';
+$wb['ssl_state_txt'] = 'State';
+$wb['ssl_locality_txt'] = 'Locality';
+$wb['ssl_organisation_txt'] = 'Organisation';
+$wb['ssl_organisation_unit_txt'] = 'Organisation Unit';
+$wb['ssl_country_txt'] = 'Country';
+$wb['ssl_key_txt'] = 'SSL Key';
+$wb['ssl_request_txt'] = 'SSL Request';
+$wb['ssl_cert_txt'] = 'SSL Certificate';
+$wb['ssl_bundle_txt'] = 'SSL Bundle';
+$wb['ssl_action_txt'] = 'SSL Action';
+$wb['ssl_email_txt'] = 'Email Address';
+$wb['ssl_txt'] = 'SSL';
+$wb['error_ssl_state_empty'] = 'SSL State is empty.';
+$wb['error_ssl_locality_empty'] = 'SSL Locality is empty.';
+$wb['error_ssl_organisation_empty'] = 'SSL Organisation is empty.';
+$wb['error_ssl_organisation_unit_empty'] = 'SSL Organisation Unit is empty.';
+$wb['error_ssl_country_empty'] = 'SSL Country is empty.';
+$wb['error_ssl_cert_empty'] = 'SSL Certificate field is empty';
+$wb['ssl_state_error_regex'] = 'Invalid SSL State. Valid characters are: a-z, 0-9 and .,-_&äöüÄÖÜ';
+$wb['ssl_locality_error_regex'] = 'Invalid SSL Locality. Valid characters are: a-z, 0-9 and .,-_&äöüÄÖÜ';
+$wb['ssl_organisation_error_regex'] = 'Invalid SSL Organisation. Valid characters are: a-z, 0-9 and .,-_&äöüÄÖÜ';
+$wb['ssl_organistaion_unit_error_regex'] = 'Invalid SSL Organisation Unit. Valid characters are: a-z, 0-9 and .,-_&äöüÄÖÜ';
+$wb['ssl_country_error_regex'] = 'Invalid SSL Country. Valid characters are: A-Z';
+$wb['none_txt'] = 'None';
+$wb['save_certificate_txt'] = 'Save certificate';
+$wb['create_certificate_txt'] = 'Create certificate';
+$wb['delete_certificate_txt'] = 'Delete certificate';
+$wb['ssl_error_isemail'] = 'Please enter a valid email adress for generation of the SSL certificate';
+$wb["limit_xmppdomain_txt"] = 'The max. number of XMPP domains for your account is reached.';
+?>
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 0000000..a3d1736
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng
@@ -0,0 +1,8 @@
+<?php
+$wb["list_head_txt"] = 'XMPP Domain';
+$wb["server_id_txt"] = 'Server';
+$wb["domain_txt"] = 'Domain';
+$wb["add_new_record_txt"] = 'Add new Domain';
+$wb["active_txt"] = 'Active';
+$wb["sys_groupid_txt"] = 'Client';
+?>
\ 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 0000000..f8c2fb9
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_xmpp_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb["list_head_txt"] = 'XMPP Domain';
+$wb["server_id_txt"] = 'Server';
+$wb["domain_txt"] = 'Domain';
+$wb["add_new_record_txt"] = 'Add new Domain';
+$wb["active_txt"] = 'Active';
+?>
\ No newline at end of file
diff --git a/interface/web/mail/lib/lang/en_xmpp_user.lng b/interface/web/mail/lib/lang/en_xmpp_user.lng
new file mode 100644
index 0000000..1cc852e
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_xmpp_user.lng
@@ -0,0 +1,15 @@
+<?php
+$wb["list_head_txt"] = 'XMPP User Accounts';
+$wb["jid_txt"] = 'Jabber ID';
+$wb["active_txt"] = 'Active';
+$wb["cryptpwd_txt"] = 'Password';
+$wb["password_strength_txt"] = 'Password strength';
+$wb["error_no_pwd"] = 'Password is empty.';
+$wb["password_txt"] = 'Password';
+$wb['generate_password_txt'] = 'Generate Password';
+$wb['repeat_password_txt'] = 'Repeat Password';
+$wb['password_mismatch_txt'] = 'The passwords do not match.';
+$wb['password_match_txt'] = 'The passwords do match.';
+$wb["no_domain_perm"] = 'You have no permission for this domain.';
+$wb["limit_xmpp_user_txt"] = 'The max. number of xmpp accounts for your account is reached.';
+?>
\ No newline at end of file
diff --git a/interface/web/mail/lib/lang/en_xmpp_user_list.lng b/interface/web/mail/lib/lang/en_xmpp_user_list.lng
new file mode 100644
index 0000000..db88b0d
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_xmpp_user_list.lng
@@ -0,0 +1,8 @@
+<?php
+$wb["list_head_txt"] = 'XMPP User Accounts';
+$wb["jid_txt"] = 'Jabber ID';
+$wb["is_domain_admin_txt"] = 'Domain admin';
+$wb["is_muc_admin_txt"] = 'MUC admin';
+$wb["add_new_record_txt"] = 'Add new user';
+$wb["active_txt"] = 'Active';
+?>
\ 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 2ca9b7a..b6df07e 100644
--- a/interface/web/mail/lib/module.conf.php
+++ b/interface/web/mail/lib/module.conf.php
@@ -148,6 +148,30 @@
'items' => $items);
}
+//**** XMPP Menu
+$items = array();
+
+if($app->auth->get_client_limit($userid, 'xmpp_domain') != 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, 'xmpp_user') != 0)
+{
+ $items[] = array( 'title' => 'XMPP Account',
+ 'target' => 'content',
+ 'link' => 'mail/xmpp_user_list.php',
+ 'html_id' => 'xmpp_user_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 0000000..21257e4
--- /dev/null
+++ b/interface/web/mail/list/xmpp_domain.list.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ Datatypes:
+ - INTEGER
+ - DOUBLE
+ - CURRENCY
+ - VARCHAR
+ - TEXT
+ - DATE
+*/
+
+
+
+// Name of the list
+if($_SESSION['s']['user']['typ'] == 'admin') {
+ $liste["name"] = "xmpp_domain_admin";
+} else {
+ $liste["name"] = "xmpp_domain";
+}
+
+// Database table
+$liste["table"] = "xmpp_domain";
+
+// Index index field of the database table
+$liste["table_idx"] = "domain_id";
+
+// Search Field Prefix
+$liste["search_prefix"] = "search_";
+
+// Records per page
+$liste["records_per_page"] = "15";
+
+// Script File of the list
+$liste["file"] = "xmpp_domain_list.php";
+
+// Script file of the edit form
+$liste["edit_file"] = "xmpp_domain_edit.php";
+
+// Script File of the delete script
+$liste["delete_file"] = "xmpp_domain_del.php";
+
+// Paging Template
+$liste["paging_tpl"] = "templates/paging.tpl.htm";
+
+// Enable auth
+$liste["auth"] = "yes";
+
+
+/*****************************************************
+* Suchfelder
+*****************************************************/
+
+
+$liste["item"][] = array( 'field' => "active",
+ 'datatype' => "VARCHAR",
+ 'formtype' => "SELECT",
+ 'op' => "=",
+ 'prefix' => "",
+ 'suffix' => "",
+ 'width' => "",
+ 'value' => array('y' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>", 'n' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>"));
+
+
+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/list/xmpp_user.list.php b/interface/web/mail/list/xmpp_user.list.php
new file mode 100644
index 0000000..c1cdbb8
--- /dev/null
+++ b/interface/web/mail/list/xmpp_user.list.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ Datatypes:
+ - INTEGER
+ - DOUBLE
+ - CURRENCY
+ - VARCHAR
+ - TEXT
+ - DATE
+*/
+
+
+
+// Name of the list
+$liste["name"] = "xmpp_user";
+
+// Database table
+$liste["table"] = "xmpp_user";
+
+// Index index field of the database table
+$liste["table_idx"] = "xmppuser_id";
+
+// Search Field Prefix
+$liste["search_prefix"] = "search_";
+
+// Records per page
+$liste["records_per_page"] = "15";
+
+// Script File of the list
+$liste["file"] = "xmpp_user_list.php";
+
+// Script file of the edit form
+$liste["edit_file"] = "xmpp_user_edit.php";
+
+// Script File of the delete script
+$liste["delete_file"] = "xmpp_user_del.php";
+
+// Paging Template
+$liste["paging_tpl"] = "templates/paging.tpl.htm";
+
+// Enable auth
+$liste["auth"] = "yes";
+
+
+/*****************************************************
+* Suchfelder
+*****************************************************/
+
+$liste["item"][] = array( 'field' => "JID",
+ '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 0000000..ccda2d5
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_domain_admin_list.htm
@@ -0,0 +1,60 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+
+
+ <p class="fieldset-legend">{tmpl_var name="toolsarea_head_txt"}</p>
+
+ <button class="btn btn-default formbutton-success" type="button" data-load-content="mail/xmpp_domain_edit.php">{tmpl_var name="add_new_record_txt"}</button>
+
+
+
+
+ <p class="fieldset-legend"><tmpl_var name="list_head_txt"></p>
+ <div class="table-wrapper marginTop15">
+<table class="table">
+ <thead class="dark form-group-sm">
+ <tr>
+ <th class="tiny-col" data-column="active"><tmpl_var name="active_txt"></th>
+ <th data-column="sys_groupid"><tmpl_var name="sys_groupid_txt"></th>
+ <th data-column="server_id"><tmpl_var name="server_id_txt"></th>
+ <th data-column="domain"><tmpl_var name="domain_txt"></th>
+ <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
+ </tr>
+ <tr>
+ <td><select class="form-control" name="search_active">{tmpl_var name='search_active'}</select></td>
+ <td><select class="form-control" name="search_sys_groupid">{tmpl_var name='search_sys_groupid'}</select></td>
+ <td><select class="form-control" name="search_server_id">{tmpl_var name='search_server_id'}</select></td>
+ <td><input class="form-control" type="text" name="search_domain" value="{tmpl_var name='search_domain'}" /></td>
+ <td class="text-right">
+ <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="mail/xmpp_domain_list.php"><span class="icon icon-filter"></span></button>
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tmpl_loop name="records">
+ <tr>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="active"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="sys_groupid"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="server_id"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="domain"}</a></td>
+ <td class="text-right">
+ <a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('mail/xmpp_domain_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></button>
+ </td>
+ </tr>
+ </tmpl_loop>
+ <tmpl_unless name="records">
+ <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td colspan="5">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+ </tr>
+ </tmpl_unless>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="5"><tmpl_var name="paging"></td>
+ </tr>
+ </tfoot>
+ </table>
+</div>
+
+
\ 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 0000000..5c4e8d7
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_domain_edit.htm
@@ -0,0 +1,130 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+
+ <tmpl_if name="is_admin">
+ <div class="form-group">
+ <tmpl_if name="edit_disabled">
+ <label for="server_id_disabled" class="col-sm-3 control-label">{tmpl_var name='server_id_txt'}</label>
+ <div class="col-sm-9"><select name="server_id_disabled" id="server_id_disabled" class="form-control" disabled="disabled">
+ {tmpl_var name='server_id'}
+ </select></div>
+ <input type="hidden" name="server_id" value="{tmpl_var name='server_id_value'}" />
+ <tmpl_else>
+ <label for="server_id" class="col-sm-3 control-label">{tmpl_var name='server_id_txt'}</label>
+ <div class="col-sm-9"><select name="server_id" id="server_id" class="form-control">
+ {tmpl_var name='server_id'}
+ </select></div>
+ </tmpl_if>
+ </div>
+ <tmpl_unless name="domain_option">
+ <div class="form-group">
+ <label for="client_group_id" class="col-sm-3 control-label">{tmpl_var name='client_group_id_txt'}</label>
+ <div class="col-sm-9"><select name="client_group_id" id="client_group_id" class="form-control">
+ {tmpl_var name='client_group_id'}
+ </select></div>
+ </div>
+ </tmpl_unless>
+ <tmpl_else>
+ <tmpl_if name="only_one_server">
+ <input type="hidden" id="server_id" name="server_id" value="{tmpl_var name='server_id_value'}" />
+ <tmpl_else>
+ <div class="form-group">
+ <tmpl_if name="edit_disabled">
+ <label for="server_id_disabled" class="col-sm-3 control-label">{tmpl_var name='server_id_txt'}</label>
+ <div class="col-sm-9"><select name="server_id_disabled" id="server_id_disabled" class="form-control" disabled="disabled">
+ {tmpl_var name='client_server_id'}
+ </select></div>
+ <input type="hidden" name="server_id" value="{tmpl_var name='server_id_value'}" />
+ <tmpl_else>
+ <label for="server_id" class="col-sm-3 control-label">{tmpl_var name='server_id_txt'}</label>
+ <div class="col-sm-9"><select name="server_id" id="server_id" class="form-control">
+ {tmpl_var name='client_server_id'}
+ </select></div>
+ </tmpl_if>
+ </div>
+ </tmpl_if>
+ </tmpl_if>
+
+ <tmpl_if name="is_reseller">
+ <tmpl_unless name="domain_option">
+ <div class="form-group">
+ <label for="client_group_id" class="col-sm-3 control-label">{tmpl_var name='client_group_id_txt'}</label>
+ <div class="col-sm-9"><select name="client_group_id" id="client_group_id" class="form-control">
+ {tmpl_var name='client_group_id'}
+ </select></div>
+ </div>
+ </tmpl_unless>
+ </tmpl_if>
+
+ <div class="form-group">
+ <label for="domain" class="col-sm-3 control-label">{tmpl_var name='domain_txt'}</label>
+ <tmpl_if name="domain_option">
+ <div class="col-sm-9"><select name="domain" id="domain" class="form-control">
+ {tmpl_var name='domain_option'}
+ </select></div>
+ <tmpl_else>
+ <div class="col-sm-9"><input type="text" name="domain" id="domain" value="{tmpl_var name='domain'}" class="form-control" <tmpl_if name="edit_disabled">readonly="readonly"</tmpl_if>/></div></tmpl_if>
+ </div>
+
+
+
+
+<!--
+management by maildomain is currently not supported
+<div class="form-group">
+ <label for="management_method" class="col-sm-3 control-label">{tmpl_var name='management_method_txt'}</label>
+ <div class="col-sm-9"><select name="management_method" id="management_method" class="form-control">
+ {tmpl_var name='management_method'}
+ </select></div>
+</div>
+-->
+<input type="hidden" name="management_method" id="management_method" value="0" />
+
+<div id="toggle-management-normal" class="collapse">
+ <!--
+ Currently not supported
+ div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='public_registration_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='public_registration'}
+ </div>
+ </div-->
+</div>
+ <input type="hidden" name="public_registration" id="public_registration" value="n" />
+<div id="toggle-registration-closed" class="collapse in">
+ <div class="form-group">
+ <label for="registration_url" class="col-sm-3 control-label">{tmpl_var name='registration_url_txt'}</label>
+ <div class="col-sm-9">
+ <input type="text" name="registration_url" id="registration_url" value="{tmpl_var name='registration_url'}" class="form-control" placeholder="<tmpl_var name='about_registration_url_txt'>" />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='registration_message_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="registration_message" id="registration_message" rows='3' cols='30' placeholder="<tmpl_var name='about_registration_message_txt'>">{tmpl_var name='registration_message'}</textarea></div>
+ </div>
+</div>
+
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='domain_admins_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="domain_admins" id="domain_admins" rows='3' cols='30' placeholder="admin@service.com, superuser@service.com">{tmpl_var name='domain_admins'}</textarea></div>
+</div>
+
+
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='active_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='active'}
+ </div>
+</div>
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+ <input type="hidden" name="type" value="domain">
+ <div class="clear"><div class="right">
+ <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="mail/xmpp_domain_edit.php">{tmpl_var name='btn_save_txt'}</button>
+ <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="mail/xmpp_domain_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+ </div></div>
+<script language="JavaScript" type="text/javascript" src="js/xmpp_domain_registration.js"></script>
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 0000000..8efcf50
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_domain_edit_modules.htm
@@ -0,0 +1,59 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+<tmpl_if name="limit_xmpp_anon" value="y">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_anon_host_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_anon_host'}
+ </div>
+ </div>
+</tmpl_if>
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_pubsub_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_pubsub'}
+ </div>
+</div>
+<tmpl_if name="limit_xmpp_vjud" value="y">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_vjud_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_vjud'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="vjud_opt_mode" class="col-sm-3 control-label">{tmpl_var name='vjud_opt_mode_txt'}</label>
+ <div class="col-sm-3"><select name="vjud_opt_mode" id="vjud_opt_mode" class="form-control">
+ {tmpl_var name='vjud_opt_mode'}
+ </select></div>
+ </div>
+</tmpl_if>
+<tmpl_if name="limit_xmpp_proxy" value="y">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_proxy_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_proxy'}
+ </div>
+ </div>
+</tmpl_if>
+<tmpl_if name="limit_xmpp_status" value="y">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_status_host_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_status_host'}
+ </div>
+ </div>
+</tmpl_if>
+
+
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+ <input type="hidden" name="type" value="modules" />
+ <div class="clear"><div class="right">
+ <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="mail/xmpp_domain_edit.php">{tmpl_var name='btn_save_txt'}</button>
+ <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="mail/xmpp_domain_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+ </div></div>
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 0000000..dd46514
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_domain_edit_muc.htm
@@ -0,0 +1,91 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+
+<div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_muc_host_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_muc_host'}
+ </div>
+</div>
+
+<div id="toggle-use-muc" class="collapse">
+ <div class="form-group">
+ <label for="muc_name" class="col-sm-3 control-label">{tmpl_var name='muc_name_txt'}</label>
+ <div class="col-sm-9">
+ <input type="text" name="muc_name" id="muc_name" value="{tmpl_var name='muc_name'}" class="form-control" maxlength="30" />
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="muc_restrict_room_creation" class="col-sm-3 control-label">{tmpl_var name='muc_restrict_room_creation_txt'}</label>
+ <div class="col-sm-3"><select name="muc_restrict_room_creation" id="muc_restrict_room_creation" class="form-control">
+ {tmpl_var name='muc_restrict_room_creation'}
+ </select></div>
+ </div>
+ <div class="form-group">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='muc_admins_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="muc_admins" id="muc_admins" rows='3' cols='30'>{tmpl_var name='muc_admins'}</textarea></div>
+ </div>
+ </div>
+
+ <tmpl_if name='limit_xmpp_pastebin' value="y">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_pastebin_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_pastebin'}
+ </div>
+ </div>
+ <div id="toggle-use-pastebin" class="collapse">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='pastebin_expire_after_txt'}</label>
+ <div class="col-sm-3">
+ <input type="number" name="pastebin_expire_after" id="pastebin_expire_after" value="{tmpl_var name='pastebin_expire_after'}" class="form-control" />
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='pastebin_trigger_txt'}</label>
+ <div class="col-sm-3">
+ <input type="text" name="pastebin_trigger" id="pastebin_trigger" value="{tmpl_var name='pastebin_trigger'}" class="form-control" />
+ </div>
+ </div>
+ </div>
+ </tmpl_if>
+
+ <tmpl_if name='limit_xmpp_httparchive' value="y">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='use_http_archive_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='use_http_archive'}
+ </div>
+ </div>
+ <div id="toggle-use-archive" class="collapse">
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='http_archive_show_join_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='http_archive_show_join'}
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='http_archive_show_status_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='http_archive_show_status'}
+ </div>
+ </div>
+ </div>
+ </tmpl_if>
+
+</div>
+
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+ <input type="hidden" name="type" value="muc" />
+ <div class="clear"><div class="right">
+ <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="mail/xmpp_domain_edit.php">{tmpl_var name='btn_save_txt'}</button>
+ <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="mail/xmpp_domain_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+ </div></div>
+<script language="JavaScript" type="text/javascript" src="js/xmpp_domain_muc.js"></script>
diff --git a/interface/web/mail/templates/xmpp_domain_edit_ssl.htm b/interface/web/mail/templates/xmpp_domain_edit_ssl.htm
new file mode 100644
index 0000000..2bb7d05
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_domain_edit_ssl.htm
@@ -0,0 +1,100 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<tmpl_if name="config_error_msg">
+<div style="background: #ffdfdf; border: 1px solid #df7d7d; border-width: 1px 0; margin: 1.5em 0 1.5em 0; padding: 7px;">
+ <p style="font-face:bold">{tmpl_var name='configuration_error_txt'}</p>
+ <div>
+ <div style="float:left;width:150px;">{tmpl_var name='config_error_tstamp'} : </div><div style="padding-left:150px;">{tmpl_var name='config_error_msg'}</div>
+ </div>
+</div>
+</tmpl_if>
+
+
+ <tmpl_if name='show_helper_links'>
+ <div id="show_helper_links" style="display:none;">
+ <label></label>
+ <div class="col-sm-9">
+ <a href="javascript:void(0);" id="load_data"><tmpl_if name='is_admin'>{tmpl_var name='load_client_data_txt'}</tmpl_else>{tmpl_var name='load_my_data_txt'}</tmpl_if></a> <a href="javascript:void(0);" id="reset_data">{tmpl_var name='reset_client_data_txt'}</a>
+ </div>
+ </div>
+ </tmpl_if>
+ <div class="form-group">
+ <label for="ssl_state" class="col-sm-3 control-label">{tmpl_var name='ssl_state_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="ssl_state" id="ssl_state" value="{tmpl_var name='ssl_state'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="ssl_locality" class="col-sm-3 control-label">{tmpl_var name='ssl_locality_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="ssl_locality" id="ssl_locality" value="{tmpl_var name='ssl_locality'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="ssl_organisation" class="col-sm-3 control-label">{tmpl_var name='ssl_organisation_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="ssl_organisation" id="ssl_organisation" value="{tmpl_var name='ssl_organisation'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="ssl_organisation_unit" class="col-sm-3 control-label">{tmpl_var name='ssl_organisation_unit_txt'}</label>
+ <div class="col-sm-9"><input type="text" name="ssl_organisation_unit" id="ssl_organisation_unit" value="{tmpl_var name='ssl_organisation_unit'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="ssl_country" class="col-sm-3 control-label">{tmpl_var name='ssl_country_txt'}</label>
+ <div class="col-sm-9"><select name="ssl_country" id="ssl_country" class="form-control flags">
+ {tmpl_var name='ssl_country'}
+ </select></div>
+ </div>
+ <div class="form-group">
+ <label for="ssl_email" class="col-sm-3 control-label">{tmpl_var name='ssl_email_txt'}</label>
+ <div class="col-sm-9"><input type="email" name="ssl_email" id="ssl_email" value="{tmpl_var name='ssl_email'}" class="form-control" /></div></div>
+ <div class="form-group">
+ <label for="ssl_request" class="col-sm-3 control-label">{tmpl_var name='ssl_key_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="ssl_key" id="ssl_key" rows='10' cols='30'>{tmpl_var name='ssl_key'}</textarea></div>
+ </div>
+ <div class="form-group">
+ <label for="ssl_request" class="col-sm-3 control-label">{tmpl_var name='ssl_request_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="ssl_request" id="ssl_request" rows='10' cols='30'>{tmpl_var name='ssl_request'}</textarea></div>
+ </div>
+ <div class="form-group">
+ <label for="ssl_cert" class="col-sm-3 control-label">{tmpl_var name='ssl_cert_txt'}</label>
+ <div class="col-sm-9"><textarea class="form-control" name="ssl_cert" id="ssl_cert" rows='10' cols='30'>{tmpl_var name='ssl_cert'}</textarea></div>
+ </div>
+ <div class="form-group">
+ <label for="ssl_action" class="col-sm-3 control-label">{tmpl_var name='ssl_action_txt'}</label>
+ <div class="col-sm-9"><select name="ssl_action" id="ssl_action" class="form-control">
+ {tmpl_var name='ssl_action'}
+ </select></div>
+ </div>
+
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+ <input type="hidden" name="type" value="ssl">
+
+ <div class="clear"><div class="right">
+ <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="mail/xmpp_domain_edit.php">{tmpl_var name='btn_save_txt'}</button>
+ <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="mail/xmpp_domain_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+ </div></div>
+
+<script>
+<!--
+ <tmpl_if name='show_helper_links'>
+ if($("input[name=id]").val() > 0) $('#show_helper_links:hidden').show();
+
+ $('#reset_data').click(function(){
+ $('#ssl_organisation').add('#ssl_locality').add('#ssl_state').add('#ssl_organisation_unit').val('');
+ $('#ssl_country').val($("#ssl_country option:first").val());
+ });
+ $('#load_data').click(function(){
+ loadClientData();
+ });
+
+
+ function loadClientData() {
+ var web_id = $("input[name=id]").val();
+
+ jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {'web_id': web_id, 'type': "getclientssldata"}, function(data) {
+ $('#ssl_organisation').val(data['company_name']);
+ $('#ssl_locality').val(data['city']);
+ $('#ssl_country').val(data['country']);
+ $('#ssl_state').val(data['state']);
+ $('#ssl_organisation_unit').val('IT');
+ });
+ }
+ </tmpl_if>
+//-->
+</script>
\ No newline at end of file
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 0000000..7957914
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_domain_list.htm
@@ -0,0 +1,74 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+ <tmpl_if name='datalog_changes_count' op='>' value='0'>
+ <div>
+ <div class="systemmonitor-state state-info">
+ <div class="status"></div>
+ <div class="statusMsg">
+ {tmpl_var name="datalog_changes_txt"}
+ <ul>
+ <tmpl_loop name="datalog_changes">
+ <li><strong>{tmpl_var name="text"}:</strong> {tmpl_var name="count"}</li>
+ </tmpl_loop>
+ </ul>
+ {tmpl_var name="datalog_changes_end_txt"}
+ </div>
+ </div><br />
+ </div>
+ </tmpl_if>
+ <p class="fieldset-legend">{tmpl_var name="toolsarea_head_txt"}</p>
+
+ <button class="btn btn-default formbutton-success" type="button" data-load-content="mail/xmpp_domain_edit.php">{tmpl_var name="add_new_record_txt"}</button>
+
+
+
+
+ <p class="fieldset-legend"><tmpl_var name="list_head_txt"></p>
+ <div class="table-wrapper marginTop15">
+<table class="table">
+ <thead class="dark form-group-sm">
+ <tr>
+ <th class="tiny-col" data-column="active"><tmpl_var name="active_txt"></th>
+ <th data-column="server_id"><tmpl_var name="server_id_txt"></th>
+ <th data-column="domain"><tmpl_var name="domain_txt"></th>
+ <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
+ </tr>
+ <tr>
+ <td><select class="form-control" name="search_active">{tmpl_var name='search_active'}</select></td>
+ <td><select class="form-control" name="search_server_id">{tmpl_var name='search_server_id'}</select></td>
+ <td><input class="form-control" type="text" name="search_domain" value="{tmpl_var name='search_domain'}" /></td>
+ <td class="text-right">
+ <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="mail/xmpp_domain_list.php"><span class="icon icon-filter"></span></button>
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tmpl_loop name="records">
+ <tr>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="active"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="server_id"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="domain"}</a></td>
+ <td class="text-right">
+ <a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('mail/xmpp_domain_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></button>
+ </td>
+ </tr>
+ </tmpl_loop>
+ <tmpl_unless name="records">
+ <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td colspan="4">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+ </tr>
+ </tmpl_unless>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="4"><tmpl_var name="paging"></td>
+ </tr>
+ </tfoot>
+ </table>
+</div>
+
+
\ No newline at end of file
diff --git a/interface/web/mail/templates/xmpp_user_edit.htm b/interface/web/mail/templates/xmpp_user_edit.htm
new file mode 100644
index 0000000..e155ec0
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_user_edit.htm
@@ -0,0 +1,47 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+
+
+ <div class="form-group">
+ <label class="col-sm-3 control-label"><em>*</em> {tmpl_var name='jid_txt'}</label>
+ <div class="col-sm-4">
+ <input type="text" id="jid_local_part" name="jid_local_part" value="{tmpl_var name='jid_local_part'}" class="form-control" />
+ </div>
+ <div class="col-sm-1 text-center">@</div>
+ <div class="col-sm-4">
+ <select name="jid_domain" id="jid_domain" class="form-control">{tmpl_var name='jid_domain'}</select>
+ </div>
+ </div>
+
+ <div class="form-group">
+ <label for="password" class="col-sm-3 control-label">{tmpl_var name='password_txt'}</label>
+ <div class="col-sm-6"><input type="password" name="password" id="password" value="{tmpl_var name='password'}" class="form-control" autocomplete="off" onkeyup="pass_check(this.value);checkPassMatch('password','repeat_password');" /></div><div class="col-sm-3 input-sm"> </div><a href="javascript:void(0);" onclick="generatePassword('password','repeat_password');">{tmpl_var name='generate_password_txt'}</a>
+ </div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='password_strength_txt'}</label>
+ <div id="passBar"></div>
+ <p class="formHint"><span id="passText"> </span></p>
+ </div>
+ <div class="form-group">
+ <label for="repeat_password" class="col-sm-3 control-label">{tmpl_var name='repeat_password_txt'}</label>
+ <div class="col-sm-9"><input type="password" name="repeat_password" id="repeat_password" value="" class="form-control" autocomplete="off" onkeyup="checkPassMatch('password','repeat_password');" /></div></div>
+ <div id="confirmpasswordError" style="display:none;" class="confirmpassworderror">{tmpl_var name='password_mismatch_txt'}</div>
+ <div id="confirmpasswordOK" style="display:none;" class="confirmpasswordok">{tmpl_var name='password_match_txt'}</div>
+ <div class="form-group">
+ <label class="col-sm-3 control-label">{tmpl_var name='active_txt'}</label>
+ <div class="col-sm-9">
+ {tmpl_var name='active'}
+ </div>
+ </div>
+
+
+ <input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+ <div class="clear"><div class="right">
+ <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="mail/xmpp_user_edit.php">{tmpl_var name='btn_save_txt'}</button>
+ <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="mail/xmpp_user_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+ </div></div>
diff --git a/interface/web/mail/templates/xmpp_user_list.htm b/interface/web/mail/templates/xmpp_user_list.htm
new file mode 100644
index 0000000..68668b4
--- /dev/null
+++ b/interface/web/mail/templates/xmpp_user_list.htm
@@ -0,0 +1,74 @@
+<div class='page-header'>
+ <h1><tmpl_var name="list_head_txt"></h1>
+</div>
+<p><tmpl_var name="list_desc_txt"></p>
+
+
+ <tmpl_if name='datalog_changes_count' op='>' value='0'>
+ <div>
+ <div class="systemmonitor-state state-info">
+ <div class="status"></div>
+ <div class="statusMsg">
+ {tmpl_var name="datalog_changes_txt"}
+ <ul>
+ <tmpl_loop name="datalog_changes">
+ <li><strong>{tmpl_var name="text"}:</strong> {tmpl_var name="count"}</li>
+ </tmpl_loop>
+ </ul>
+ {tmpl_var name="datalog_changes_end_txt"}
+ </div>
+ </div><br />
+ </div>
+ </tmpl_if>
+ <p class="fieldset-legend">{tmpl_var name="toolsarea_head_txt"}</p>
+
+ <button class="btn btn-default formbutton-success" type="button" data-load-content="mail/xmpp_user_edit.php">{tmpl_var name="add_new_record_txt"}</button>
+
+
+
+
+ <p class="fieldset-legend"><tmpl_var name="list_head_txt"></p>
+ <div class="table-wrapper marginTop15">
+<table class="table">
+ <thead class="dark form-group-sm">
+ <tr>
+ <th data-column="jid"><tmpl_var name="jid_txt"></th>
+ <th class="small-col" data-column="is_domain_admin"><tmpl_var name="is_domain_admin_txt"></th>
+ <th class="small-col" data-column="is_muc_admin"><tmpl_var name="is_muc_admin_txt"></th>
+ <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
+ </tr>
+ <tr>
+ <td><input class="form-control" type="text" name="search_jid" value="{tmpl_var name='search_jid'}" /></td>
+ <td><select class="form-control" name="search_is_domain_admin">{tmpl_var name='search_is_domain_admin'}</select></td>
+ <td><select class="form-control" name="search_is_muc_admin">{tmpl_var name='search_is_muc_admin'}</select></td>
+ <td class="text-right">
+ <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="mail/xmpp_user_list.php"><span class="icon icon-filter"></span></button>
+ </td>
+ </tr>
+ </thead>
+ <tbody>
+ <tmpl_loop name="records">
+ <tr>
+ <td><a href="#" data-load-content="mail/xmpp_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="jid"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="is_domain_admin"}</a></td>
+ <td><a href="#" data-load-content="mail/xmpp_user_edit.php?id={tmpl_var name='id'}">{tmpl_var name="is_muc_admin"}</a></td>
+ <td class="text-right">
+ <a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('mail/xmpp_user_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></button>
+ </td>
+ </tr>
+ </tmpl_loop>
+ <tmpl_unless name="records">
+ <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+ <td colspan="4">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+ </tr>
+ </tmpl_unless>
+ </tbody>
+ <tfoot>
+ <tr>
+ <td colspan="4"><tmpl_var name="paging"></td>
+ </tr>
+ </tfoot>
+ </table>
+</div>
+
+
\ 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 0000000..da481c8
--- /dev/null
+++ b/interface/web/mail/xmpp_domain_del.php
@@ -0,0 +1,93 @@
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/xmpp_domain.list.php";
+$tform_def_file = "form/xmpp_domain.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+//* Check permissions for module
+$app->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.
+ $this->delete_accounts($domain);
+ // and DNS entries
+ $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 = ?", $domain.'.');
+ if ( isset($soa) && !empty($soa) ) $this->remove_dns($soa);
+ }
+
+ private function delete_accounts($domain){
+ global $app;
+ // get all accounts
+ $sql = "SELECT * FROM xmpp_user WHERE jid LIKE ? AND ?";
+ $users = $app->db->queryAllRecords($sql, '%@'.$domain, $app->tform->getAuthSQL('d'));
+ foreach($users AS $u)
+ $app->db->datalogDelete('xmpp_user', 'xmppuser_id', $u['xmppuser_id']);
+ }
+
+ private function remove_dns($new_rr) {
+ global $app;
+
+ // purge all xmpp related 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']);
+ }
+ }
+
+}
+
+$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 0000000..1213a91
--- /dev/null
+++ b/interface/web/mail/xmpp_domain_edit.php
@@ -0,0 +1,543 @@
+<?php
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$tform_def_file = "form/xmpp_domain.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+//* Check permissions for module
+$app->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 = 'server';
+
+ function onLoad() {
+ $show_type = 'server';
+ if(isset($_REQUEST['type']) && $_REQUEST['type'] == 'modules') {
+ $show_type = 'modules';
+ } elseif(isset($_REQUEST['type']) && $_REQUEST['type'] == 'muc') {
+ $show_type = 'muc';
+ }elseif(isset($_REQUEST['type']) && $_REQUEST['type'] == 'ssl') {
+ $show_type = 'ssl';
+ }
+
+ $_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_xmpp_domain')) {
+ $app->error($app->tform->wordbook["limit_xmppdomain_txt"]);
+ }
+ if(!$app->tform->checkResellerLimit('limit_xmpp_domain')) {
+ $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');
+
+ $read_limits = array('limit_xmpp_pastebin', 'limit_xmpp_httparchive', 'limit_xmpp_anon', 'limit_xmpp_vjud', 'limit_xmpp_proxy', 'limit_xmpp_status');
+ if($_SESSION["s"]["user"]["typ"] != 'admin') {
+ $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+ $client = $app->db->queryOneRecord("SELECT client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+ // add limits to template to be able to hide settings
+ foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]);
+ }else{
+ foreach($read_limits as $limit) $app->tpl->setVar($limit, 'y');
+ }
+
+
+ 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 .= "<option value='0'></option>";
+ //$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 .= "<option value='$client[groupid]' $selected>$client[contactname]</option>\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, 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");
+
+ 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 = '<option value="'.$tmp['groupid'].'">'.$client['contactname'].'</option>';
+ //$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 .= "<option value='$client[groupid]' $selected>$client[contactname]</option>\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 .= "<option value='$xmpp_server[server_id]'>$xmpp_server[server_name]</option>";
+ }
+
+ $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 .= "<option value=" . $domain['domain_id'] ;
+ if ($domain['domain'] == $this->dataRecord["domain"]) {
+ $domain_select .= " selected";
+ }
+ $domain_select .= ">" . $app->functions->idn_decode($domain['domain']) . "</option>\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 .= "<option value=''></option>\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")."<br />";
+ } 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_xmpp_domain 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_xmpp_domain"] >= 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_xmpp_domain"]) {
+ $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 management method
+ if(isset($this->dataRecord["management_method"]))
+ // Set management method to 0 as long as the mailaccount hook is not implemented
+ $this->dataRecord["management_method"] = 0;
+ switch($this->dataRecord["management_method"]){
+ case 0:
+ $this->dataRecord["management_method"] = 'normal';
+ break;
+ case 1:
+ $this->dataRecord["management_method"] = 'maildomain';
+ // Check for corresponding mail domain
+ $tmp = $app->db->queryOneRecord("SELECT count(domain_id) AS number FROM mail_domain WHERE domain = '".$this->dataRecord["domain"]."' AND ".$app->tform->getAuthSQL('r')." ORDER BY domain");
+ if($tmp['number']==0){
+ $app->error($app->tform->wordbook["no_corresponding_maildomain_txt"]);
+ break;
+ }
+ 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;
+ }
+ }
+
+ // Reset public registration to 'n', is not yet supported
+ $this->dataRecord["public_registration"] = 'n';
+
+ 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"]);
+
+ // create new accounts from mail domain
+ //if($this->dataRecord['management_method']=='maildomain')
+ // $this->syncMailusers($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 domain has been changed
+ $rec = $app->db->queryOneRecord("SELECT domain from xmpp_domain WHERE domain_id = ".$this->id);
+ if($this->dataRecord['domain']!=$rec['domain'])
+ $app->error($app->tform->wordbook["cant_change_domainname_txt"]);
+
+ //* 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, domain from 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);
+ }
+ }
+
+ if($this->_xmpp_type == 'ssl'){
+ //* Check that all fields for the SSL cert creation are filled
+ if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'create') {
+ if($this->dataRecord['ssl_state'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_state_empty').'<br />';
+ if($this->dataRecord['ssl_locality'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_locality_empty').'<br />';
+ if($this->dataRecord['ssl_organisation'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_empty').'<br />';
+ if($this->dataRecord['ssl_organisation_unit'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_unit_empty').'<br />';
+ if($this->dataRecord['ssl_country'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_country_empty').'<br />';
+ }
+
+ if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'save') {
+ if(trim($this->dataRecord['ssl_cert']) == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_cert_empty').'<br />';
+ }
+ }
+
+ //* 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;
+
+ // create new accounts from mail domain
+ //if($this->oldDataRecord['management_method'] != 'maildomain' && $this->dataRecord['management_method']=='maildomain')
+ // $this->syncMailusers($this->dataRecord['domain']);
+ // or reset to normal permissions
+ //elseif($this->oldDataRecord['management_method'] == 'maildomain' && $this->dataRecord['management_method']!='maildomain')
+ // $this->desyncMailusers($this->dataRecord['domain']);
+ // Update DNS Records
+ // TODO: Update gets only triggered from main form. WHY?
+ $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other FROM dns_soa WHERE active = 'Y' AND = ?", $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']);
+ }
+
+ /*
+ * NOT YET FINISHED
+
+ private function syncMailusers($domain){
+ global $app, $conf;
+ // get all mailusers
+ $db_mailusers = $app->db->queryAllRecords("SELECT email, password, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other FROM mail_user WHERE email like ?", '@'.$this->dataRecord['domain'].'.');
+ // get existing xmpp users
+ $db_xmppusers = $app->db->queryAllRecords("SELECT jid, password, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other FROM xmpp_user WHERE jid like ?", '@'.$this->dataRecord['domain'].'.');
+
+ // Migrate user accounts
+ $users_delete = array();
+ $users_update = array();
+ $users_create = array();
+ foreach($db_xmppusers AS $ix=>$x){
+ $matched = false;
+ foreach($db_mailusers AS $im=>$m){
+ if($x['jid']==$m['email']){
+ // User matched, mark for update
+ $x['password'] = $m['password'];
+ $users_update[] = $x;
+ unset($db_xmppusers[$ix]);
+ unset($db_mailusers[$im]);
+ $matched = true;
+ break;
+ }
+ }
+ // XMPP user not matched, mark for deletion
+ if(!$matched){
+ $users_delete[] = $x;
+ unset($db_xmppusers[$ix]);
+ }
+ }
+ // Mark remaining mail users for creation
+ $users_create = $db_xmppusers;
+ foreach($users_create AS $u){
+ $u['server_id'] = $this->dataRecord['server_id'];
+ $u['sys_perm_user'] = 'r';
+ $u['sys_perm_group'] = 'r';
+ $app->db->datalogInsert('xmpp_user', $u, 'xmppuser_id');
+ }
+ foreach($users_update AS $u){
+ $u['sys_perm_user'] = 'r';
+ $u['sys_perm_group'] = 'r';
+ $app->db->datalogUpdate('xmpp_user', $u, 'xmppuser_id', $u['xmppuser_id']);
+ }
+ foreach($users_delete AS $u){
+ $app->db->datalogDelete('xmpp_user', 'xmppuser_id', $u['xmppuser_id']);
+ }
+
+ }
+
+ private function desyncMailusers($domain){
+ global $app, $conf;
+ // get existing xmpp users
+ $db_xmppusers = $app->db->queryAllRecords("SELECT jid, password, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other FROM xmpp_user WHERE jid like ?", '@'.$this->dataRecord['domain'].'.');
+ foreach($db_xmppusers AS $u){
+ $u['sys_perm_user'] = 'riud';
+ $u['sys_perm_group'] = 'riud';
+ $app->db->datalogUpdate('xmpp_user', $u, 'xmppuser_id', $u['xmppuser_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 0000000..ff632e3
--- /dev/null
+++ b/interface/web/mail/xmpp_domain_list.php
@@ -0,0 +1,28 @@
+<?php
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/xmpp_domain.list.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+
+//* Check permissions for module
+$app->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/interface/web/mail/xmpp_user_del.php b/interface/web/mail/xmpp_user_del.php
new file mode 100644
index 0000000..cf0cc62
--- /dev/null
+++ b/interface/web/mail/xmpp_user_del.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/xmpp_user.list.php";
+$tform_def_file = "form/xmpp_user.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+//* Check permissions for module
+$app->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;
+
+ $jid_parts = explode("@", $this->dataRecord['jid']);
+ $domain = $jid_parts[1];
+
+ // check if domain is managed through mail domain
+ // if yes, manual deletion is not allowed
+ //$app->error('blubb');
+
+
+ }
+
+}
+
+$page = new page_action;
+$page->onDelete();
+
+?>
diff --git a/interface/web/mail/xmpp_user_edit.php b/interface/web/mail/xmpp_user_edit.php
new file mode 100644
index 0000000..6ad6161
--- /dev/null
+++ b/interface/web/mail/xmpp_user_edit.php
@@ -0,0 +1,172 @@
+<?php
+/*
+Copyright (c) 2005 - 2009, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$tform_def_file = "form/xmpp_user.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+//* Check permissions for module
+$app->auth->check_module_permissions('mail');
+
+// Loading classes
+$app->uses('tpl,tform,tform_actions');
+$app->load('tform_actions');
+
+class page_action extends tform_actions {
+
+
+ function onShowNew() {
+ global $app, $conf;
+
+ // we will check only users, not admins
+ if($_SESSION["s"]["user"]["typ"] == 'user') {
+ if(!$app->tform->checkClientLimit('limit_xmpp_user')) {
+ $app->error($app->tform->wordbook["limit_xmpp_user_txt"]);
+ }
+ if(!$app->tform->checkResellerLimit('limit_xmpp_user')) {
+ $app->error('Reseller: '.$app->tform->wordbook["limit_xmpp_user_txt"]);
+ }
+ }
+
+ parent::onShowNew();
+ }
+
+ function onShowEnd() {
+ global $app, $conf;
+
+ $jid = $this->dataRecord["jid"];
+ $jid_parts = explode("@", $jid);
+ $app->tpl->setVar("jid_local_part", $jid_parts[0]);
+ $jid_parts[1] = $app->functions->idn_decode($jid_parts[1]);
+
+ // Getting Domains of the user
+ $sql = "SELECT domain, server_id FROM xmpp_domain WHERE ".$app->tform->getAuthSQL('r')." ORDER BY domain";
+ $domains = $app->db->queryAllRecords($sql);
+ $domain_select = '';
+ if(is_array($domains)) {
+ foreach( $domains as $domain) {
+ $domain['domain'] = $app->functions->idn_decode($domain['domain']);
+ $selected = ($domain["domain"] == @$jid_parts[1])?'SELECTED':'';
+ $domain_select .= "<option value='$domain[domain]' $selected>$domain[domain]</option>\r\n";
+ }
+ }
+ $app->tpl->setVar("jid_domain", $domain_select);
+ unset($domains);
+ unset($domain_select);
+
+
+ parent::onShowEnd();
+ }
+
+ function onSubmit() {
+ global $app, $conf;
+ //* Check if Domain belongs to user
+ if(isset($_POST["jid_domain"])) {
+ $domain = $app->db->queryOneRecord("SELECT server_id, domain FROM xmpp_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["jid_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
+ if($domain["domain"] != $app->functions->idn_encode($_POST["jid_domain"])) $app->tform->errorMessage .= $app->tform->lng("no_domain_perm");
+ }
+
+
+ //* if its an insert, check that the password is not empty
+ if($this->id == 0 && $_POST["password"] == '') {
+ $app->tform->errorMessage .= $app->tform->lng("error_no_pwd")."<br>";
+ }
+
+ //* Check the client limits, if user is not the admin
+ if($_SESSION["s"]["user"]["typ"] != 'admin') { // if user is not admin
+ // Get the limits of the client
+ $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+ $client = $app->db->queryOneRecord("SELECT limit_xmpp_user, parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
+
+
+ // Check if the user may add another xmpp user.
+ if($this->id == 0 && $client["limit_xmpp_user"] >= 0) {
+ $tmp = $app->db->queryOneRecord("SELECT count(xmppuser_id) as number FROM xmpp_user WHERE sys_groupid = $client_group_id");
+ if($tmp["number"] >= $client["limit_xmpp_user"]) {
+ $app->tform->errorMessage .= $app->tform->lng("limit_xmpp_user_txt")."<br>";
+ }
+ unset($tmp);
+ }
+ } // end if user is not admin
+
+
+ $app->uses('getconf');
+ $xmpp_config = $app->getconf->get_server_config(!empty($domain["server_id"]) ? $domain["server_id"] : '', 'xmpp');
+
+ //* compose the xmpp field
+ if(isset($_POST["jid_local_part"]) && isset($_POST["jid_domain"])) {
+ $this->dataRecord["jid"] = strtolower($_POST["jid_local_part"]."@".$app->functions->idn_encode($_POST["jid_domain"]));
+
+ // Set the server id of the xmpp user = server ID of xmpp domain.
+ $this->dataRecord["server_id"] = $domain["server_id"];
+
+ unset($this->dataRecord["jid_local_part"]);
+ unset($this->dataRecord["jid_domain"]);
+
+ }
+
+ parent::onSubmit();
+ }
+
+ function onAfterInsert() {
+ global $app, $conf;
+
+ // Set the domain owner as xmpp user owner
+ $domain = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM xmpp_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["jid_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
+ $app->db->query("UPDATE xmpp_user SET sys_groupid = ".$app->functions->intval($domain["sys_groupid"])." WHERE xmppuser_id = ".$this->id);
+
+ }
+
+ function onAfterUpdate() {
+ global $app, $conf;
+
+ // Set the domain owner as mailbox owner
+ if(isset($_POST["xmpp_domain"])) {
+ $domain = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM xmpp_domain WHERE domain = '".$app->db->quote($app->functions->idn_encode($_POST["jid_domain"]))."' AND ".$app->tform->getAuthSQL('r'));
+ $app->db->query("UPDATE xmpp_user SET sys_groupid = ".$app->functions->intval($domain["sys_groupid"])." WHERE xmppuser_id = ".$this->id);
+
+ }
+ }
+
+}
+
+$app->tform_actions = new page_action;
+$app->tform_actions->onLoad();
+
+?>
diff --git a/interface/web/mail/xmpp_user_list.php b/interface/web/mail/xmpp_user_list.php
new file mode 100644
index 0000000..ea44e4d
--- /dev/null
+++ b/interface/web/mail/xmpp_user_list.php
@@ -0,0 +1,39 @@
+<?php
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/xmpp_user.list.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+//* Check permissions for module
+$app->auth->check_module_permissions('mail');
+
+$app->load('listform_actions');
+
+
+class list_action extends listform_actions {
+
+ function onShow() {
+ global $app, $conf;
+
+ $app->uses('getconf');
+ $global_config = $app->getconf->get_global_config('xmpp');
+
+ parent::onShow();
+ }
+
+}
+
+$list = new list_action;
+$list->SQLOrderBy = 'ORDER BY xmpp_user.jid';
+$list->onLoad();
+
+
+?>
diff --git a/server/conf/metronome_conf_global.master b/server/conf/metronome_conf_global.master
new file mode 100644
index 0000000..71920ca
--- /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 0000000..179d533
--- /dev/null
+++ b/server/conf/metronome_conf_host.master
@@ -0,0 +1,135 @@
+VirtualHost "{tmpl_var name='domain'}"
+ enabled = {tmpl_var name='active'};
+ authentication = "external";
+ external_auth_command = "/usr/lib/metronome/isp-modules/mod_auth_external/authenticate_isp.sh";
+ allow_registration = {tmpl_var name='public_registration'};
+ <tmpl_if name='registration_url' op='!=' value=''>
+ registration_url = "{tmpl_var name='registration_url'}";
+ registration_text = "{tmpl_var name='registration_message'}";
+ </tmpl_if>
+ no_registration_whitelist = true;
+
+ modules_enabled = {
+ "roster",
+ "private",
+ "vcard",
+ "privacy",
+ "pep",
+<tmpl_if name='public_registration' op='==' value='true'>
+ "register",
+<tmpl_elseif name='registration_url' op='!=' value=''>
+ "register_redirect",
+</tmpl_if>
+ "admin_adhoc",
+ };
+ disco_items = {
+<tmpl_if name='use_muc' op='==' value='true'>
+ {
+ "muc.{tmpl_var name='domain'}",
+ "{tmpl_var name='muc_name'}",
+ },
+</tmpl_if>
+<tmpl_if name='use_pubsub' op='==' value='true'>
+ {
+ "pubsub.{tmpl_var name='domain'}",
+ "{tmpl_var name='domain'} Publish/Subscribe",
+ },
+</tmpl_if>
+<tmpl_if name='use_proxy' op='==' value='true'>
+ {
+ "proxy.{tmpl_var name='domain'}",
+ "{tmpl_var name='domain'} Bytestream Proxy",
+ },
+</tmpl_if>
+<tmpl_if name='use_vjud' op='==' value='true'>
+ {
+ "vjud.{tmpl_var name='domain'}",
+ "{tmpl_var name='domain'} User Directory",
+ },
+</tmpl_if>
+ };
+
+ admins = {
+{tmpl_var name='domain_admins'}
+ };
+<tmpl_if name='ssl_cert' op='==' value='true'>
+ ssl = {
+ key = "/etc/metronome/certs/{tmpl_var name='domain'}.key",
+ certificate = "/etc/metronome/certs/{tmpl_var name='domain'}.cert",
+ };
+</tmpl_if>
+
+<tmpl_if name='use_proxy' op='==' value='true'>
+VirtualHost "anon.{tmpl_var name='domain'}"
+ enabled = true;
+ authentication = "anonymous";
+ allow_anonymous_multiresourcing = true;
+ anonymous_jid_gentoken = "{tmpl_var name='domain'} Anonymous User";
+ admins = {
+ };
+</tmpl_if>
+
+
+<tmpl_if name='use_muc' op='==' value='true'>
+Component "muc.{tmpl_var name='domain'}" "muc"
+ modules_enabled = {
+ "muc_limits",
+ "muc_log",
+<tmpl_if name='use_archive' op='==' value='true'>
+ "muc_log_http",
+</tmpl_if>
+<tmpl_if name='use_pastebin' op='==' value='true'>
+ "pastebin",
+</tmpl_if>
+ };
+ muc_event_rate = 0.7;
+ muc_burst_factor = 13;
+ muc_log_presences = false;
+<tmpl_if name='use_archive' op='==' value='true'>
+ muc_log_http_config = {
+ show_join = {tmpl_var name='archive_join'},
+ show_status = {tmpl_var name='archive_status'},
+ theme = "metronome",
+ url_base = "logs",
+ };
+</tmpl_if>
+<tmpl_if name='use_pastebin' op='==' value='true'>
+ pastebin_path = "/pastes/";
+ pastebin_expire_after = {tmpl_var name='pastebin_expire'};
+ pastebin_trigger = "{tmpl_var name='pastebin_trigger'}";
+</tmpl_if>
+ name = "{tmpl_var name='muc_name'}";
+ restrict_room_creation = "{tmpl_var name='muc_restrict_room_creation'}";
+ admins = {
+{tmpl_var name='muc_admins'}
+ };
+</tmpl_if>
+
+
+<tmpl_if name='use_pubsub' op='==' value='true'>
+Component "pubsub.{tmpl_var name='domain'}" "pubsub"
+ name = "{tmpl_var name='domain'} Publish/Subscribe";
+ unrestricted_node_creation = false;
+</tmpl_if>
+
+<tmpl_if name='use_proxy' op='==' value='true'>
+Component "proxy.{tmpl_var name='domain'}" "proxy65"
+ proxy65_acl = {
+ "{tmpl_var name='domain'}",
+ };
+ proxy65_interfaces = {
+ "*",
+ "::",
+ };
+ proxy65_ports = {
+ 5000,
+ };
+</tmpl_if>
+
+
+<tmpl_if name='use_vjud' op='==' value='true'>
+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'}";
+</tmpl_if>
\ 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 0000000..1103ca4
--- /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_ssl.master b/server/conf/metronome_conf_ssl.master
new file mode 100644
index 0000000..73ab3a8
--- /dev/null
+++ b/server/conf/metronome_conf_ssl.master
@@ -0,0 +1,72 @@
+oid_section = new_oids
+
+[ new_oids ]
+
+# RFC 3920 section 5.1.1 defines this OID
+xmppAddr = 1.3.6.1.5.5.7.8.5
+
+# RFC 4985 defines this OID
+SRVName = 1.3.6.1.5.5.7.8.7
+
+[ req ]
+
+default_bits = 4096
+default_keyfile = {tmpl_var name='domain'}.key
+distinguished_name = distinguished_name
+req_extensions = v3_extensions
+x509_extensions = v3_extensions
+
+# ask about the DN?
+prompt = no
+
+[ distinguished_name ]
+
+commonName = {tmpl_var name='domain'}
+countryName = {tmpl_var name='ssl_country'}
+localityName = {tmpl_var name='ssl_locality'}
+organizationName = {tmpl_var name='ssl_organisation'}
+organizationalUnitName = {tmpl_var name='ssl_organisation_unit'}
+emailAddress = {tmpl_var name='ssl_email'}
+
+[ v3_extensions ]
+
+# for certificate requests (req_extensions)
+# and self-signed certificates (x509_extensions)
+
+basicConstraints = CA:FALSE
+keyUsage = digitalSignature,keyEncipherment
+extendedKeyUsage = serverAuth,clientAuth
+subjectAltName = @subject_alternative_name
+
+[ subject_alternative_name ]
+
+# See http://tools.ietf.org/html/draft-ietf-xmpp-3920bis#section-13.7.1.2 for more info.
+
+DNS.0 = {tmpl_var name='domain'}
+otherName.0 = xmppAddr;FORMAT:UTF8,UTF8:{tmpl_var name='domain'}
+otherName.1 = SRVName;IA5STRING:_xmpp-client.{tmpl_var name='domain'}
+otherName.2 = SRVName;IA5STRING:_xmpp-server.{tmpl_var name='domain'}
+
+DNS.1 = muc.{tmpl_var name='domain'}
+otherName.3 = xmppAddr;FORMAT:UTF8,UTF8:muc.{tmpl_var name='domain'}
+otherName.4 = SRVName;IA5STRING:_xmpp-server.muc.{tmpl_var name='domain'}
+
+DNS.2 = pubsub.{tmpl_var name='domain'}
+otherName.5 = xmppAddr;FORMAT:UTF8,UTF8:pubsub.{tmpl_var name='domain'}
+otherName.6 = SRVName;IA5STRING:_xmpp-server.pubsub.{tmpl_var name='domain'}
+
+DNS.3 = anon.{tmpl_var name='domain'}
+otherName.7 = xmppAddr;FORMAT:UTF8,UTF8:anon.{tmpl_var name='domain'}
+otherName.8 = SRVName;IA5STRING:_xmpp-server.anon.{tmpl_var name='domain'}
+
+DNS.4 = xmpp.{tmpl_var name='domain'}
+otherName.9 = xmppAddr;FORMAT:UTF8,UTF8:xmpp.{tmpl_var name='domain'}
+otherName.10= SRVName;IA5STRING:_xmpp-server.xmpp.{tmpl_var name='domain'}
+
+DNS.5 = proxy.{tmpl_var name='domain'}
+otherName.11= xmppAddr;FORMAT:UTF8,UTF8:proxy.{tmpl_var name='domain'}
+otherName.12= SRVName;IA5STRING:_xmpp-server.proxy.{tmpl_var name='domain'}
+
+DNS.6 = vjud.{tmpl_var name='domain'}
+otherName.13= xmppAddr;FORMAT:UTF8,UTF8:vjud.{tmpl_var name='domain'}
+otherName.14= SRVName;IA5STRING:_xmpp-server.vjud.{tmpl_var name='domain'}
\ No newline at end of file
diff --git a/server/conf/metronome_conf_status.master b/server/conf/metronome_conf_status.master
new file mode 100644
index 0000000..daa8205
--- /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 0000000..aace256
--- /dev/null
+++ b/server/mods-available/xmpp_module.inc.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class xmpp_module {
+
+ var $module_name = 'xmpp_module';
+ var $class_name = 'xmpp_module';
+ var $actions_available = array(
+ 'xmpp_domain_insert',
+ 'xmpp_domain_update',
+ 'xmpp_domain_delete',
+ 'xmpp_user_insert',
+ 'xmpp_user_update',
+ 'xmpp_user_delete'
+ );
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ function onInstall() {
+ global $conf;
+
+ if($conf['services']['xmpp'] == true) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /*
+ This function is called when the module is loaded
+ */
+
+ function onLoad() {
+ global $app;
+
+ /*
+ Annonce the actions that where provided by this module, so plugins
+ can register on them.
+ */
+
+ $app->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');
+ $app->services->registerService('metronome', 'xmpp_module', 'reloadXMPP');
+ $app->services->registerService('metronome', 'xmpp_module', 'restartXMPP');
+
+ }
+
+ /*
+ 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
+
+
+ function restartXMPP($action = 'restart') {
+ global $app, $conf;
+
+ // load the server configuration options
+ $app->uses('getconf,system');
+
+ $daemon = 'metronome';
+
+ $retval = array('output' => '', 'retval' => 0);
+ if($action == 'restart') {
+ $cmd = $app->system->getinitcommand($daemon, 'restart');
+ } else {
+ $cmd = $app->system->getinitcommand($daemon, 'reload');
+ }
+ exec($cmd.' 2>&1', $retval['output'], $retval['retval']);
+ $app->log("Restarting xmpp: $cmd", LOGLEVEL_DEBUG);
+ return $retval;
+ }
+} // 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 0000000..d5d36a0
--- /dev/null
+++ b/server/plugins-available/xmpp_plugin.inc.php
@@ -0,0 +1,397 @@
+<?php
+
+/*
+Copyright (c) 2015 Michael Fürmann, Spicy Web (spicyweb.de)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of ISPConfig nor the names of its contributors
+ may be used to endorse or promote products derived from this software without
+ specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class xmpp_plugin {
+
+ var $plugin_name = 'xmpp_server_plugin';
+ var $class_name = 'xmpp_server_plugin';
+
+ var $xmpp_config_dir = '/etc/metronome';
+
+ var $ssl_certificate_changed = false;
+ var $ssl_certificate_deleted = false;
+
+
+ //* This function is called during ispconfig installation to determine
+ // if a symlink shall be created for this plugin.
+ function onInstall() {
+ global $conf;
+
+ if($conf['services']['xmpp'] == true) {
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /*
+ This function is called when the plugin is loaded
+ */
+
+ function onLoad() {
+ global $app;
+
+ /*
+ Register for the events
+ */
+
+ $app->plugins->registerEvent('server_insert', 'xmpp_plugin', 'insert');
+ $app->plugins->registerEvent('server_update', 'xmpp_plugin', 'update');
+
+ $app->plugins->registerEvent('xmpp_domain_insert', 'xmpp_plugin', 'ssl');
+ $app->plugins->registerEvent('xmpp_domain_update', 'xmpp_plugin', 'ssl');
+ $app->plugins->registerEvent('xmpp_domain_delete', 'xmpp_plugin', 'ssl');
+
+ $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');
+ $app->plugins->registerEvent('xmpp_user_insert', 'xmpp_plugin', 'userInsert');
+ $app->plugins->registerEvent('xmpp_user_update', 'xmpp_plugin', 'userUpdate');
+ $app->plugins->registerEvent('xmpp_user_delete', 'xmpp_plugin', 'userDelete');
+
+ }
+
+ 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');
+
+ // Global server config
+ $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']));
+ // Global server admins (for all hosted domains)
+ $admins = '';
+ foreach(explode(',', $xmpp_config['xmpp_server_admins']) AS $a)
+ $admins.= "\t\"".trim($a)."\",\n";
+ $tpl->setVar('server_admins', $admins);
+ unset($admins);
+ // enabled modules, so own modules or simmilar prosody-modules can easily be added
+ $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);
+
+ $app->services->restartServiceDelayed('metronome', 'restart');
+ 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('public_registration', $data['new']['public_registration'] == 'y' ? 'true' : 'false');
+ // Domain admins
+ $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");
+
+ // Enable / Disable features
+ 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 for MUC channels
+ $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');
+
+ }
+
+ // Check for SSL
+ if(strlen($data['new']['ssl_cert']) && strlen($data['new']['ssl_key']) && !$this->ssl_certificate_deleted || $this->ssl_certificate_changed)
+ $tpl->setVar('ssl_cert', true);
+
+ $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);
+ }
+
+ $app->services->restartServiceDelayed('metronome', 'reload');
+ }
+
+ 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', 'reload');
+ }
+
+ function userInsert($event_name, $data){
+ //$data['new']['auth_method']
+ // Check domain for auth settings
+ // Don't allow manual user creation for mailaccount controlled domains
+
+ // maybe metronomectl adduser for new local users
+ }
+ function userUpdate($event_name, $data){
+ // Check domain for auth settings
+ // Don't allow manual user update for mailaccount controlled domains
+
+ // maybe metronomectl passwd for existing local users
+ }
+ function userDelete($event_name, $data){
+ // Check domain for auth settings
+ // Don't allow manual user deletion for mailaccount controlled domains
+
+ // Remove account from metronome
+ exec('metronomectl deluser '.$data['old']['jid']);
+ }
+
+ // Handle the creation of SSL certificates
+ function ssl($event_name, $data) {
+ global $app, $conf;
+
+ $app->uses('system,tpl');
+
+ // load the server configuration options
+ $app->uses('getconf');
+ $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
+
+ $ssl_dir = '/etc/metronome/certs';
+ $domain = $data['new']['domain'];
+ $cnf_file = $ssl_dir.'/'.$domain.'.cnf';
+ $key_file = $ssl_dir.'/'.$domain.'.key';
+ $csr_file = $ssl_dir.'/'.$domain.'.csr';
+ $crt_file = $ssl_dir.'/'.$domain.'.cert';
+
+ //* Create a SSL Certificate, but only if this is not a mirror server.
+ if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
+
+ $this->ssl_certificate_changed = true;
+
+ //* Rename files if they exist
+ if(file_exists($cnf_file)) $app->system->rename($cnf_file, $cnf_file.'.bak');
+ if(file_exists($key_file)){
+ $app->system->rename($key_file, $key_file.'.bak');
+ $app->system->chmod($key_file.'.bak', 0400);
+ $app->system->chown($key_file.'.bak', 'metronome');
+ }
+ if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
+ if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');
+
+ // Write new CNF file
+ $tpl = new tpl();
+ $tpl->newTemplate('metronome_conf_ssl.master');
+ $tpl->setVar('domain', $domain);
+ $tpl->setVar('ssl_country', $data['new']['ssl_country']);
+ $tpl->setVar('ssl_locality', $data['new']['ssl_locality']);
+ $tpl->setVar('ssl_organisation', $data['new']['ssl_organisation']);
+ $tpl->setVar('ssl_organisation_unit', $data['new']['ssl_organisation_unit']);
+ $tpl->setVar('ssl_email', $data['new']['ssl_email']);
+ $app->system->file_put_contents($cnf_file, $tpl->grab());
+
+ // Generate new key, csr and cert
+ exec("(cd /etc/metronome/certs && make $domain.key)");
+ exec("(cd /etc/metronome/certs && make $domain.csr)");
+ exec("(cd /etc/metronome/certs && make $domain.cert)");
+
+ $ssl_key = $app->db->quote($app->system->file_get_contents($key_file));
+ $app->system->chmod($key_file, 0400);
+ $app->system->chown($key_file, 'metronome');
+ $ssl_request = $app->db->quote($app->system->file_get_contents($csr_file));
+ $ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file));
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE xmpp_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key' WHERE domain = '".$data['new']['domain']."'");
+ $app->db->query("UPDATE xmpp_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE xmpp_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key' WHERE domain = '".$data['new']['domain']."'");
+ $app->dbmaster->query("UPDATE xmpp_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+ $app->log('Creating XMPP SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
+ }
+
+ //* Save a SSL certificate to disk
+ if($data["new"]["ssl_action"] == 'save') {
+ $this->ssl_certificate_changed = true;
+
+ //* Rename files if they exist
+ if(file_exists($cnf_file)) $app->system->rename($cnf_file, $cnf_file.'.bak');
+ if(file_exists($key_file)){
+ $app->system->rename($key_file, $key_file.'.bak');
+ $app->system->chmod($key_file.'.bak', 0400);
+ $app->system->chown($key_file.'.bak', 'metronome');
+ }
+ if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
+ if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');
+
+ //* Write new ssl files
+ if(trim($data["new"]["ssl_request"]) != '')
+ $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
+ if(trim($data["new"]["ssl_cert"]) != '')
+ $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
+
+ //* Write the key file, if field is empty then import the key into the db
+ if(trim($data["new"]["ssl_key"]) != '') {
+ $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]);
+ $app->system->chmod($key_file, 0400);
+ $app->system->chown($key_file, 'metronome');
+ } else {
+ $ssl_key = $app->db->quote($app->system->file_get_contents($key_file));
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE xmpp_domain SET ssl_key = '$ssl_key' WHERE domain = '".$data['new']['domain']."'");
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE xmpp_domain SET ssl_key = '$ssl_key' WHERE domain = '".$data['new']['domain']."'");
+ }
+
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE xmpp_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE xmpp_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+ $app->log('Saving XMPP SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
+ }
+
+ //* Delete a SSL certificate
+ if($data['new']['ssl_action'] == 'del') {
+ $this->ssl_certificate_deleted = true;
+ $app->system->unlink($csr_file);
+ $app->system->unlink($crt_file);
+ $app->system->unlink($key_file);
+ $app->system->unlink($cnf_file);
+ $app->system->unlink($csr_file.'.bak');
+ $app->system->unlink($crt_file.'.bak');
+ $app->system->unlink($key_file.'.bak');
+ $app->system->unlink($cnf_file.'.bak');
+ /* Update the DB of the (local) Server */
+ $app->db->query("UPDATE xmpp_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = '".$data['new']['domain']."'");
+ $app->db->query("UPDATE xmpp_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+ /* Update also the master-DB of the Server-Farm */
+ $app->dbmaster->query("UPDATE xmpp_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = '".$data['new']['domain']."'");
+ $app->dbmaster->query("UPDATE xmpp_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+ $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
+ }
+
+ }
+
+} // end class
+
+?>
diff --git a/server/server.sh b/server/server.sh
index 522e0d5..2f3d2fb 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
--
Gitblit v1.9.1