From 3e994a81a8b407c0076eaf90649fbf98e71082e2 Mon Sep 17 00:00:00 2001 From: Michael Fürmann <michael@spicyweb.de> Date: Thu, 19 Feb 2015 10:04:10 -0500 Subject: [PATCH] XMPP User and domain changes and Metronome SQL Auth scripts --- interface/web/mail/lib/lang/en_xmpp_domain.lng | 3 install/apps/metronome_libs/mod_auth_external/db_conf.inc.php | 6 interface/web/mail/templates/xmpp_user_edit.htm | 47 +++ install/apps/metronome_libs/mod_auth_external/db_auth.php | 58 ++++ interface/web/mail/form/xmpp_user.tform.php | 127 +++++++++ interface/web/mail/list/xmpp_user.list.php | 19 - install/apps/metronome_libs/mod_auth_external/db_isuser.php | 37 ++ interface/web/mail/form/xmpp_domain.tform.php | 6 install/sql/incremental/upd_0081.sql | 6 /dev/null | 44 --- interface/web/mail/xmpp_user_del.php | 71 +++++ interface/web/mail/xmpp_user_edit.php | 172 +++++++++++++ install/lib/installer_base.lib.php | 10 interface/web/mail/xmpp_domain_edit.php | 89 ++++++ install/sql/ispconfig3.sql | 6 interface/web/mail/lib/lang/en_xmpp_user.lng | 15 + server/conf/metronome_conf_host.master | 11 interface/web/mail/templates/xmpp_domain_edit.htm | 6 install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh | 10 server/plugins-available/xmpp_plugin.inc.php | 25 + 20 files changed, 667 insertions(+), 101 deletions(-) diff --git a/install/apps/metronome_libs/mod_auth_external/authenticate_isp.php b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.php deleted file mode 100644 index 7c59f37..0000000 --- a/install/apps/metronome_libs/mod_auth_external/authenticate_isp.php +++ /dev/null @@ -1,65 +0,0 @@ -<?php -ini_set('display_errors', false); -$username = 'prosody'; -$password = '23fm%4ks0'; -/* -$soap_location = 'http://localhost:8080/ispconfig3/interface/web/remote/index.php'; -$soap_uri = 'http://localhost:8080/ispconfig3/interface/web/remote/'; -*/ -$soap_location = 'https://tepin.spicyweb.de:8080/remote/index.php'; -$soap_uri = 'https://tepin.spicyweb.de:8080/remote/'; - -$auth_keys = array( - 'iplay-esports.de' => 'f47kmm5Yh5hJzSws2KTS', - 'weirdempire.de' => 'scNDcU37gQ7MCMeBgaJX' -); - -$arg_email = ''; -$arg_password = ''; - -if(count($argv) == 4){ - $arg_email = $argv[1].'@'.$argv[2]; - $arg_password = $argv[3]; -} -$client = new SoapClient(null, array('location' => $soap_location, 'uri' => $soap_uri)); -try { - //* Login to the remote server - if($session_id = $client->login($username,$password)) { - //var_dump($client->mail_alias_get($session_id, array('source' => 'blablubb@divepage.net', 'type' => 'alias', 'active' => 'y'))); - // Is Mail Alias? - $alias = $client->mail_alias_get($session_id, array('source' => $arg_email, 'type' => 'alias', 'active' => 'y')); - if(count($alias)) - $arg_email = $alias[0]['destination']; - $mailbox = $client->mail_user_get($session_id, array('email' => $arg_email)); - if(count($mailbox)){ - $password = $mailbox[0]['password']; - echo checkAuth($argv[1], $argv[2], $arg_password, $password);//intval(crypt($arg_password, $password) == $password); - } - else - echo 0; - //* Logout - $client->logout($session_id); - } - else - echo 0; -} catch (SoapFault $e) { - echo 0; -} - -function checkAuth($user, $domain, $pw, $pw_mailbox){ - global $auth_keys; - if(crypt($pw, $pw_mailbox) == $pw_mailbox) - return intval(1); - - if(array_key_exists($domain, $auth_keys)){ - $datetime = new DateTime(); - $datetime->setTimezone(new DateTimeZone("UTC")); - for($t = $datetime->getTimestamp(); $t >= $datetime->getTimestamp()-30; $t--){ - $pw_api = md5($domain.'@'.$auth_keys[$domain].'@'.$user.'@'.$t); - if($pw_api == $pw) - return intval(1); - } - } - return intval(0); -} -?> \ No newline at end of file diff --git a/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh index c4832f4..c5a0c8e 100644 --- a/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh +++ b/install/apps/metronome_libs/mod_auth_external/authenticate_isp.sh @@ -12,7 +12,7 @@ case $ACTION in "auth") - if [ `/usr/bin/php /usr/lib/metronome/spicy-modules/mod_auth_external/authenticate_isp.php $USER $HOST $PASS` == 1 ] ; then + 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 @@ -21,17 +21,17 @@ fi ;; "isuser") - if [ `/usr/bin/php /usr/lib/metronome/spicy-modules/mod_auth_external/isuser_isp.php $USER $HOST` == 1 ] ; then + 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 "AUTH OK" >> $LOGFILE; } + [ $USELOG == true ] && { echo "ISUSER OK" >> $LOGFILE; } else echo $AUTH_FAILED - [ $USELOG == true ] && { echo "AUTH FAILED" >> $LOGFILE; } + [ $USELOG == true ] && { echo "ISUSER FAILED" >> $LOGFILE; } fi ;; *) echo $AUTH_FAILED - [ $USELOG == true ] && { echo "NO ACTION GIVEN" >> $LOGFILE; } + [ $USELOG == true ] && { echo "UNKNOWN ACTION GIVEN: $ACTION" >> $LOGFILE; } ;; esac 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/isuser_isp.php b/install/apps/metronome_libs/mod_auth_external/isuser_isp.php deleted file mode 100644 index d370532..0000000 --- a/install/apps/metronome_libs/mod_auth_external/isuser_isp.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -ini_set('display_errors', false); -$username = 'prosody'; -$password = '23fm%4ks0'; -/* -$soap_location = 'http://localhost:8080/ispconfig3/interface/web/remote/index.php'; -$soap_uri = 'http://localhost:8080/ispconfig3/interface/web/remote/'; -*/ -$soap_location = 'https://tepin.spicyweb.de:8080/remote/index.php'; -$soap_uri = 'https://tepin.spicyweb.de:8080/remote/'; - - -$arg_email = ''; - -if(count($argv) == 3){ - $arg_email = $argv[1].'@'.$argv[2]; -} - -$client = new SoapClient(null, array('location' => $soap_location, 'uri' => $soap_uri)); -try { - //* Login to the remote server - if($session_id = $client->login($username,$password)) { - //var_dump($client->mail_alias_get($session_id, array('source' => 'blablubb@divepage.net', 'type' => 'alias', 'active' => 'y'))); - // Is Mail Alias? - $alias = $client->mail_alias_get($session_id, array('source' => $arg_email, 'type' => 'alias', 'active' => 'y')); - if(count($alias)) - $arg_email = $alias[0]['destination']; - $mailbox = $client->mail_user_get($session_id, array('email' => $arg_email)); - if(count($mailbox)){ - echo 1; - //$password = $mailbox[0]['password']; - //echo intval(crypt($arg_password, $password) == $password); - } - else - echo 0; - //* Logout - $client->logout($session_id); - } - else - echo 0; -} catch (SoapFault $e) { - echo 0; -} -?> \ No newline at end of file diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 688cfdb..acaaf3b 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -1339,6 +1339,16 @@ // 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); + // Copy init script caselog('cp -f apps/metronome-init /etc/init.d/metronome', __FILE__, __LINE__); diff --git a/install/sql/incremental/upd_0081.sql b/install/sql/incremental/upd_0081.sql index 5acfc73..ce16a5b 100644 --- a/install/sql/incremental/upd_0081.sql +++ b/install/sql/incremental/upd_0081.sql @@ -23,7 +23,7 @@ `server_id` int(11) unsigned NOT NULL default '0', `domain` varchar(255) NOT NULL default '', - `auth_method` ENUM( 'isp', 'plain', 'hashed' ) NOT NULL default 'hashed', + `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 '', @@ -66,12 +66,8 @@ `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', - `xmpp_domain_id` int(11) unsigned NOT NULL default '0', - `login` varchar(255) NOT NULL default '', `jid` varchar(255) NOT NULL default '', `password` varchar(255) NOT NULL default '', - `is_domain_admin` enum('n','y') NOT NULL default 'n', - `is_muc_admin` enum('n','y') NOT NULL default 'n', `active` enum('n','y') NOT NULL DEFAULT 'n', PRIMARY KEY (`xmppuser_id`), KEY `server_id` (`server_id`,`jid`), diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 0b5ce40..22c58b1 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1977,7 +1977,7 @@ `server_id` int(11) unsigned NOT NULL default '0', `domain` varchar(255) NOT NULL default '', - `auth_method` ENUM( 'isp', 'plain', 'hashed' ) NOT NULL default 'hashed', + `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 '', @@ -2022,12 +2022,8 @@ `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', - `xmpp_domain_id` int(11) unsigned NOT NULL default '0', - `login` varchar(255) NOT NULL default '', `jid` varchar(255) NOT NULL default '', `password` varchar(255) NOT NULL default '', - `is_domain_admin` enum('n','y') NOT NULL default 'n', - `is_muc_admin` enum('n','y') NOT NULL default 'n', `active` enum('n','y') NOT NULL DEFAULT 'n', PRIMARY KEY (`xmppuser_id`), KEY `server_id` (`server_id`,`jid`), diff --git a/interface/web/mail/form/xmpp_domain.tform.php b/interface/web/mail/form/xmpp_domain.tform.php index cc1765f..6c5ff62 100644 --- a/interface/web/mail/form/xmpp_domain.tform.php +++ b/interface/web/mail/form/xmpp_domain.tform.php @@ -98,11 +98,11 @@ 'maxlength' => '255', 'searchable' => 1 ), - 'auth_method' => array ( + 'management_method' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', - 'default' => '1', - 'value' => array(0 => 'Plain', 1 => 'Hashed', 2 => 'By Email Mailbox') + 'default' => '0', + 'value' => array(0 => 'Normal', 1 => 'By Mail Domain') ), 'public_registration' => array ( 'datatype' => 'VARCHAR', 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 index 1151f5c..0cbf0c7 100644 --- a/interface/web/mail/lib/lang/en_xmpp_domain.lng +++ b/interface/web/mail/lib/lang/en_xmpp_domain.lng @@ -4,7 +4,7 @@ $wb["type_txt"] = 'Type'; $wb["active_txt"] = 'Active'; $wb["client_txt"] = 'Client'; -$wb["auth_method_txt"] = 'Authentication Method'; +$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'; @@ -25,4 +25,5 @@ $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["no_corresponding_maildomain_txt"] = 'Corresponding mail domain for user management not found. Please create the mail domain first.'; ?> 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/list/xmpp_user.list.php b/interface/web/mail/list/xmpp_user.list.php index f9a2415..c1cdbb8 100644 --- a/interface/web/mail/list/xmpp_user.list.php +++ b/interface/web/mail/list/xmpp_user.list.php @@ -59,23 +59,4 @@ 'width' => "", 'value' => ""); -$liste["item"][] = array( 'field' => "is_domain_admin", - 'datatype' => "VARCHAR", - 'formtype' => "SELECT", - 'op' => "=", - 'prefix' => "", - 'suffix' => "", - 'width' => "", - 'value' => array('n' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>", 'y' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>")); - -$liste["item"][] = array( 'field' => "is_muc_admin", - 'datatype' => "VARCHAR", - 'formtype' => "SELECT", - 'op' => "=", - 'prefix' => "", - 'suffix' => "", - 'width' => "", - 'value' => array('n' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>", 'y' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>")); - - ?> diff --git a/interface/web/mail/templates/xmpp_domain_edit.htm b/interface/web/mail/templates/xmpp_domain_edit.htm index c735eff..0bae7e4 100644 --- a/interface/web/mail/templates/xmpp_domain_edit.htm +++ b/interface/web/mail/templates/xmpp_domain_edit.htm @@ -75,9 +75,9 @@ <div class="form-group"> - <label for="auth_method" class="col-sm-3 control-label">{tmpl_var name='auth_method_txt'}</label> - <div class="col-sm-9"><select name="auth_method" id="auth_method" class="form-control"> - {tmpl_var name='auth_method'} + <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> 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/xmpp_domain_edit.php b/interface/web/mail/xmpp_domain_edit.php index d87778d..127acd7 100644 --- a/interface/web/mail/xmpp_domain_edit.php +++ b/interface/web/mail/xmpp_domain_edit.php @@ -263,16 +263,19 @@ if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); // Read auth method - if(isset($this->dataRecord["auth_method"])) - switch($this->dataRecord["auth_method"]){ + if(isset($this->dataRecord["management_method"])) + switch($this->dataRecord["management_method"]){ case 0: - $this->dataRecord["auth_method"] = 'plain'; + $this->dataRecord["management_method"] = 'normal'; break; case 1: - $this->dataRecord["auth_method"] = 'hashed'; - break; - case 2: - $this->dataRecord["auth_method"] = 'isp'; + $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['count']==0){ + $app->error($app->tform->wordbook["no_corresponding_maildomain_txt"]); + break; + } break; } // vjud opt mode @@ -311,6 +314,10 @@ //* 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'].'.'); @@ -354,10 +361,16 @@ 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? // TODO: if(in_array($this->_xmpp_type, array('muc', 'modules'))){ - $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + $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); //} } @@ -428,6 +441,66 @@ } + 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; diff --git a/interface/web/mail/xmpp_user_del.php b/interface/web/mail/xmpp_user_del.php new file mode 100644 index 0000000..3d32f7f --- /dev/null +++ b/interface/web/mail/xmpp_user_del.php @@ -0,0 +1,71 @@ +<?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 + $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/server/conf/metronome_conf_host.master b/server/conf/metronome_conf_host.master index 66cbf0b..2b47832 100644 --- a/server/conf/metronome_conf_host.master +++ b/server/conf/metronome_conf_host.master @@ -1,11 +1,8 @@ VirtualHost "{tmpl_var name='domain'}" - enabled = {tmpl_var name='active'}; - authentication = "{tmpl_var name='auth_method'}"; - <tmpl_if name='auth_method' op='==' value='external'> - external_auth_command = "/usr/lib/metronome/isp-modules/mod_auth_external/authenticate_isp.sh"; - <tmpl_else> - allow_registration = {tmpl_var name='public_registration'}; - </tmpl_if> + 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'}"; diff --git a/server/plugins-available/xmpp_plugin.inc.php b/server/plugins-available/xmpp_plugin.inc.php index c4f70e3..1b177e7 100644 --- a/server/plugins-available/xmpp_plugin.inc.php +++ b/server/plugins-available/xmpp_plugin.inc.php @@ -67,6 +67,9 @@ $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'); } @@ -135,7 +138,6 @@ $tpl->newTemplate('metronome_conf_host.master'); $tpl->setVar('domain', $data['new']['domain']); $tpl->setVar('active', $data['new']['active'] == 'y' ? 'true' : 'false'); - $tpl->setVar('auth_method', $data['new']['auth_method'] == 'isp' ? 'external' : 'internal_'.$data['new']['auth_method']); $tpl->setVar('public_registration', $data['new']['public_registration'] == 'y' ? 'true' : 'false'); $admins = array(); @@ -227,6 +229,27 @@ $app->services->restartServiceDelayed('metronome', 'restart'); } + 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']); + } + } // end class ?> -- Gitblit v1.9.1