summaryrefslogtreecommitdiff
path: root/plugins/password
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/password')
-rw-r--r--plugins/password/README350
-rw-r--r--plugins/password/composer.json24
-rw-r--r--plugins/password/config.inc.php.dist407
-rw-r--r--plugins/password/drivers/chpasswd.php54
-rw-r--r--plugins/password/drivers/cpanel.php87
-rw-r--r--plugins/password/drivers/dbmail.php70
-rw-r--r--plugins/password/drivers/directadmin.php502
-rw-r--r--plugins/password/drivers/domainfactory.php100
-rw-r--r--plugins/password/drivers/expect.php73
-rw-r--r--plugins/password/drivers/gearman.php70
-rw-r--r--plugins/password/drivers/hmail.php76
-rw-r--r--plugins/password/drivers/kpasswd.php45
-rw-r--r--plugins/password/drivers/ldap.php381
-rw-r--r--plugins/password/drivers/ldap_simple.php238
-rw-r--r--plugins/password/drivers/pam.php58
-rw-r--r--plugins/password/drivers/plesk.php241
-rw-r--r--plugins/password/drivers/poppassd.php82
-rw-r--r--plugins/password/drivers/pw_usermod.php56
-rw-r--r--plugins/password/drivers/sasl.php60
-rw-r--r--plugins/password/drivers/smb.php74
-rw-r--r--plugins/password/drivers/sql.php212
-rw-r--r--plugins/password/drivers/virtualmin.php94
-rw-r--r--plugins/password/drivers/vpopmaild.php71
-rw-r--r--plugins/password/drivers/ximss.php89
-rw-r--r--plugins/password/drivers/xmail.php119
-rw-r--r--plugins/password/helpers/chgdbmailusers.c47
-rw-r--r--plugins/password/helpers/chgsaslpasswd.c29
-rw-r--r--plugins/password/helpers/chgvirtualminpasswd.c28
-rw-r--r--plugins/password/helpers/chpass-wrapper.py32
-rw-r--r--plugins/password/helpers/dovecot_hmacmd5.php191
-rw-r--r--plugins/password/helpers/passwd-expect267
-rw-r--r--plugins/password/localization/ar.inc31
-rw-r--r--plugins/password/localization/ar_SA.inc31
-rw-r--r--plugins/password/localization/ast.inc32
-rw-r--r--plugins/password/localization/az_AZ.inc31
-rw-r--r--plugins/password/localization/be_BE.inc33
-rw-r--r--plugins/password/localization/bg_BG.inc31
-rw-r--r--plugins/password/localization/br.inc33
-rw-r--r--plugins/password/localization/bs_BA.inc33
-rw-r--r--plugins/password/localization/ca_ES.inc33
-rw-r--r--plugins/password/localization/cs_CZ.inc33
-rw-r--r--plugins/password/localization/cy_GB.inc33
-rw-r--r--plugins/password/localization/da_DK.inc33
-rw-r--r--plugins/password/localization/de_CH.inc33
-rw-r--r--plugins/password/localization/de_DE.inc33
-rw-r--r--plugins/password/localization/el_GR.inc33
-rw-r--r--plugins/password/localization/en_CA.inc31
-rw-r--r--plugins/password/localization/en_GB.inc33
-rw-r--r--plugins/password/localization/en_US.inc38
-rw-r--r--plugins/password/localization/eo.inc31
-rw-r--r--plugins/password/localization/es_419.inc33
-rw-r--r--plugins/password/localization/es_AR.inc33
-rw-r--r--plugins/password/localization/es_ES.inc33
-rw-r--r--plugins/password/localization/et_EE.inc33
-rw-r--r--plugins/password/localization/eu_ES.inc33
-rw-r--r--plugins/password/localization/fa_AF.inc31
-rw-r--r--plugins/password/localization/fa_IR.inc33
-rw-r--r--plugins/password/localization/fi_FI.inc33
-rw-r--r--plugins/password/localization/fo_FO.inc31
-rw-r--r--plugins/password/localization/fr_FR.inc33
-rw-r--r--plugins/password/localization/fy_NL.inc19
-rw-r--r--plugins/password/localization/gl_ES.inc33
-rw-r--r--plugins/password/localization/he_IL.inc33
-rw-r--r--plugins/password/localization/hr_HR.inc31
-rw-r--r--plugins/password/localization/hu_HU.inc33
-rw-r--r--plugins/password/localization/hy_AM.inc33
-rw-r--r--plugins/password/localization/ia.inc33
-rw-r--r--plugins/password/localization/id_ID.inc31
-rw-r--r--plugins/password/localization/it_IT.inc33
-rw-r--r--plugins/password/localization/ja_JP.inc33
-rw-r--r--plugins/password/localization/km_KH.inc31
-rw-r--r--plugins/password/localization/ko_KR.inc33
-rw-r--r--plugins/password/localization/ku.inc33
-rw-r--r--plugins/password/localization/ku_IQ.inc30
-rw-r--r--plugins/password/localization/lb_LU.inc31
-rw-r--r--plugins/password/localization/lt_LT.inc33
-rw-r--r--plugins/password/localization/lv_LV.inc31
-rw-r--r--plugins/password/localization/ml_IN.inc33
-rw-r--r--plugins/password/localization/nb_NO.inc31
-rw-r--r--plugins/password/localization/nl_NL.inc33
-rw-r--r--plugins/password/localization/nn_NO.inc31
-rw-r--r--plugins/password/localization/pl_PL.inc33
-rw-r--r--plugins/password/localization/pt_BR.inc33
-rw-r--r--plugins/password/localization/pt_PT.inc33
-rw-r--r--plugins/password/localization/ro_RO.inc33
-rw-r--r--plugins/password/localization/ru_RU.inc33
-rw-r--r--plugins/password/localization/sk_SK.inc33
-rw-r--r--plugins/password/localization/sl_SI.inc31
-rw-r--r--plugins/password/localization/sq_AL.inc24
-rw-r--r--plugins/password/localization/sr_CS.inc31
-rw-r--r--plugins/password/localization/sv_SE.inc33
-rw-r--r--plugins/password/localization/ti.inc31
-rw-r--r--plugins/password/localization/tr_TR.inc33
-rw-r--r--plugins/password/localization/uk_UA.inc31
-rw-r--r--plugins/password/localization/vi_VN.inc31
-rw-r--r--plugins/password/localization/zh_CN.inc31
-rw-r--r--plugins/password/localization/zh_TW.inc33
-rw-r--r--plugins/password/password.js47
-rw-r--r--plugins/password/password.php370
-rw-r--r--plugins/password/tests/Password.php23
100 files changed, 6781 insertions, 0 deletions
diff --git a/plugins/password/README b/plugins/password/README
new file mode 100644
index 000000000..b883211bb
--- /dev/null
+++ b/plugins/password/README
@@ -0,0 +1,350 @@
+ -----------------------------------------------------------------------
+ Password Plugin for Roundcube
+ -----------------------------------------------------------------------
+ Plugin that adds a possibility to change user password using many
+ methods (drivers) via Settings/Password tab.
+ -----------------------------------------------------------------------
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
+
+ @version @package_version@
+ @author Aleksander Machniak <alec@alec.pl>
+ @author <see driver files for driver authors>
+ -----------------------------------------------------------------------
+
+ 1. Configuration
+ 2. Drivers
+ 2.1. Database (sql)
+ 2.2. Cyrus/SASL (sasl)
+ 2.3. Poppassd/Courierpassd (poppassd)
+ 2.4. LDAP (ldap)
+ 2.5. DirectAdmin Control Panel (directadmin)
+ 2.6. cPanel (cpanel)
+ 2.7. XIMSS/Communigate (ximms)
+ 2.8. Virtualmin (virtualmin)
+ 2.9. hMailServer (hmail)
+ 2.10. PAM (pam)
+ 2.11. Chpasswd (chpasswd)
+ 2.12. LDAP - no PEAR (ldap_simple)
+ 2.13. XMail (xmail)
+ 2.14. Pw (pw_usermod)
+ 2.15. domainFACTORY (domainfactory)
+ 2.16. DBMail (dbmail)
+ 2.17. Expect (expect)
+ 2.18. Samba (smb)
+ 2.19. Vpopmail daemon (vpopmaild)
+ 2.20. Plesk (Plesk RPC-API)
+ 2.21. Kpasswd
+ 3. Driver API
+
+
+ 1. Configuration
+ ----------------
+
+ Copy config.inc.php.dist to config.inc.php and set the options as described
+ within the file.
+
+
+ 2. Drivers
+ ----------
+
+ Password plugin supports many password change mechanisms which are
+ handled by included drivers. Just pass driver name in 'password_driver' option.
+
+
+ 2.1. Database (sql)
+ -------------------
+
+ You can specify which database to connect by 'password_db_dsn' option and
+ what SQL query to execute by 'password_query'. See config.inc.php.dist file for
+ more info.
+
+ Example implementations of an update_passwd function:
+
+ - This is for use with LMS (http://lms.org.pl) database and postgres:
+
+ CREATE OR REPLACE FUNCTION update_passwd(hash text, account text) RETURNS integer AS $$
+ DECLARE
+ res integer;
+ BEGIN
+ UPDATE passwd SET password = hash
+ WHERE login = split_part(account, '@', 1)
+ AND domainid = (SELECT id FROM domains WHERE name = split_part(account, '@', 2))
+ RETURNING id INTO res;
+ RETURN res;
+ END;
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
+
+ - This is for use with a SELECT update_passwd(%o,%c,%u) query
+ Updates the password only when the old password matches the MD5 password
+ in the database
+
+ CREATE FUNCTION update_password (oldpass text, cryptpass text, user text) RETURNS text
+ MODIFIES SQL DATA
+ BEGIN
+ DECLARE currentsalt varchar(20);
+ DECLARE error text;
+ SET error = 'incorrect current password';
+ SELECT substring_index(substr(user.password,4),_latin1'$',1) INTO currentsalt FROM users WHERE username=user;
+ SELECT '' INTO error FROM users WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+ UPDATE users SET password=cryptpass WHERE username=user AND password=ENCRYPT(oldpass,currentsalt);
+ RETURN error;
+ END
+
+ Example SQL UPDATEs:
+
+ - Plain text passwords:
+ UPDATE users SET password=%p WHERE username=%u AND password=%o AND domain=%h LIMIT 1
+
+ - Crypt text passwords:
+ UPDATE users SET password=%c WHERE username=%u LIMIT 1
+
+ - Use a MYSQL crypt function (*nix only) with random 8 character salt
+ UPDATE users SET password=ENCRYPT(%p,concat(_utf8'$1$',right(md5(rand()),8),_utf8'$')) WHERE username=%u LIMIT 1
+
+ - MD5 stored passwords:
+ UPDATE users SET password=MD5(%p) WHERE username=%u AND password=MD5(%o) LIMIT 1
+
+
+ 2.2. Cyrus/SASL (sasl)
+ ----------------------
+
+ Cyrus SASL database authentication allows your Cyrus+Roundcube
+ installation to host mail users without requiring a Unix Shell account!
+
+ This driver only covers the "sasldb" case when using Cyrus SASL. Kerberos
+ and PAM authentication mechanisms will require other techniques to enable
+ user password manipulations.
+
+ Cyrus SASL includes a shell utility called "saslpasswd" for manipulating
+ user passwords in the "sasldb" database. This plugin attempts to use
+ this utility to perform password manipulations required by your webmail
+ users without any administrative interaction. Unfortunately, this
+ scheme requires that the "saslpasswd" utility be run as the "cyrus"
+ user - kind of a security problem since we have chosen to SUID a small
+ script which will allow this to happen.
+
+ This driver is based on the Squirrelmail Change SASL Password Plugin.
+ See http://www.squirrelmail.org/plugin_view.php?id=107 for details.
+
+ Installation:
+
+ Change into the helpers directory. Edit the chgsaslpasswd.c file as is
+ documented within it.
+
+ Compile the wrapper program:
+ gcc -o chgsaslpasswd chgsaslpasswd.c
+
+ Chown the compiled chgsaslpasswd binary to the cyrus user and group
+ that your browser runs as, then chmod them to 4550.
+
+ For example, if your cyrus user is 'cyrus' and the apache server group is
+ 'nobody' (I've been told Redhat runs Apache as user 'apache'):
+
+ chown cyrus:nobody chgsaslpasswd
+ chmod 4550 chgsaslpasswd
+
+ Stephen Carr has suggested users should try to run the scripts on a test
+ account as the cyrus user eg;
+
+ su cyrus -c "./chgsaslpasswd -p test_account"
+
+ This will allow you to make sure that the script will work for your setup.
+ Should the script not work, make sure that:
+ 1) the user the script runs as has access to the saslpasswd|saslpasswd2
+ file and proper permissions
+ 2) make sure the user in the chgsaslpasswd.c file is set correctly.
+ This could save you some headaches if you are the paranoid type.
+
+
+ 2.3. Poppassd/Courierpassd (poppassd)
+ -------------------------------------
+
+ You can specify which host to connect to via 'password_pop_host' and
+ what port via 'password_pop_port'. See config.inc.php.dist file for more info.
+
+
+ 2.4. LDAP (ldap)
+ ----------------
+
+ See config.inc.php.dist file. Requires PEAR::Net_LDAP2 package.
+
+
+ 2.5. DirectAdmin Control Panel (directadmin)
+ --------------------------------------------
+
+ You can specify which host to connect to via 'password_directadmin_host' (don't
+ forget to use tcp:// or ssl://) and what port via 'password_direactadmin_port'.
+ The password enforcement with plenty customization can be done directly by
+ DirectAdmin, please see http://www.directadmin.com/features.php?id=910
+ See config.inc.php.dist file for more info.
+
+
+ 2.6. cPanel (cpanel)
+ --------------------
+
+ Install cPanel XMLAPI Client Class into Roundcube program/lib directory
+ or any other place in PHP include path. You can get the class from
+ https://raw.github.com/CpanelInc/xmlapi-php/master/xmlapi.php
+
+ You can configure parameters for connection to cPanel's API interface.
+ See config.inc.php.dist file for more info.
+
+
+ 2.7. XIMSS/Communigate (ximms)
+ ------------------------------
+
+ You can specify which host and port to connect to via 'password_ximss_host'
+ and 'password_ximss_port'. See config.inc.php.dist file for more info.
+
+
+ 2.8. Virtualmin (virtualmin)
+ ----------------------------
+
+ As in sasl driver this one allows to change password using shell
+ utility called "virtualmin". See helpers/chgvirtualminpasswd.c for
+ installation instructions. See also config.inc.php.dist file.
+
+
+ 2.9. hMailServer (hmail)
+ ------------------------
+
+ Requires PHP COM (Windows only). For access to hMail server on remote host
+ you'll need to define 'hmailserver_remote_dcom' and 'hmailserver_server'.
+ See config.inc.php.dist file for more info.
+
+
+ 2.10. PAM (pam)
+ ---------------
+
+ This driver is for changing passwords of shell users authenticated with PAM.
+ Requires PECL's PAM exitension to be installed (http://pecl.php.net/package/PAM).
+
+
+ 2.11. Chpasswd (chpasswd)
+ -------------------------
+
+ Driver that adds functionality to change the systems user password via
+ the 'chpasswd' command. See config.inc.php.dist file.
+
+ Attached wrapper script (helpers/chpass-wrapper.py) restricts password changes
+ to uids >= 1000 and can deny requests based on a blacklist.
+
+
+ 2.12. LDAP - no PEAR (ldap_simple)
+ -----------------------------------
+
+ It's rewritten ldap driver that doesn't require the Net_LDAP2 PEAR extension.
+ It uses directly PHP's ldap module functions instead (as Roundcube does).
+
+ This driver is fully compatible with the ldap driver, but
+ does not require (or uses) the
+ $config['password_ldap_force_replace'] variable.
+ Other advantages:
+ * Connects only once with the LDAP server when using the search user.
+ * Does not read the DN, but only replaces the password within (that is
+ why the 'force replace' is always used).
+
+
+ 2.13. XMail (xmail)
+ -----------------------------------
+
+ Driver for XMail (www.xmailserver.org). See config.inc.php.dist file
+ for configuration description.
+
+
+ 2.14. Pw (pw_usermod)
+ -----------------------------------
+
+ Driver to change the systems user password via the 'pw usermod' command.
+ See config.inc.php.dist file for configuration description.
+
+
+ 2.15. domainFACTORY (domainfactory)
+ -----------------------------------
+
+ Driver for the hosting provider domainFACTORY (www.df.eu).
+ No configuration options.
+
+
+ 2.16. DBMail (dbmail)
+ -----------------------------------
+
+ Driver that adds functionality to change the users DBMail password.
+ It only works with dbmail-users on the same host where Roundcube runs
+ and requires shell access and gcc in order to compile the binary
+ (see instructions in chgdbmailusers.c file).
+ See config.inc.php.dist file for configuration description.
+
+ Note: DBMail users can also use sql driver.
+
+
+ 2.17. Expect (expect)
+ -----------------------------------
+
+ Driver to change user password via the 'expect' command.
+ See config.inc.php.dist file for configuration description.
+
+
+ 2.18. Samba (smb)
+ -----------------------------------
+
+ Driver to change Samba user password via the 'smbpasswd' command.
+ See config.inc.php.dist file for configuration description.
+
+
+ 2.19. Vpopmail daemon (vpopmaild)
+ -----------------------------------
+
+ Driver for the daemon of vpopmail. Vpopmail is used with qmail to
+ enable virtual users that are saved in a database and not in /etc/passwd.
+
+ Set $config['password_vpopmaild_host'] to the host where vpopmaild runs.
+
+ Set $config['password_vpopmaild_port'] to the port of vpopmaild.
+
+ Set $config['password_vpopmaild_timeout'] to the timeout used for the TCP
+ connection to vpopmaild (You may want to set it higher on busy servers).
+
+
+ 2.20. Plesk (Plesk RPC-API)
+ ---------------------------
+
+ Driver for changing Passwords via Plesk RPC-API. This Driver also works with
+ Parallels Plesk Automation (PPA).
+
+ You need to allow the IP of the Roundcube-Server for RPC-Calls in the Panel.
+
+ Set $config['password_plesk_host'] to the Hostname / IP where Plesk runs
+ Set your Admin or RPC User: $config['password_plesk_user']
+ Set the Password of the User: $config['password_plesk_pass']
+ Set $config['password_plesk_rpc_port'] for the RPC-Port. Usually its 8443
+ Set the RPC-Path in $config['password_plesk_rpc_path']. Normally this is: enterprise/control/agent.php.
+
+
+ 2.21. Kpasswd
+ -----------------------------------
+
+ Driver to change the password in Kerberos environments via the 'kpasswd' command.
+ See config.inc.php.dist file for configuration description.
+
+
+ 3. Driver API
+ -------------
+
+ Driver file (<driver_name>.php) must define rcube_<driver_name>_password class
+ with public save() method that has two arguments. First - current password, second - new password.
+ This method should return PASSWORD_SUCCESS on success or any of PASSWORD_CONNECT_ERROR,
+ PASSWORD_CRYPT_ERROR, PASSWORD_ERROR when driver was unable to change password.
+ Extended result (as a hash-array with 'message' and 'code' items) can be returned
+ too. See existing drivers in drivers/ directory for examples.
diff --git a/plugins/password/composer.json b/plugins/password/composer.json
new file mode 100644
index 000000000..3aba2a2ba
--- /dev/null
+++ b/plugins/password/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "roundcube/password",
+ "type": "roundcube-plugin",
+ "description": "Password Change for Roundcube. Plugin adds a possibility to change user password using many methods (drivers) via Settings/Password tab.",
+ "license": "GPLv3+",
+ "version": "3.5",
+ "authors": [
+ {
+ "name": "Aleksander Machniak",
+ "email": "alec@alec.pl",
+ "role": "Lead"
+ }
+ ],
+ "repositories": [
+ {
+ "type": "composer",
+ "url": "http://plugins.roundcube.net"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0",
+ "roundcube/plugin-installer": ">=0.1.3"
+ }
+}
diff --git a/plugins/password/config.inc.php.dist b/plugins/password/config.inc.php.dist
new file mode 100644
index 000000000..18144996f
--- /dev/null
+++ b/plugins/password/config.inc.php.dist
@@ -0,0 +1,407 @@
+<?php
+
+// Password Plugin options
+// -----------------------
+// A driver to use for password change. Default: "sql".
+// See README file for list of supported driver names.
+$config['password_driver'] = 'sql';
+
+// Determine whether current password is required to change password.
+// Default: false.
+$config['password_confirm_current'] = true;
+
+// Require the new password to be a certain length.
+// set to blank to allow passwords of any length
+$config['password_minimum_length'] = 0;
+
+// Require the new password to contain a letter and punctuation character
+// Change to false to remove this check.
+$config['password_require_nonalpha'] = false;
+
+// Enables logging of password changes into logs/password
+$config['password_log'] = false;
+
+// Comma-separated list of login exceptions for which password change
+// will be not available (no Password tab in Settings)
+$config['password_login_exceptions'] = null;
+
+// Array of hosts that support password changing. Default is NULL.
+// Listed hosts will feature a Password option in Settings; others will not.
+// Example:
+//$config['password_hosts'] = array('mail.example.com', 'mail2.example.org');
+$config['password_hosts'] = null;
+
+// Enables saving the new password even if it matches the old password. Useful
+// for upgrading the stored passwords after the encryption scheme has changed.
+$config['password_force_save'] = false;
+
+// Enables forcing new users to change their password at their first login.
+$config['password_force_new_user'] = false;
+
+
+// SQL Driver options
+// ------------------
+// PEAR database DSN for performing the query. By default
+// Roundcube DB settings are used.
+$config['password_db_dsn'] = '';
+
+// The SQL query used to change the password.
+// The query can contain the following macros that will be expanded as follows:
+// %p is replaced with the plaintext new password
+// %c is replaced with the crypt version of the new password, MD5 if available
+// otherwise DES. More hash function can be enabled using the password_crypt_hash
+// configuration parameter.
+// %D is replaced with the dovecotpw-crypted version of the new password
+// %o is replaced with the password before the change
+// %n is replaced with the hashed version of the new password
+// %q is replaced with the hashed password before the change
+// %h is replaced with the imap host (from the session info)
+// %u is replaced with the username (from the session info)
+// %l is replaced with the local part of the username
+// (in case the username is an email address)
+// %d is replaced with the domain part of the username
+// (in case the username is an email address)
+// Escaping of macros is handled by this module.
+// Default: "SELECT update_passwd(%c, %u)"
+$config['password_query'] = 'SELECT update_passwd(%c, %u)';
+
+// By default the crypt() function which is used to create the '%c'
+// parameter uses the md5 algorithm. To use different algorithms
+// you can choose between: des, md5, blowfish, sha256, sha512.
+// Before using other hash functions than des or md5 please make sure
+// your operating system supports the other hash functions.
+$config['password_crypt_hash'] = 'md5';
+
+// By default domains in variables are using unicode.
+// Enable this option to use punycoded names
+$config['password_idn_ascii'] = false;
+
+// Path for dovecotpw (if not in $PATH)
+// $config['password_dovecotpw'] = '/usr/local/sbin/dovecotpw';
+
+// Dovecot method (dovecotpw -s 'method')
+$config['password_dovecotpw_method'] = 'CRAM-MD5';
+
+// Enables use of password with crypt method prefix in %D, e.g. {MD5}$1$LUiMYWqx$fEkg/ggr/L6Mb2X7be4i1/
+$config['password_dovecotpw_with_method'] = false;
+
+// Using a password hash for %n and %q variables.
+// Determine which hashing algorithm should be used to generate
+// the hashed new and current password for using them within the
+// SQL query. Requires PHP's 'hash' extension.
+$config['password_hash_algorithm'] = 'sha1';
+
+// You can also decide whether the hash should be provided
+// as hex string or in base64 encoded format.
+$config['password_hash_base64'] = false;
+
+// Iteration count parameter for Blowfish-based hashing algo.
+// It must be between 4 and 31. Default: 12.
+// Be aware, the higher the value, the longer it takes to generate the password hashes.
+$config['password_blowfish_cost'] = 12;
+
+
+// Poppassd Driver options
+// -----------------------
+// The host which changes the password
+$config['password_pop_host'] = 'localhost';
+
+// TCP port used for poppassd connections
+$config['password_pop_port'] = 106;
+
+
+// SASL Driver options
+// -------------------
+// Additional arguments for the saslpasswd2 call
+$config['password_saslpasswd_args'] = '';
+
+
+// LDAP and LDAP_SIMPLE Driver options
+// -----------------------------------
+// LDAP server name to connect to.
+// You can provide one or several hosts in an array in which case the hosts are tried from left to right.
+// Exemple: array('ldap1.exemple.com', 'ldap2.exemple.com');
+// Default: 'localhost'
+$config['password_ldap_host'] = 'localhost';
+
+// LDAP server port to connect to
+// Default: '389'
+$config['password_ldap_port'] = '389';
+
+// TLS is started after connecting
+// Using TLS for password modification is recommanded.
+// Default: false
+$config['password_ldap_starttls'] = false;
+
+// LDAP version
+// Default: '3'
+$config['password_ldap_version'] = '3';
+
+// LDAP base name (root directory)
+// Exemple: 'dc=exemple,dc=com'
+$config['password_ldap_basedn'] = 'dc=exemple,dc=com';
+
+// LDAP connection method
+// There is two connection method for changing a user's LDAP password.
+// 'user': use user credential (recommanded, require password_confirm_current=true)
+// 'admin': use admin credential (this mode require password_ldap_adminDN and password_ldap_adminPW)
+// Default: 'user'
+$config['password_ldap_method'] = 'user';
+
+// LDAP Admin DN
+// Used only in admin connection mode
+// Default: null
+$config['password_ldap_adminDN'] = null;
+
+// LDAP Admin Password
+// Used only in admin connection mode
+// Default: null
+$config['password_ldap_adminPW'] = null;
+
+// LDAP user DN mask
+// The user's DN is mandatory and as we only have his login,
+// we need to re-create his DN using a mask
+// '%login' will be replaced by the current roundcube user's login
+// '%name' will be replaced by the current roundcube user's name part
+// '%domain' will be replaced by the current roundcube user's domain part
+// '%dc' will be replaced by domain name hierarchal string e.g. "dc=test,dc=domain,dc=com"
+// Exemple: 'uid=%login,ou=people,dc=exemple,dc=com'
+$config['password_ldap_userDN_mask'] = 'uid=%login,ou=people,dc=exemple,dc=com';
+
+// LDAP search DN
+// The DN roundcube should bind with to find out user's DN
+// based on his login. Note that you should comment out the default
+// password_ldap_userDN_mask setting for this to take effect.
+// Use this if you cannot specify a general template for user DN with
+// password_ldap_userDN_mask. You need to perform a search based on
+// users login to find his DN instead. A common reason might be that
+// your users are placed under different ou's like engineering or
+// sales which cannot be derived from their login only.
+$config['password_ldap_searchDN'] = 'cn=roundcube,ou=services,dc=example,dc=com';
+
+// LDAP search password
+// If password_ldap_searchDN is set, the password to use for
+// binding to search for user's DN. Note that you should comment out the default
+// password_ldap_userDN_mask setting for this to take effect.
+// Warning: Be sure to set approperiate permissions on this file so this password
+// is only accesible to roundcube and don't forget to restrict roundcube's access to
+// your directory as much as possible using ACLs. Should this password be compromised
+// you want to minimize the damage.
+$config['password_ldap_searchPW'] = 'secret';
+
+// LDAP search base
+// If password_ldap_searchDN is set, the base to search in using the filter below.
+// Note that you should comment out the default password_ldap_userDN_mask setting
+// for this to take effect.
+$config['password_ldap_search_base'] = 'ou=people,dc=example,dc=com';
+
+// LDAP search filter
+// If password_ldap_searchDN is set, the filter to use when
+// searching for user's DN. Note that you should comment out the default
+// password_ldap_userDN_mask setting for this to take effect.
+// '%login' will be replaced by the current roundcube user's login
+// '%name' will be replaced by the current roundcube user's name part
+// '%domain' will be replaced by the current roundcube user's domain part
+// '%dc' will be replaced by domain name hierarchal string e.g. "dc=test,dc=domain,dc=com"
+// Example: '(uid=%login)'
+// Example: '(&(objectClass=posixAccount)(uid=%login))'
+$config['password_ldap_search_filter'] = '(uid=%login)';
+
+// LDAP password hash type
+// Standard LDAP encryption type which must be one of: crypt,
+// ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, ad, cram-md5 (dovecot style) or clear.
+// Please note that most encodage types require external libraries
+// to be included in your PHP installation, see function hashPassword in drivers/ldap.php for more info.
+// Multiple password Values can be generated by concatenating encodings with a +. E.g. 'cram-md5+crypt'
+// Default: 'crypt'.
+$config['password_ldap_encodage'] = 'crypt';
+
+// LDAP password attribute
+// Name of the ldap's attribute used for storing user password
+// Default: 'userPassword'
+$config['password_ldap_pwattr'] = 'userPassword';
+
+// LDAP password force replace
+// Force LDAP replace in cases where ACL allows only replace not read
+// See http://pear.php.net/package/Net_LDAP2/docs/latest/Net_LDAP2/Net_LDAP2_Entry.html#methodreplace
+// Default: true
+$config['password_ldap_force_replace'] = true;
+
+// LDAP Password Last Change Date
+// Some places use an attribute to store the date of the last password change
+// The date is meassured in "days since epoch" (an integer value)
+// Whenever the password is changed, the attribute will be updated if set (e.g. shadowLastChange)
+$config['password_ldap_lchattr'] = '';
+
+// LDAP Samba password attribute, e.g. sambaNTPassword
+// Name of the LDAP's Samba attribute used for storing user password
+$config['password_ldap_samba_pwattr'] = '';
+
+// LDAP Samba Password Last Change Date attribute, e.g. sambaPwdLastSet
+// Some places use an attribute to store the date of the last password change
+// The date is meassured in "seconds since epoch" (an integer value)
+// Whenever the password is changed, the attribute will be updated if set
+$config['password_ldap_samba_lchattr'] = '';
+
+
+// DirectAdmin Driver options
+// --------------------------
+// The host which changes the password
+// Use 'ssl://host' instead of 'tcp://host' when running DirectAdmin over SSL.
+// The host can contain the following macros that will be expanded as follows:
+// %h is replaced with the imap host (from the session info)
+// %d is replaced with the domain part of the username (if the username is an email)
+$config['password_directadmin_host'] = 'tcp://localhost';
+
+// TCP port used for DirectAdmin connections
+$config['password_directadmin_port'] = 2222;
+
+
+// vpopmaild Driver options
+// -----------------------
+// The host which changes the password
+$config['password_vpopmaild_host'] = 'localhost';
+
+// TCP port used for vpopmaild connections
+$config['password_vpopmaild_port'] = 89;
+
+// Timout used for the connection to vpopmaild (in seconds)
+$config['password_vpopmaild_timeout'] = 10;
+
+
+// cPanel Driver options
+// --------------------------
+// The cPanel Host name
+$config['password_cpanel_host'] = 'host.domain.com';
+
+// The cPanel admin username
+$config['password_cpanel_username'] = 'username';
+
+// The cPanel admin password
+$config['password_cpanel_password'] = 'password';
+
+// The cPanel port to use
+$config['password_cpanel_port'] = 2087;
+
+
+// XIMSS (Communigate server) Driver options
+// -----------------------------------------
+// Host name of the Communigate server
+$config['password_ximss_host'] = 'mail.example.com';
+
+// XIMSS port on Communigate server
+$config['password_ximss_port'] = 11024;
+
+
+// chpasswd Driver options
+// ---------------------
+// Command to use
+$config['password_chpasswd_cmd'] = 'sudo /usr/sbin/chpasswd 2> /dev/null';
+
+
+// XMail Driver options
+// ---------------------
+$config['xmail_host'] = 'localhost';
+$config['xmail_user'] = 'YourXmailControlUser';
+$config['xmail_pass'] = 'YourXmailControlPass';
+$config['xmail_port'] = 6017;
+
+
+// hMail Driver options
+// -----------------------
+// Remote hMailServer configuration
+// true: HMailserver is on a remote box (php.ini: com.allow_dcom = true)
+// false: Hmailserver is on same box as PHP
+$config['hmailserver_remote_dcom'] = false;
+// Windows credentials
+$config['hmailserver_server'] = array(
+ 'Server' => 'localhost', // hostname or ip address
+ 'Username' => 'administrator', // windows username
+ 'Password' => 'password' // windows user password
+);
+
+
+// Virtualmin Driver options
+// -------------------------
+// Username format:
+// 0: username@domain
+// 1: username%domain
+// 2: username.domain
+// 3: domain.username
+// 4: username-domain
+// 5: domain-username
+// 6: username_domain
+// 7: domain_username
+$config['password_virtualmin_format'] = 0;
+
+
+// pw_usermod Driver options
+// --------------------------
+// Use comma delimited exlist to disable password change for users
+// Add the following line to visudo to tighten security:
+// www ALL=NOPASSWORD: /usr/sbin/pw
+$config['password_pw_usermod_cmd'] = 'sudo /usr/sbin/pw usermod -h 0 -n';
+
+
+// DBMail Driver options
+// -------------------
+// Additional arguments for the dbmail-users call
+$config['password_dbmail_args'] = '-p sha512';
+
+
+// Expect Driver options
+// ---------------------
+// Location of expect binary
+$config['password_expect_bin'] = '/usr/bin/expect';
+
+// Location of expect script (see helpers/passwd-expect)
+$config['password_expect_script'] = '';
+
+// Arguments for the expect script. See the helpers/passwd-expect file for details.
+// This is probably a good starting default:
+// -telent -host localhost -output /tmp/passwd.log -log /tmp/passwd.log
+$config['password_expect_params'] = '';
+
+
+// smb Driver options
+// ---------------------
+// Samba host (default: localhost)
+// Supported replacement variables:
+// %n - hostname ($_SERVER['SERVER_NAME'])
+// %t - hostname without the first part
+// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
+$config['password_smb_host'] = 'localhost';
+// Location of smbpasswd binary
+$config['password_smb_cmd'] = '/usr/bin/smbpasswd';
+
+// gearman driver options
+// ---------------------
+// Gearman host (default: localhost)
+$config['password_gearman_host'] = 'localhost';
+
+
+
+// Plesk/PPA Driver options
+// --------------------
+// You need to allow RCP for IP of roundcube-server in Plesk/PPA Panel
+
+// Plesk RCP Host
+$config['password_plesk_host'] = '10.0.0.5';
+
+// Plesk RPC Username
+$config['password_plesk_user'] = 'admin';
+
+// Plesk RPC Password
+$config['password_plesk_pass'] = 'password';
+
+// Plesk RPC Port
+$config['password_plesk_rpc_port'] = '8443';
+
+// Plesk RPC Path
+$config['password_plesk_rpc_path'] = 'enterprise/control/agent.php';
+
+
+// kasswd Driver options
+// ---------------------
+// Command to use
+$config['password_kpasswd_cmd'] = '/usr/bin/kpasswd';
diff --git a/plugins/password/drivers/chpasswd.php b/plugins/password/drivers/chpasswd.php
new file mode 100644
index 000000000..45c56dba3
--- /dev/null
+++ b/plugins/password/drivers/chpasswd.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * chpasswd driver
+ *
+ * Driver that adds functionality to change the systems user password via
+ * the 'chpasswd' command.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 2.0
+ * @author Alex Cartwright <acartwright@mutinydesign.co.uk>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_chpasswd_password
+{
+ public function save($currpass, $newpass)
+ {
+ $cmd = rcmail::get_instance()->config->get('password_chpasswd_cmd');
+ $username = $_SESSION['username'];
+
+ $handle = popen($cmd, "w");
+ fwrite($handle, "$username:$newpass\n");
+
+ if (pclose($handle) == 0) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $cmd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/cpanel.php b/plugins/password/drivers/cpanel.php
new file mode 100644
index 000000000..663c125ce
--- /dev/null
+++ b/plugins/password/drivers/cpanel.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * cPanel Password Driver
+ *
+ * Driver that adds functionality to change the users cPanel password.
+ * Originally written by Fulvio Venturelli <fulvio@venturelli.org>
+ *
+ * Completely rewritten using the cPanel API2 call Email::passwdpop
+ * as opposed to the original coding against the UI, which is a fragile method that
+ * makes the driver to always return a failure message for any language other than English
+ * see http://trac.roundcube.net/ticket/1487015
+ *
+ * This driver has been tested with o2switch hosting and seems to work fine.
+ *
+ * @version 3.0
+ * @author Christian Chech <christian@chech.fr>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_cpanel_password
+{
+ public function save($curpas, $newpass)
+ {
+ require_once 'xmlapi.php';
+
+ $rcmail = rcmail::get_instance();
+
+ $this->cuser = $rcmail->config->get('password_cpanel_username');
+
+ // Setup the xmlapi connection
+ $this->xmlapi = new xmlapi($rcmail->config->get('password_cpanel_host'));
+ $this->xmlapi->set_port($rcmail->config->get('password_cpanel_port'));
+ $this->xmlapi->password_auth($this->cuser, $rcmail->config->get('password_cpanel_password'));
+ $this->xmlapi->set_output('json');
+ $this->xmlapi->set_debug(0);
+
+ if ($this->setPassword($_SESSION['username'], $newpass)) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ return PASSWORD_ERROR;
+ }
+ }
+
+ /**
+ * Change email account password
+ *
+ * Returns true on success or false on failure.
+ * @param string $password email account password
+ * @return bool
+ */
+ function setPassword($address, $password)
+ {
+ if (strpos($address, '@')) {
+ list($data['email'], $data['domain']) = explode('@', $address);
+ }
+ else {
+ list($data['email'], $data['domain']) = array($address, '');
+ }
+
+ $data['password'] = $password;
+
+ $query = $this->xmlapi->api2_query($this->cuser, 'Email', 'passwdpop', $data);
+ $query = json_decode($query, true);
+
+ if ($query['cpanelresult']['data'][0]['result'] == 1) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/plugins/password/drivers/dbmail.php b/plugins/password/drivers/dbmail.php
new file mode 100644
index 000000000..120728395
--- /dev/null
+++ b/plugins/password/drivers/dbmail.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * DBMail Password Driver
+ *
+ * Driver that adds functionality to change the users DBMail password.
+ * The code is derrived from the Squirrelmail "Change SASL Password" Plugin
+ * by Galen Johnson.
+ *
+ * It only works with dbmail-users on the same host where Roundcube runs
+ * and requires shell access and gcc in order to compile the binary.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 1.0
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_dbmail_password
+{
+ function save($currpass, $newpass)
+ {
+ $curdir = RCUBE_PLUGINS_DIR . 'password/helpers';
+ $username = escapeshellarg($_SESSION['username']);
+ $password = escapeshellarg($newpass);
+ $args = rcmail::get_instance()->config->get('password_dbmail_args', '');
+ $command = "$curdir/chgdbmailusers -c $username -w $password $args";
+
+ if (strlen($command) > 1024) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: The command is too long."
+ ), true, false);
+
+ return PASSWORD_ERROR;
+ }
+
+ exec($command, $output, $returnvalue);
+
+ if ($returnvalue == 0) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $curdir/chgdbmailusers"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/directadmin.php b/plugins/password/drivers/directadmin.php
new file mode 100644
index 000000000..08ade5130
--- /dev/null
+++ b/plugins/password/drivers/directadmin.php
@@ -0,0 +1,502 @@
+<?php
+
+/**
+ * DirectAdmin Password Driver
+ *
+ * Driver to change passwords via DirectAdmin Control Panel
+ *
+ * @version 2.1
+ * @author Victor Benincasa <vbenincasa@gmail.com>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_directadmin_password
+{
+ public function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+ $Socket = new HTTPSocket;
+
+ $da_user = $_SESSION['username'];
+ $da_curpass = $curpass;
+ $da_newpass = $passwd;
+ $da_host = $rcmail->config->get('password_directadmin_host');
+ $da_port = $rcmail->config->get('password_directadmin_port');
+
+ if (strpos($da_user, '@') === false) {
+ return array('code' => PASSWORD_ERROR, 'message' => 'Change the SYSTEM user password through control panel!');
+ }
+
+ $da_host = str_replace('%h', $_SESSION['imap_host'], $da_host);
+ $da_host = str_replace('%d', $rcmail->user->get_username('domain'), $da_host);
+
+ $Socket->connect($da_host,$da_port);
+ $Socket->set_method('POST');
+ $Socket->query('/CMD_CHANGE_EMAIL_PASSWORD',
+ array(
+ 'email' => $da_user,
+ 'oldpassword' => $da_curpass,
+ 'password1' => $da_newpass,
+ 'password2' => $da_newpass,
+ 'api' => '1'
+ ));
+ $response = $Socket->fetch_parsed_body();
+
+ //DEBUG
+ //rcube::console("Password Plugin: [USER: $da_user] [HOST: $da_host] - Response: [SOCKET: ".$Socket->result_status_code."] [DA ERROR: ".strip_tags($response['error'])."] [TEXT: ".$response[text]."]");
+
+ if($Socket->result_status_code != 200)
+ return array('code' => PASSWORD_CONNECT_ERROR, 'message' => $Socket->error[0]);
+ elseif($response['error'] == 1)
+ return array('code' => PASSWORD_ERROR, 'message' => strip_tags($response['text']));
+ else
+ return PASSWORD_SUCCESS;
+ }
+}
+
+
+/**
+ * Socket communication class.
+ *
+ * Originally designed for use with DirectAdmin's API, this class will fill any HTTP socket need.
+ *
+ * Very, very basic usage:
+ * $Socket = new HTTPSocket;
+ * echo $Socket->get('http://user:pass@somehost.com:2222/CMD_API_SOMEAPI?query=string&this=that');
+ *
+ * @author Phi1 'l0rdphi1' Stier <l0rdphi1@liquenox.net>
+ * @updates 2.7 and 2.8 by Victor Benincasa <vbenincasa @ gmail.com>
+ * @package HTTPSocket
+ * @version 2.8
+ */
+class HTTPSocket {
+
+ var $version = '2.8';
+
+ /* all vars are private except $error, $query_cache, and $doFollowLocationHeader */
+
+ var $method = 'GET';
+
+ var $remote_host;
+ var $remote_port;
+ var $remote_uname;
+ var $remote_passwd;
+
+ var $result;
+ var $result_header;
+ var $result_body;
+ var $result_status_code;
+
+ var $lastTransferSpeed;
+
+ var $bind_host;
+
+ var $error = array();
+ var $warn = array();
+ var $query_cache = array();
+
+ var $doFollowLocationHeader = TRUE;
+ var $redirectURL;
+
+ var $extra_headers = array();
+
+ /**
+ * Create server "connection".
+ *
+ */
+ function connect($host, $port = '' )
+ {
+ if (!is_numeric($port))
+ {
+ $port = 2222;
+ }
+
+ $this->remote_host = $host;
+ $this->remote_port = $port;
+ }
+
+ function bind( $ip = '' )
+ {
+ if ( $ip == '' )
+ {
+ $ip = $_SERVER['SERVER_ADDR'];
+ }
+
+ $this->bind_host = $ip;
+ }
+
+ /**
+ * Change the method being used to communicate.
+ *
+ * @param string|null request method. supports GET, POST, and HEAD. default is GET
+ */
+ function set_method( $method = 'GET' )
+ {
+ $this->method = strtoupper($method);
+ }
+
+ /**
+ * Specify a username and password.
+ *
+ * @param string|null username. defualt is null
+ * @param string|null password. defualt is null
+ */
+ function set_login( $uname = '', $passwd = '' )
+ {
+ if ( strlen($uname) > 0 )
+ {
+ $this->remote_uname = $uname;
+ }
+
+ if ( strlen($passwd) > 0 )
+ {
+ $this->remote_passwd = $passwd;
+ }
+
+ }
+
+ /**
+ * Query the server
+ *
+ * @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
+ * @param string|array query to pass to url
+ * @param int if connection KB/s drops below value here, will drop connection
+ */
+ function query( $request, $content = '', $doSpeedCheck = 0 )
+ {
+ $this->error = $this->warn = array();
+ $this->result_status_code = NULL;
+
+ // is our request a http(s):// ... ?
+ if (preg_match('/^(http|https):\/\//i',$request))
+ {
+ $location = parse_url($request);
+ $this->connect($location['host'],$location['port']);
+ $this->set_login($location['user'],$location['pass']);
+
+ $request = $location['path'];
+ $content = $location['query'];
+
+ if ( strlen($request) < 1 )
+ {
+ $request = '/';
+ }
+
+ }
+
+ $array_headers = array(
+ 'User-Agent' => "HTTPSocket/$this->version",
+ 'Host' => ( $this->remote_port == 80 ? parse_url($this->remote_host,PHP_URL_HOST) : parse_url($this->remote_host,PHP_URL_HOST).":".$this->remote_port ),
+ 'Accept' => '*/*',
+ 'Connection' => 'Close' );
+
+ foreach ( $this->extra_headers as $key => $value )
+ {
+ $array_headers[$key] = $value;
+ }
+
+ $this->result = $this->result_header = $this->result_body = '';
+
+ // was content sent as an array? if so, turn it into a string
+ if (is_array($content))
+ {
+ $pairs = array();
+
+ foreach ( $content as $key => $value )
+ {
+ $pairs[] = "$key=".urlencode($value);
+ }
+
+ $content = join('&',$pairs);
+ unset($pairs);
+ }
+
+ $OK = TRUE;
+
+ // instance connection
+ if ($this->bind_host)
+ {
+ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ socket_bind($socket,$this->bind_host);
+
+ if (!@socket_connect($socket,$this->remote_host,$this->remote_port))
+ {
+ $OK = FALSE;
+ }
+
+ }
+ else
+ {
+ $socket = @fsockopen( $this->remote_host, $this->remote_port, $sock_errno, $sock_errstr, 10 );
+ }
+
+ if ( !$socket || !$OK )
+ {
+ $this->error[] = "Can't create socket connection to $this->remote_host:$this->remote_port.";
+ return 0;
+ }
+
+ // if we have a username and password, add the header
+ if ( isset($this->remote_uname) && isset($this->remote_passwd) )
+ {
+ $array_headers['Authorization'] = 'Basic '.base64_encode("$this->remote_uname:$this->remote_passwd");
+ }
+
+ // for DA skins: if $this->remote_passwd is NULL, try to use the login key system
+ if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
+ {
+ $array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
+ }
+
+ // if method is POST, add content length & type headers
+ if ( $this->method == 'POST' )
+ {
+ $array_headers['Content-type'] = 'application/x-www-form-urlencoded';
+ $array_headers['Content-length'] = strlen($content);
+ }
+ // else method is GET or HEAD. we don't support anything else right now.
+ else
+ {
+ if ($content)
+ {
+ $request .= "?$content";
+ }
+ }
+
+ // prepare query
+ $query = "$this->method $request HTTP/1.0\r\n";
+ foreach ( $array_headers as $key => $value )
+ {
+ $query .= "$key: $value\r\n";
+ }
+ $query .= "\r\n";
+
+ // if POST we need to append our content
+ if ( $this->method == 'POST' && $content )
+ {
+ $query .= "$content\r\n\r\n";
+ }
+
+ // query connection
+ if ($this->bind_host)
+ {
+ socket_write($socket,$query);
+
+ // now load results
+ while ( $out = socket_read($socket,2048) )
+ {
+ $this->result .= $out;
+ }
+ }
+ else
+ {
+ fwrite( $socket, $query, strlen($query) );
+
+ // now load results
+ $this->lastTransferSpeed = 0;
+ $status = socket_get_status($socket);
+ $startTime = time();
+ $length = 0;
+ while ( !feof($socket) && !$status['timed_out'] )
+ {
+ $chunk = fgets($socket,1024);
+ $length += strlen($chunk);
+ $this->result .= $chunk;
+
+ $elapsedTime = time() - $startTime;
+
+ if ( $elapsedTime > 0 )
+ {
+ $this->lastTransferSpeed = ($length/1024)/$elapsedTime;
+ }
+
+ if ( $doSpeedCheck > 0 && $elapsedTime > 5 && $this->lastTransferSpeed < $doSpeedCheck )
+ {
+ $this->warn[] = "kB/s for last 5 seconds is below 50 kB/s (~".( ($length/1024)/$elapsedTime )."), dropping connection...";
+ $this->result_status_code = 503;
+ break;
+ }
+
+ }
+
+ if ( $this->lastTransferSpeed == 0 )
+ {
+ $this->lastTransferSpeed = $length/1024;
+ }
+
+ }
+
+ list($this->result_header,$this->result_body) = preg_split("/\r\n\r\n/",$this->result,2);
+
+ if ($this->bind_host)
+ {
+ socket_close($socket);
+ }
+ else
+ {
+ fclose($socket);
+ }
+
+ $this->query_cache[] = $query;
+
+
+ $headers = $this->fetch_header();
+
+ // what return status did we get?
+ if (!$this->result_status_code)
+ {
+ preg_match("#HTTP/1\.. (\d+)#",$headers[0],$matches);
+ $this->result_status_code = $matches[1];
+ }
+
+ // did we get the full file?
+ if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
+ {
+ $this->result_status_code = 206;
+ }
+
+ // now, if we're being passed a location header, should we follow it?
+ if ($this->doFollowLocationHeader)
+ {
+ if ($headers['location'])
+ {
+ $this->redirectURL = $headers['location'];
+ $this->query($headers['location']);
+ }
+ }
+ }
+
+ function getTransferSpeed()
+ {
+ return $this->lastTransferSpeed;
+ }
+
+ /**
+ * The quick way to get a URL's content :)
+ *
+ * @param string URL
+ * @param boolean return as array? (like PHP's file() command)
+ * @return string result body
+ */
+ function get($location, $asArray = FALSE )
+ {
+ $this->query($location);
+
+ if ( $this->get_status_code() == 200 )
+ {
+ if ($asArray)
+ {
+ return preg_split("/\n/",$this->fetch_body());
+ }
+
+ return $this->fetch_body();
+ }
+
+ return FALSE;
+ }
+
+ /**
+ * Returns the last status code.
+ * 200 = OK;
+ * 403 = FORBIDDEN;
+ * etc.
+ *
+ * @return int status code
+ */
+ function get_status_code()
+ {
+ return $this->result_status_code;
+ }
+
+ /**
+ * Adds a header, sent with the next query.
+ *
+ * @param string header name
+ * @param string header value
+ */
+ function add_header($key,$value)
+ {
+ $this->extra_headers[$key] = $value;
+ }
+
+ /**
+ * Clears any extra headers.
+ *
+ */
+ function clear_headers()
+ {
+ $this->extra_headers = array();
+ }
+
+ /**
+ * Return the result of a query.
+ *
+ * @return string result
+ */
+ function fetch_result()
+ {
+ return $this->result;
+ }
+
+ /**
+ * Return the header of result (stuff before body).
+ *
+ * @param string (optional) header to return
+ * @return array result header
+ */
+ function fetch_header( $header = '' )
+ {
+ $array_headers = preg_split("/\r\n/",$this->result_header);
+ $array_return = array( 0 => $array_headers[0] );
+ unset($array_headers[0]);
+
+ foreach ( $array_headers as $pair )
+ {
+ list($key,$value) = preg_split("/: /",$pair,2);
+ $array_return[strtolower($key)] = $value;
+ }
+
+ if ( $header != '' )
+ {
+ return $array_return[strtolower($header)];
+ }
+
+ return $array_return;
+ }
+
+ /**
+ * Return the body of result (stuff after header).
+ *
+ * @return string result body
+ */
+ function fetch_body()
+ {
+ return $this->result_body;
+ }
+
+ /**
+ * Return parsed body in array format.
+ *
+ * @return array result parsed
+ */
+ function fetch_parsed_body()
+ {
+ parse_str($this->result_body,$x);
+ return $x;
+ }
+
+}
diff --git a/plugins/password/drivers/domainfactory.php b/plugins/password/drivers/domainfactory.php
new file mode 100644
index 000000000..95088e9dd
--- /dev/null
+++ b/plugins/password/drivers/domainfactory.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * domainFACTORY Password Driver
+ *
+ * Driver to change passwords with the hosting provider domainFACTORY.
+ * http://www.df.eu/
+ *
+ * @version 2.1
+ * @author Till Krüss <me@tillkruess.com>
+ * @link http://tillkruess.com/projects/roundcube/
+ *
+ * Copyright (C) 2005-2014, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_domainfactory_password
+{
+ function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+
+ if (is_null($curpass)) {
+ $curpass = $rcmail->decrypt($_SESSION['password']);
+ }
+
+ if ($ch = curl_init()) {
+ // initial login
+ curl_setopt_array($ch, array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_URL => 'https://ssl.df.eu/chmail.php',
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => http_build_query(array(
+ 'login' => $rcmail->user->get_username(),
+ 'pwd' => $curpass,
+ 'action' => 'change'
+ ))
+ ));
+
+ if ($result = curl_exec($ch)) {
+ // login successful, get token!
+ $postfields = array(
+ 'pwd1' => $passwd,
+ 'pwd2' => $passwd,
+ 'action[update]' => 'Speichern'
+ );
+
+ preg_match_all('~<input name="(.+?)" type="hidden" value="(.+?)">~i', $result, $fields);
+ foreach ($fields[1] as $field_key => $field_name) {
+ $postfields[$field_name] = $fields[2][$field_key];
+ }
+
+ // change password
+ $ch = curl_copy_handle($ch);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields));
+ if ($result = curl_exec($ch)) {
+ // has the password been changed?
+ if (strpos($result, 'Einstellungen erfolgreich') !== false) {
+ return PASSWORD_SUCCESS;
+ }
+
+ // show error message(s) if possible
+ if (strpos($result, '<div class="d-msg-text">') !== false) {
+ preg_match_all('#<div class="d-msg-text">(.*?)</div>#s', $result, $errors);
+ if (isset($errors[1])) {
+ $error_message = '';
+ foreach ($errors[1] as $error) {
+ $error_message .= trim(mb_convert_encoding( $error, 'UTF-8', 'ISO-8859-15' )).' ';
+ }
+ return array('code' => PASSWORD_ERROR, 'message' => $error_message);
+ }
+ }
+ }
+ else {
+ return PASSWORD_CONNECT_ERROR;
+ }
+ }
+ else {
+ return PASSWORD_CONNECT_ERROR;
+ }
+ }
+ else {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/expect.php b/plugins/password/drivers/expect.php
new file mode 100644
index 000000000..57fe905ee
--- /dev/null
+++ b/plugins/password/drivers/expect.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * expect driver
+ *
+ * Driver that adds functionality to change the systems user password via
+ * the 'expect' command.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 2.0
+ * @author Andy Theuninck <gohanman@gmail.com)
+ *
+ * Based on chpasswd roundcubemail password driver by
+ * @author Alex Cartwright <acartwright@mutinydesign.co.uk)
+ * and expect horde passwd driver by
+ * @author Gaudenz Steinlin <gaudenz@soziologie.ch>
+ *
+ * Configuration settings:
+ * password_expect_bin => location of expect (e.g. /usr/bin/expect)
+ * password_expect_script => path to "password-expect" file
+ * password_expect_params => arguments for the expect script
+ * see the password-expect file for details. This is probably
+ * a good starting default:
+ * -telent -host localhost -output /tmp/passwd.log -log /tmp/passwd.log
+ *
+ * Copyright (C) 2005-2014, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_expect_password
+{
+ public function save($currpass, $newpass)
+ {
+ $rcmail = rcmail::get_instance();
+ $bin = $rcmail->config->get('password_expect_bin');
+ $script = $rcmail->config->get('password_expect_script');
+ $params = $rcmail->config->get('password_expect_params');
+ $username = $_SESSION['username'];
+
+ $cmd = $bin . ' -f ' . $script . ' -- ' . $params;
+ $handle = popen($cmd, "w");
+ fwrite($handle, "$username\n");
+ fwrite($handle, "$currpass\n");
+ fwrite($handle, "$newpass\n");
+
+ if (pclose($handle) == 0) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $cmd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/gearman.php b/plugins/password/drivers/gearman.php
new file mode 100644
index 000000000..983aee046
--- /dev/null
+++ b/plugins/password/drivers/gearman.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * Gearman Password Driver
+ *
+ * Payload is json string containing username, oldPassword and newPassword
+ * Return value is a json string saying result: true if success.
+ *
+ * @version 1.0
+ * @author Mohammad Anwari <mdamt@mdamt.net>
+ *
+ * Copyright (C) 2005-2014, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_gearman_password
+{
+ function save($currpass, $newpass)
+ {
+ if (extension_loaded('gearman')) {
+ $rcmail = rcmail::get_instance();
+ $user = $_SESSION['username'];
+ $payload = array(
+ 'username' => $user,
+ 'oldPassword' => $currpass,
+ 'newPassword' => $newpass,
+ );
+
+ $gmc = new GearmanClient();
+ $gmc->addServer($rcmail->config->get('password_gearman_host'));
+
+ $result = $gmc->doNormal('setPassword', json_encode($payload));
+ $success = json_decode($result);
+
+ if ($success && $success->result == 1) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Gearman authentication failed for user $user: $error"
+ ), true, false);
+ }
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: PECL Gearman module not loaded"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/hmail.php b/plugins/password/drivers/hmail.php
new file mode 100644
index 000000000..49f7f6cf4
--- /dev/null
+++ b/plugins/password/drivers/hmail.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * hMailserver password driver
+ *
+ * @version 2.0
+ * @author Roland 'rosali' Liebl <myroundcube@mail4us.net>
+ *
+ * Copyright (C) 2005-2014, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_hmail_password
+{
+ public function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+
+ if ($curpass == '' || $passwd == '') {
+ return PASSWORD_ERROR;
+ }
+
+ try {
+ $remote = $rcmail->config->get('hmailserver_remote_dcom', false);
+ if ($remote)
+ $obApp = new COM("hMailServer.Application", $rcmail->config->get('hmailserver_server'));
+ else
+ $obApp = new COM("hMailServer.Application");
+ }
+ catch (Exception $e) {
+ rcube::write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage())));
+ rcube::write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set.");
+ return PASSWORD_ERROR;
+ }
+
+ $username = $rcmail->user->data['username'];
+ if (strstr($username,'@')){
+ $temparr = explode('@', $username);
+ $domain = $temparr[1];
+ }
+ else {
+ $domain = $rcmail->config->get('username_domain',false);
+ if (!$domain) {
+ rcube::write_log('errors','Plugin password (hmail driver): $config[\'username_domain\'] is not defined.');
+ return PASSWORD_ERROR;
+ }
+ $username = $username . "@" . $domain;
+ }
+
+ $obApp->Authenticate($username, $curpass);
+ try {
+ $obDomain = $obApp->Domains->ItemByName($domain);
+ $obAccount = $obDomain->Accounts->ItemByAddress($username);
+ $obAccount->Password = $passwd;
+ $obAccount->Save();
+ return PASSWORD_SUCCESS;
+ }
+ catch (Exception $e) {
+ rcube::write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage())));
+ rcube::write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set.");
+ return PASSWORD_ERROR;
+ }
+ }
+}
diff --git a/plugins/password/drivers/kpasswd.php b/plugins/password/drivers/kpasswd.php
new file mode 100644
index 000000000..ce245b315
--- /dev/null
+++ b/plugins/password/drivers/kpasswd.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * kpasswd Driver
+ *
+ * Driver that adds functionality to change the systems user password via
+ * the 'kpasswd' command.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 1.0
+ * @author Peter Allgeyer <peter.allgeyer@salzburgresearch.at>
+ *
+ * Based on chpasswd roundcubemail password driver by
+ * @author Alex Cartwright <acartwright@mutinydesign.co.uk>
+ */
+
+class rcube_kpasswd_password
+{
+ public function save($currpass, $newpass)
+ {
+ $bin = rcmail::get_instance()->config->get('password_kpasswd_cmd', '/usr/bin/kpasswd');
+ $username = $_SESSION['username'];
+ $cmd = $bin . ' "' . $username . '" 2>&1';
+
+ $handle = popen($cmd, "w");
+ fwrite($handle, $currpass."\n");
+ fwrite($handle, $newpass."\n");
+ fwrite($handle, $newpass."\n");
+
+ if (pclose($handle) == 0) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $cmd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/ldap.php b/plugins/password/drivers/ldap.php
new file mode 100644
index 000000000..6ed5ada04
--- /dev/null
+++ b/plugins/password/drivers/ldap.php
@@ -0,0 +1,381 @@
+<?php
+
+/**
+ * LDAP Password Driver
+ *
+ * Driver for passwords stored in LDAP
+ * This driver use the PEAR Net_LDAP2 class (http://pear.php.net/package/Net_LDAP2).
+ *
+ * @version 2.0
+ * @author Edouard MOREAU <edouard.moreau@ensma.fr>
+ *
+ * method hashPassword based on code from the phpLDAPadmin development team (http://phpldapadmin.sourceforge.net/).
+ * method randomSalt based on code from the phpLDAPadmin development team (http://phpldapadmin.sourceforge.net/).
+ *
+ * Copyright (C) 2005-2014, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_ldap_password
+{
+ public function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+ require_once 'Net/LDAP2.php';
+
+ // Building user DN
+ if ($userDN = $rcmail->config->get('password_ldap_userDN_mask')) {
+ $userDN = self::substitute_vars($userDN);
+ }
+ else {
+ $userDN = $this->search_userdn($rcmail);
+ }
+
+ if (empty($userDN)) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ // Connection Method
+ switch($rcmail->config->get('password_ldap_method')) {
+ case 'admin':
+ $binddn = $rcmail->config->get('password_ldap_adminDN');
+ $bindpw = $rcmail->config->get('password_ldap_adminPW');
+ break;
+ case 'user':
+ default:
+ $binddn = $userDN;
+ $bindpw = $curpass;
+ break;
+ }
+
+ // Configuration array
+ $ldapConfig = array (
+ 'binddn' => $binddn,
+ 'bindpw' => $bindpw,
+ 'basedn' => $rcmail->config->get('password_ldap_basedn'),
+ 'host' => $rcmail->config->get('password_ldap_host'),
+ 'port' => $rcmail->config->get('password_ldap_port'),
+ 'starttls' => $rcmail->config->get('password_ldap_starttls'),
+ 'version' => $rcmail->config->get('password_ldap_version'),
+ );
+
+ // Connecting using the configuration array
+ $ldap = Net_LDAP2::connect($ldapConfig);
+
+ // Checking for connection error
+ if (is_a($ldap, 'PEAR_Error')) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ $force = $rcmail->config->get('password_ldap_force_replace');
+ $pwattr = $rcmail->config->get('password_ldap_pwattr');
+ $lchattr = $rcmail->config->get('password_ldap_lchattr');
+ $smbpwattr = $rcmail->config->get('password_ldap_samba_pwattr');
+ $smblchattr = $rcmail->config->get('password_ldap_samba_lchattr');
+ $samba = $rcmail->config->get('password_ldap_samba');
+ $encodage = $rcmail->config->get('password_ldap_encodage');
+
+ // Support multiple userPassword values where desired.
+ // multiple encodings can be specified separated by '+' (e.g. "cram-md5+ssha")
+ $encodages = explode('+', $encodage);
+ $crypted_pass = array();
+
+ foreach ($encodages as $enc) {
+ $cpw = self::hash_password($passwd, $enc);
+ if (!empty($cpw)) {
+ $crypted_pass[] = $cpw;
+ }
+ }
+
+ // Support password_ldap_samba option for backward compat.
+ if ($samba && !$smbpwattr) {
+ $smbpwattr = 'sambaNTPassword';
+ $smblchattr = 'sambaPwdLastSet';
+ }
+
+ // Crypt new password
+ if (empty($crypted_pass)) {
+ return PASSWORD_CRYPT_ERROR;
+ }
+
+ // Crypt new samba password
+ if ($smbpwattr && !($samba_pass = self::hash_password($passwd, 'samba'))) {
+ return PASSWORD_CRYPT_ERROR;
+ }
+
+ // Writing new crypted password to LDAP
+ $userEntry = $ldap->getEntry($userDN);
+ if (Net_LDAP2::isError($userEntry)) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ if (!$userEntry->replace(array($pwattr => $crypted_pass), $force)) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ // Updating PasswordLastChange Attribute if desired
+ if ($lchattr) {
+ $current_day = (int)(time() / 86400);
+ if (!$userEntry->replace(array($lchattr => $current_day), $force)) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+ }
+
+ // Update Samba password and last change fields
+ if ($smbpwattr) {
+ $userEntry->replace(array($smbpwattr => $samba_pass), $force);
+ }
+ // Update Samba password last change field
+ if ($smblchattr) {
+ $userEntry->replace(array($smblchattr => time()), $force);
+ }
+
+ if (Net_LDAP2::isError($userEntry->update())) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ // All done, no error
+ return PASSWORD_SUCCESS;
+ }
+
+ /**
+ * Bind with searchDN and searchPW and search for the user's DN.
+ * Use search_base and search_filter defined in config file.
+ * Return the found DN.
+ */
+ function search_userdn($rcmail)
+ {
+ $binddn = $rcmail->config->get('password_ldap_searchDN');
+ $bindpw = $rcmail->config->get('password_ldap_searchPW');
+
+ $ldapConfig = array (
+ 'basedn' => $rcmail->config->get('password_ldap_basedn'),
+ 'host' => $rcmail->config->get('password_ldap_host'),
+ 'port' => $rcmail->config->get('password_ldap_port'),
+ 'starttls' => $rcmail->config->get('password_ldap_starttls'),
+ 'version' => $rcmail->config->get('password_ldap_version'),
+ );
+
+ // allow anonymous searches
+ if (!empty($binddn)) {
+ $ldapConfig['binddn'] = $binddn;
+ $ldapConfig['bindpw'] = $bindpw;
+ }
+
+ $ldap = Net_LDAP2::connect($ldapConfig);
+
+ if (is_a($ldap, 'PEAR_Error')) {
+ return '';
+ }
+
+ $base = self::substitute_vars($rcmail->config->get('password_ldap_search_base'));
+ $filter = self::substitute_vars($rcmail->config->get('password_ldap_search_filter'));
+ $options = array (
+ 'scope' => 'sub',
+ 'attributes' => array(),
+ );
+
+ $result = $ldap->search($base, $filter, $options);
+ $ldap->done();
+ if (is_a($result, 'PEAR_Error') || ($result->count() != 1)) {
+ return '';
+ }
+
+ return $result->current()->dn();
+ }
+
+ /**
+ * Substitute %login, %name, %domain, %dc in $str
+ * See plugin config for details
+ */
+ static function substitute_vars($str)
+ {
+ $str = str_replace('%login', $_SESSION['username'], $str);
+ $str = str_replace('%l', $_SESSION['username'], $str);
+
+ $parts = explode('@', $_SESSION['username']);
+
+ if (count($parts) == 2) {
+ $dc = 'dc='.strtr($parts[1], array('.' => ',dc=')); // hierarchal domain string
+
+ $str = str_replace('%name', $parts[0], $str);
+ $str = str_replace('%n', $parts[0], $str);
+ $str = str_replace('%dc', $dc, $str);
+ $str = str_replace('%domain', $parts[1], $str);
+ $str = str_replace('%d', $parts[1], $str);
+ }
+
+ return $str;
+ }
+
+ /**
+ * Code originaly from the phpLDAPadmin development team
+ * http://phpldapadmin.sourceforge.net/
+ *
+ * Hashes a password and returns the hash based on the specified enc_type
+ */
+ static function hash_password($password_clear, $encodage_type)
+ {
+ $encodage_type = strtolower($encodage_type);
+ switch ($encodage_type) {
+ case 'crypt':
+ $crypted_password = '{CRYPT}' . crypt($password_clear, self::random_salt(2));
+ break;
+
+ case 'ext_des':
+ /* Extended DES crypt. see OpenBSD crypt man page */
+ if (!defined('CRYPT_EXT_DES') || CRYPT_EXT_DES == 0) {
+ /* Your system crypt library does not support extended DES encryption */
+ return false;
+ }
+
+ $crypted_password = '{CRYPT}' . crypt($password_clear, '_' . self::random_salt(8));
+ break;
+
+ case 'md5crypt':
+ if (!defined('CRYPT_MD5') || CRYPT_MD5 == 0) {
+ /* Your system crypt library does not support md5crypt encryption */
+ return false;
+ }
+
+ $crypted_password = '{CRYPT}' . crypt($password_clear, '$1$' . self::random_salt(9));
+ break;
+
+ case 'blowfish':
+ if (!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH == 0) {
+ /* Your system crypt library does not support blowfish encryption */
+ return false;
+ }
+
+ $rcmail = rcmail::get_instance();
+ $cost = (int) $rcmail->config->get('password_blowfish_cost');
+ $cost = $cost < 4 || $cost > 31 ? 12 : $cost;
+ $prefix = sprintf('$2a$%02d$', $cost);
+
+ $crypted_password = '{CRYPT}' . crypt($password_clear, $prefix . self::random_salt(22));
+ break;
+
+ case 'md5':
+ $crypted_password = '{MD5}' . base64_encode(pack('H*', md5($password_clear)));
+ break;
+
+ case 'sha':
+ if (function_exists('sha1')) {
+ /* Use PHP 4.3.0+ sha1 function, if it is available */
+ $crypted_password = '{SHA}' . base64_encode(pack('H*', sha1($password_clear)));
+ }
+ else if (function_exists('hash')) {
+ $crypted_password = '{SHA}' . base64_encode(hash('sha1', $password_clear, true));
+ }
+ else if (function_exists('mhash')) {
+ $crypted_password = '{SHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear));
+ }
+ else {
+ /* Your PHP install does not have the mhash()/hash() nor sha1() function */
+ return false;
+ }
+ break;
+
+ case 'ssha':
+ $salt = substr(pack('h*', md5(mt_rand())), 0, 8);
+
+ if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
+ $salt = mhash_keygen_s2k(MHASH_SHA1, $password_clear, $salt, 4);
+ $password = mhash(MHASH_SHA1, $password_clear . $salt);
+ }
+ else if (function_exists('sha1')) {
+ $salt = substr(pack("H*", sha1($salt . $password_clear)), 0, 4);
+ $password = sha1($password_clear . $salt, true);
+ }
+ else if (function_exists('hash')) {
+ $salt = substr(pack("H*", hash('sha1', $salt . $password_clear)), 0, 4);
+ $password = hash('sha1', $password_clear . $salt, true);
+ }
+
+ if ($password) {
+ $crypted_password = '{SSHA}' . base64_encode($password . $salt);
+ }
+ else {
+ /* Your PHP install does not have the mhash()/hash() nor sha1() function */
+ return false;
+ }
+ break;
+
+
+ case 'smd5':
+ $salt = substr(pack('h*', md5(mt_rand())), 0, 8);
+
+ if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
+ $salt = mhash_keygen_s2k(MHASH_MD5, $password_clear, $salt, 4);
+ $password = mhash(MHASH_MD5, $password_clear . $salt);
+ }
+ else if (function_exists('hash')) {
+ $salt = substr(pack("H*", hash('md5', $salt . $password_clear)), 0, 4);
+ $password = hash('md5', $password_clear . $salt, true);
+ }
+ else {
+ $salt = substr(pack("H*", md5($salt . $password_clear)), 0, 4);
+ $password = md5($password_clear . $salt, true);
+ }
+
+ $crypted_password = '{SMD5}' . base64_encode($password . $salt);
+ break;
+
+ case 'samba':
+ if (function_exists('hash')) {
+ $crypted_password = hash('md4', rcube_charset::convert($password_clear, RCUBE_CHARSET, 'UTF-16LE'));
+ $crypted_password = strtoupper($crypted_password);
+ }
+ else {
+ /* Your PHP install does not have the hash() function */
+ return false;
+ }
+ break;
+
+ case 'ad':
+ $crypted_password = rcube_charset::convert('"' . $password_clear . '"', RCUBE_CHARSET, 'UTF-16LE');
+ break;
+
+ case 'cram-md5':
+ require_once __DIR__ . '/../helpers/dovecot_hmacmd5.php';
+ return dovecot_hmacmd5($password_clear);
+ break;
+
+ case 'clear':
+ default:
+ $crypted_password = $password_clear;
+ }
+
+ return $crypted_password;
+ }
+
+ /**
+ * Code originaly from the phpLDAPadmin development team
+ * http://phpldapadmin.sourceforge.net/
+ *
+ * Used to generate a random salt for crypt-style passwords
+ */
+ static function random_salt($length)
+ {
+ $possible = '0123456789' . 'abcdefghijklmnopqrstuvwxyz' . 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . './';
+ $str = '';
+
+ while (strlen($str) < $length) {
+ $str .= substr($possible, (rand() % strlen($possible)), 1);
+ }
+
+ return $str;
+ }
+}
diff --git a/plugins/password/drivers/ldap_simple.php b/plugins/password/drivers/ldap_simple.php
new file mode 100644
index 000000000..9123ea81f
--- /dev/null
+++ b/plugins/password/drivers/ldap_simple.php
@@ -0,0 +1,238 @@
+<?php
+
+/**
+ * Simple LDAP Password Driver
+ *
+ * Driver for passwords stored in LDAP
+ * This driver is based on Edouard's LDAP Password Driver, but does not
+ * require PEAR's Net_LDAP2 to be installed
+ *
+ * @version 2.0
+ * @author Wout Decre <wout@canodus.be>
+ * @author Aleksander Machniak <machniak@kolabsys.com>
+ *
+ * Copyright (C) 2005-2014, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_ldap_simple_password
+{
+ private $debug = false;
+
+ function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+
+ $this->debug = $rcmail->config->get('ldap_debug');
+
+ $ldap_host = $rcmail->config->get('password_ldap_host');
+ $ldap_port = $rcmail->config->get('password_ldap_port');
+
+ $this->_debug("C: Connect to $ldap_host:$ldap_port");
+
+ // Connect
+ if (!$ds = ldap_connect($ldap_host, $ldap_port)) {
+ $this->_debug("S: NOT OK");
+
+ rcube::raise_error(array(
+ 'code' => 100, 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Could not connect to LDAP server"
+ ),
+ true);
+
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ $this->_debug("S: OK");
+
+ // Set protocol version
+ ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $rcmail->config->get('password_ldap_version'));
+
+ // Start TLS
+ if ($rcmail->config->get('password_ldap_starttls')) {
+ if (!ldap_start_tls($ds)) {
+ ldap_unbind($ds);
+ return PASSWORD_CONNECT_ERROR;
+ }
+ }
+
+ // include 'ldap' driver, we share some static methods with it
+ require_once INSTALL_PATH . 'plugins/password/drivers/ldap.php';
+
+ // other plugins might want to modify user DN
+ $plugin = $rcmail->plugins->exec_hook('password_ldap_bind', array(
+ 'user_dn' => '', 'conn' => $ds));
+
+ // Build user DN
+ if (!empty($plugin['user_dn'])) {
+ $user_dn = $plugin['user_dn'];
+ }
+ else if ($user_dn = $rcmail->config->get('password_ldap_userDN_mask')) {
+ $user_dn = rcube_ldap_password::substitute_vars($user_dn);
+ }
+ else {
+ $user_dn = $this->search_userdn($rcmail, $ds);
+ }
+
+ if (empty($user_dn)) {
+ ldap_unbind($ds);
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ // Connection method
+ switch ($rcmail->config->get('password_ldap_method')) {
+ case 'admin':
+ $binddn = $rcmail->config->get('password_ldap_adminDN');
+ $bindpw = $rcmail->config->get('password_ldap_adminPW');
+ break;
+ case 'user':
+ default:
+ $binddn = $user_dn;
+ $bindpw = $curpass;
+ break;
+ }
+
+ $lchattr = $rcmail->config->get('password_ldap_lchattr');
+ $pwattr = $rcmail->config->get('password_ldap_pwattr');
+ $smbpwattr = $rcmail->config->get('password_ldap_samba_pwattr');
+ $smblchattr = $rcmail->config->get('password_ldap_samba_lchattr');
+ $samba = $rcmail->config->get('password_ldap_samba');
+ $pass_mode = $rcmail->config->get('password_ldap_encodage');
+ $crypted_pass = rcube_ldap_password::hash_password($passwd, $pass_mode);
+
+ // Support password_ldap_samba option for backward compat.
+ if ($samba && !$smbpwattr) {
+ $smbpwattr = 'sambaNTPassword';
+ $smblchattr = 'sambaPwdLastSet';
+ }
+
+ // Crypt new password
+ if (!$crypted_pass) {
+ return PASSWORD_CRYPT_ERROR;
+ }
+
+ // Crypt new Samba password
+ if ($smbpwattr && !($samba_pass = rcube_ldap_password::hash_password($passwd, 'samba'))) {
+ return PASSWORD_CRYPT_ERROR;
+ }
+
+ $this->_debug("C: Bind $binddn, pass: **** [" . strlen($bindpw) . "]");
+
+ // Bind
+ if (!ldap_bind($ds, $binddn, $bindpw)) {
+ $this->_debug("S: ".ldap_error($ds));
+
+ ldap_unbind($ds);
+
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ $this->_debug("S: OK");
+
+ $entry[$pwattr] = $crypted_pass;
+
+ // Update PasswordLastChange Attribute if desired
+ if ($lchattr) {
+ $entry[$lchattr] = (int)(time() / 86400);
+ }
+
+ // Update Samba password
+ if ($smbpwattr) {
+ $entry[$smbpwattr] = $samba_pass;
+ }
+
+ // Update Samba password last change
+ if ($smblchattr) {
+ $entry[$smblchattr] = time();
+ }
+
+ $this->_debug("C: Modify $user_dn: " . print_r($entry, true));
+
+ if (!ldap_modify($ds, $user_dn, $entry)) {
+ $this->_debug("S: ".ldap_error($ds));
+
+ ldap_unbind($ds);
+
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ $this->_debug("S: OK");
+
+ // All done, no error
+ ldap_unbind($ds);
+
+ return PASSWORD_SUCCESS;
+ }
+
+ /**
+ * Bind with searchDN and searchPW and search for the user's DN
+ * Use search_base and search_filter defined in config file
+ * Return the found DN
+ */
+ function search_userdn($rcmail, $ds)
+ {
+ $search_user = $rcmail->config->get('password_ldap_searchDN');
+ $search_pass = $rcmail->config->get('password_ldap_searchPW');
+ $search_base = $rcmail->config->get('password_ldap_search_base');
+ $search_filter = $rcmail->config->get('password_ldap_search_filter');
+
+ if (empty($search_filter)) {
+ return false;
+ }
+
+ $this->_debug("C: Bind " . ($search_user ? $search_user : '[anonymous]'));
+
+ // Bind
+ if (!ldap_bind($ds, $search_user, $search_pass)) {
+ $this->_debug("S: ".ldap_error($ds));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+
+ $search_base = rcube_ldap_password::substitute_vars($search_base);
+ $search_filter = rcube_ldap_password::substitute_vars($search_filter);
+
+ $this->_debug("C: Search $search_base for $search_filter");
+
+ // Search for the DN
+ if (!$sr = ldap_search($ds, $search_base, $search_filter)) {
+ $this->_debug("S: ".ldap_error($ds));
+ return false;
+ }
+
+ $found = ldap_count_entries($ds, $sr);
+
+ $this->_debug("S: OK [found $found records]");
+
+ // If no or more entries were found, return false
+ if ($found != 1) {
+ return false;
+ }
+
+ return ldap_get_dn($ds, ldap_first_entry($ds, $sr));
+ }
+
+ /**
+ * Prints debug info to the log
+ */
+ private function _debug($str)
+ {
+ if ($this->debug) {
+ rcube::write_log('ldap', $str);
+ }
+ }
+}
diff --git a/plugins/password/drivers/pam.php b/plugins/password/drivers/pam.php
new file mode 100644
index 000000000..cd5a92f49
--- /dev/null
+++ b/plugins/password/drivers/pam.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * PAM Password Driver
+ *
+ * @version 2.0
+ * @author Aleksander Machniak
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_pam_password
+{
+ function save($currpass, $newpass)
+ {
+ $user = $_SESSION['username'];
+ $error = '';
+
+ if (extension_loaded('pam') || extension_loaded('pam_auth')) {
+ if (pam_auth($user, $currpass, $error, false)) {
+ if (pam_chpass($user, $currpass, $newpass)) {
+ return PASSWORD_SUCCESS;
+ }
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: PAM authentication failed for user $user: $error"
+ ), true, false);
+ }
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: PECL-PAM module not loaded"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/plesk.php b/plugins/password/drivers/plesk.php
new file mode 100644
index 000000000..db9ad9efd
--- /dev/null
+++ b/plugins/password/drivers/plesk.php
@@ -0,0 +1,241 @@
+<?php
+
+/**
+ * Roundcube Password Driver for Plesk-RPC.
+ *
+ * This driver changes a E-Mail-Password via Plesk-RPC
+ * Deps: PHP-Curl, SimpleXML
+ *
+ * @author Cyrill von Wattenwyl <cyrill.vonwattenwyl@adfinis-sygroup.ch>
+ * @copyright Adfinis SyGroup AG, 2014
+ *
+ * Config needed:
+ * $config['password_plesk_host'] = '10.0.0.5';
+ * $config['password_plesk_user'] = 'admin';
+ * $config['password_plesk_pass'] = 'pass';
+ * $config['password_plesk_rpc_port'] = 8443;
+ * $config['password_plesk_rpc_path'] = enterprise/control/agent.php;
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+/**
+ * Roundcube Password Driver Class
+ *
+ * See {ROUNDCUBE_ROOT}/plugins/password/README for API description
+ *
+ * @author Cyrill von Wattenwyl <cyrill.vonwattenwyl@adfinis-sygroup.ch>
+ */
+class rcube_plesk_password
+{
+ /**
+ * this method is called from roundcube to change the password
+ *
+ * roundcube allready validated the old password so we just need to change it at this point
+ *
+ * @author Cyrill von Wattenwyl <cyrill.vonwattenwyl@adfinis-sygroup.ch>
+ * @param string $curpass Current password
+ * @param string $newpass New password
+ * @returns int PASSWORD_SUCCESS|PASSWORD_ERROR
+ */
+ function save($currpass, $newpass)
+ {
+ // get config
+ $rcmail = rcmail::get_instance();
+ $host = $rcmail->config->get('password_plesk_host');
+ $user = $rcmail->config->get('password_plesk_user');
+ $pass = $rcmail->config->get('password_plesk_pass');
+ $port = $rcmail->config->get('password_plesk_rpc_port');
+ $path = $rcmail->config->get('password_plesk_rpc_path');
+
+ // create plesk-object
+ $plesk = new plesk_rpc;
+ $plesk->init($host, $port, $path, $user, $pass);
+
+ // try to change password and return the status
+ $result = $plesk->change_mailbox_password($_SESSION['username'], $newpass);
+ //$plesk->destroy();
+
+ if ($result) {
+ return PASSWORD_SUCCESS;
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
+
+
+/**
+ * Plesk RPC-Class
+ *
+ * Striped down version of Plesk-RPC-Class
+ * Just functions for changing mail-passwords included
+ *
+ * Documentation of Plesk RPC-API: http://download1.parallels.com/Plesk/PP11/11.0/Doc/en-US/online/plesk-api-rpc/
+ *
+ * @author Cyrill von Wattenwyl <cyrill.vonwattenwyl@adfinis-sygroup.ch>
+ */
+class plesk_rpc
+{
+ /**
+ * init plesk-rpc via curl
+ *
+ * @param string $host plesk host
+ * @param string $port plesk rpc port
+ * @param string $path plesk rpc path
+ * @param string $user plesk user
+ * @param string $user plesk password
+ * @returns void
+ */
+ function init($host, $port, $path, $user, $pass)
+ {
+ $headers = array(
+ sprintf("HTTP_AUTH_LOGIN: %s", $user),
+ sprintf("HTTP_AUTH_PASSWD: %s", $pass),
+ "Content-Type: text/xml"
+ );
+
+ $url = sprintf("https://%s:%s/%s", $host, $port, $path);
+ $this->curl = curl_init();
+
+ curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT , 5);
+ curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST , 0);
+ curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER , false);
+ curl_setopt($this->curl, CURLOPT_HTTPHEADER , $headers);
+ curl_setopt($this->curl, CURLOPT_URL , $url);
+ }
+
+ /**
+ * send a request to the plesk
+ *
+ * @param string $packet XML-Packet to send to Plesk
+ * @returns bool request was successfull or not
+ */
+ function send_request($packet)
+ {
+ curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($this->curl, CURLOPT_POSTFIELDS, $packet);
+ $retval = curl_exec($this->curl);
+
+ return $retval;
+ }
+
+ /**
+ * close curl
+ */
+ function destroy(){
+ curl_close($this->curl);
+ }
+
+ /**
+ * Creates an Initial SimpleXML-Object for Plesk-RPC
+ *
+ * @returns object SimpleXML object
+ */
+ function get_request_obj()
+ {
+ $request = new SimpleXMLElement("<packet></packet>");
+ $request->addAttribute("version", "1.6.3.0");
+
+ return $request;
+ }
+
+ /**
+ * Get all hosting-informations of a domain
+ *
+ * @param string $domain domain-name
+ * @returns object SimpleXML object
+ */
+ function domain_info($domain)
+ {
+ // build xml
+ $request = $this->get_request_obj();
+ $site = $request->addChild("site");
+ $get = $site->addChild("get");
+ $filter = $get->addChild("filter");
+
+ $filter->addChild("name", utf8_encode($domain));
+ $dataset = $get->addChild("dataset");
+
+ $dataset->addChild("hosting");
+ $packet = $request->asXML();
+
+ // send the request
+ $res = $this->send_request($packet);
+
+ // make it to simple-xml-object
+ $xml = new SimpleXMLElement($res);
+
+ return $xml;
+ }
+
+ /**
+ * Get psa-id of a domain
+ *
+ * @param string $domain domain-name
+ *
+ * @returns bool|int false if failed and integer if successed
+ */
+ function get_domain_id($domain)
+ {
+ $xml = $this->domain_info($domain);
+ $id = intval($xml->site->get->result->id);
+ $id = (is_int($id)) ? $id : false;
+
+ return $id;
+ }
+
+ /**
+ * Change Password of a mailbox
+ *
+ * @param string $mailbox full email-adress (user@domain.tld)
+ * @param string $newpass new password of mailbox
+ *
+ * @returns bool
+ */
+ function change_mailbox_password($mailbox, $newpass)
+ {
+ list($user, $domain) = explode("@", $mailbox);
+ $domain_id = $this->get_domain_id($domain);
+
+ // if domain cannot be resolved to an id, do not continue
+ if (!$domain_id) {
+ return false;
+ }
+
+ // build xml-packet
+ $request = $this -> get_request_obj();
+ $mail = $request -> addChild("mail");
+ $update = $mail -> addChild("update");
+ $add = $update -> addChild("set");
+ $filter = $add -> addChild("filter");
+ $filter->addChild("site-id", $domain_id);
+
+ $mailname = $filter->addChild("mailname");
+ $mailname->addChild("name", $user);
+
+ $password = $mailname->addChild("password");
+ $password->addChild("value", $newpass);
+ $password->addChild("type", "plain");
+
+ $packet = $request->asXML();
+
+ // send the request to plesk
+ $res = $this->send_request($packet);
+ $xml = new SimpleXMLElement($res);
+ $res = strval($xml->mail->update->set->result->status);
+
+ return $res == "ok";
+ }
+}
diff --git a/plugins/password/drivers/poppassd.php b/plugins/password/drivers/poppassd.php
new file mode 100644
index 000000000..7a2821083
--- /dev/null
+++ b/plugins/password/drivers/poppassd.php
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * Poppassd Password Driver
+ *
+ * Driver to change passwords via Poppassd/Courierpassd
+ *
+ * @version 2.0
+ * @author Philip Weir
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_poppassd_password
+{
+ function format_error_result($code, $line)
+ {
+ if (preg_match('/^\d\d\d\s+(\S.*)\s*$/', $line, $matches)) {
+ return array('code' => $code, 'message' => $matches[1]);
+ }
+
+ return $code;
+ }
+
+ function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+// include('Net/Socket.php');
+ $poppassd = new Net_Socket();
+
+ $result = $poppassd->connect($rcmail->config->get('password_pop_host'), $rcmail->config->get('password_pop_port'), null);
+ if (is_a($result, 'PEAR_Error')) {
+ return $this->format_error_result(PASSWORD_CONNECT_ERROR, $result->getMessage());
+ }
+ else {
+ $result = $poppassd->readLine();
+ if(!preg_match('/^2\d\d/', $result)) {
+ $poppassd->disconnect();
+ return $this->format_error_result(PASSWORD_ERROR, $result);
+ }
+ else {
+ $poppassd->writeLine("user ". $_SESSION['username']);
+ $result = $poppassd->readLine();
+ if (!preg_match('/^[23]\d\d/', $result) ) {
+ $poppassd->disconnect();
+ return $this->format_error_result(PASSWORD_CONNECT_ERROR, $result);
+ }
+ else {
+ $poppassd->writeLine("pass ". $curpass);
+ $result = $poppassd->readLine();
+ if (!preg_match('/^[23]\d\d/', $result) ) {
+ $poppassd->disconnect();
+ return $this->format_error_result(PASSWORD_ERROR, $result);
+ }
+ else {
+ $poppassd->writeLine("newpass ". $passwd);
+ $result = $poppassd->readLine();
+ $poppassd->disconnect();
+ if (!preg_match('/^2\d\d/', $result)) {
+ return $this->format_error_result(PASSWORD_ERROR, $result);
+ }
+
+ return PASSWORD_SUCCESS;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/password/drivers/pw_usermod.php b/plugins/password/drivers/pw_usermod.php
new file mode 100644
index 000000000..c519bf4a4
--- /dev/null
+++ b/plugins/password/drivers/pw_usermod.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * pw_usermod Driver
+ *
+ * Driver that adds functionality to change the systems user password via
+ * the 'pw usermod' command.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 2.0
+ * @author Alex Cartwright <acartwright@mutinydesign.co.uk>
+ * @author Adamson Huang <adomputer@gmail.com>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_pw_usermod_password
+{
+ public function save($currpass, $newpass)
+ {
+ $username = $_SESSION['username'];
+ $cmd = rcmail::get_instance()->config->get('password_pw_usermod_cmd');
+ $cmd .= " $username > /dev/null";
+
+ $handle = popen($cmd, "w");
+ fwrite($handle, "$newpass\n");
+
+ if (pclose($handle) == 0) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $cmd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/sasl.php b/plugins/password/drivers/sasl.php
new file mode 100644
index 000000000..f3baef557
--- /dev/null
+++ b/plugins/password/drivers/sasl.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * SASL Password Driver
+ *
+ * Driver that adds functionality to change the users Cyrus/SASL password.
+ * The code is derrived from the Squirrelmail "Change SASL Password" Plugin
+ * by Galen Johnson.
+ *
+ * It only works with saslpasswd2 on the same host where Roundcube runs
+ * and requires shell access and gcc in order to compile the binary.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 2.0
+ * @author Thomas Bruederli
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_sasl_password
+{
+ function save($currpass, $newpass)
+ {
+ $curdir = RCUBE_PLUGINS_DIR . 'password/helpers';
+ $username = escapeshellcmd($_SESSION['username']);
+ $args = rcmail::get_instance()->config->get('password_saslpasswd_args', '');
+
+ if ($fh = popen("$curdir/chgsaslpasswd -p $args $username", 'w')) {
+ fwrite($fh, $newpass."\n");
+ $code = pclose($fh);
+
+ if ($code == 0)
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $curdir/chgsaslpasswd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/smb.php b/plugins/password/drivers/smb.php
new file mode 100644
index 000000000..3e34c79a1
--- /dev/null
+++ b/plugins/password/drivers/smb.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * smb Driver
+ *
+ * Driver that adds functionality to change the systems user password via
+ * the 'smbpasswd' command.
+ *
+ * For installation instructions please read the README file.
+ *
+ * @version 2.0
+ * @author Andy Theuninck <gohanman@gmail.com)
+ *
+ * Based on chpasswd roundcubemail password driver by
+ * @author Alex Cartwright <acartwright@mutinydesign.co.uk)
+ * and smbpasswd horde passwd driver by
+ * @author Rene Lund Jensen <Rene@lundjensen.net>
+ *
+ * Configuration settings:
+ * password_smb_host => samba host (default: localhost)
+ * password_smb_cmd => smbpasswd binary (default: /usr/bin/smbpasswd)
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_smb_password
+{
+
+ public function save($currpass, $newpass)
+ {
+ $host = rcmail::get_instance()->config->get('password_smb_host','localhost');
+ $bin = rcmail::get_instance()->config->get('password_smb_cmd','/usr/bin/smbpasswd');
+ $username = $_SESSION['username'];
+
+ $host = rcube_utils::parse_host($host);
+ $tmpfile = tempnam(sys_get_temp_dir(),'smb');
+ $cmd = $bin . ' -r ' . $host . ' -s -U "' . $username . '" > ' . $tmpfile . ' 2>&1';
+ $handle = @popen($cmd, 'w');
+
+ fputs($handle, $currpass."\n");
+ fputs($handle, $newpass."\n");
+ fputs($handle, $newpass."\n");
+ @pclose($handle);
+ $res = file($tmpfile);
+ unlink($tmpfile);
+
+ if (strstr($res[count($res) - 1], 'Password changed for user') !== false) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $cmd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/sql.php b/plugins/password/drivers/sql.php
new file mode 100644
index 000000000..37e162e22
--- /dev/null
+++ b/plugins/password/drivers/sql.php
@@ -0,0 +1,212 @@
+<?php
+
+/**
+ * SQL Password Driver
+ *
+ * Driver for passwords stored in SQL database
+ *
+ * @version 2.0
+ * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_sql_password
+{
+ function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+
+ if (!($sql = $rcmail->config->get('password_query'))) {
+ $sql = 'SELECT update_passwd(%c, %u)';
+ }
+
+ if ($dsn = $rcmail->config->get('password_db_dsn')) {
+ $db = rcube_db::factory($dsn, '', false);
+ $db->set_debug((bool)$rcmail->config->get('sql_debug'));
+ }
+ else {
+ $db = $rcmail->get_dbh();
+ }
+
+ if ($db->is_error()) {
+ return PASSWORD_ERROR;
+ }
+
+ // crypted password
+ if (strpos($sql, '%c') !== FALSE) {
+ $salt = '';
+
+ if (!($crypt_hash = $rcmail->config->get('password_crypt_hash'))) {
+ if (CRYPT_MD5)
+ $crypt_hash = 'md5';
+ else if (CRYPT_STD_DES)
+ $crypt_hash = 'des';
+ }
+
+ switch ($crypt_hash) {
+ case 'md5':
+ $len = 8;
+ $salt_hashindicator = '$1$';
+ break;
+ case 'des':
+ $len = 2;
+ break;
+ case 'blowfish':
+ $cost = (int) $rcmail->config->get('password_blowfish_cost');
+ $cost = $cost < 4 || $cost > 31 ? 12 : $cost;
+ $len = 22;
+ $salt_hashindicator = sprintf('$2a$%02d$', $cost);
+ break;
+ case 'sha256':
+ $len = 16;
+ $salt_hashindicator = '$5$';
+ break;
+ case 'sha512':
+ $len = 16;
+ $salt_hashindicator = '$6$';
+ break;
+ default:
+ return PASSWORD_CRYPT_ERROR;
+ }
+
+ //Restrict the character set used as salt (#1488136)
+ $seedchars = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+ for ($i = 0; $i < $len ; $i++) {
+ $salt .= $seedchars[rand(0, 63)];
+ }
+
+ $sql = str_replace('%c', $db->quote(crypt($passwd, $salt_hashindicator ? $salt_hashindicator .$salt.'$' : $salt)), $sql);
+ }
+
+ // dovecotpw
+ if (strpos($sql, '%D') !== FALSE) {
+ if (!($dovecotpw = $rcmail->config->get('password_dovecotpw')))
+ $dovecotpw = 'dovecotpw';
+ if (!($method = $rcmail->config->get('password_dovecotpw_method')))
+ $method = 'CRAM-MD5';
+
+ // use common temp dir
+ $tmp_dir = $rcmail->config->get('temp_dir');
+ $tmpfile = tempnam($tmp_dir, 'roundcube-');
+
+ $pipe = popen("$dovecotpw -s '$method' > '$tmpfile'", "w");
+ if (!$pipe) {
+ unlink($tmpfile);
+ return PASSWORD_CRYPT_ERROR;
+ }
+ else {
+ fwrite($pipe, $passwd . "\n", 1+strlen($passwd)); usleep(1000);
+ fwrite($pipe, $passwd . "\n", 1+strlen($passwd));
+ pclose($pipe);
+ $newpass = trim(file_get_contents($tmpfile), "\n");
+ if (!preg_match('/^\{' . $method . '\}/', $newpass)) {
+ return PASSWORD_CRYPT_ERROR;
+ }
+ if (!$rcmail->config->get('password_dovecotpw_with_method'))
+ $newpass = trim(str_replace('{' . $method . '}', '', $newpass));
+ unlink($tmpfile);
+ }
+ $sql = str_replace('%D', $db->quote($newpass), $sql);
+ }
+
+ // hashed passwords
+ if (preg_match('/%[n|q]/', $sql)) {
+ if (!extension_loaded('hash')) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: 'hash' extension not loaded!"
+ ), true, false);
+
+ return PASSWORD_ERROR;
+ }
+
+ if (!($hash_algo = strtolower($rcmail->config->get('password_hash_algorithm')))) {
+ $hash_algo = 'sha1';
+ }
+
+ $hash_passwd = hash($hash_algo, $passwd);
+ $hash_curpass = hash($hash_algo, $curpass);
+
+ if ($rcmail->config->get('password_hash_base64')) {
+ $hash_passwd = base64_encode(pack('H*', $hash_passwd));
+ $hash_curpass = base64_encode(pack('H*', $hash_curpass));
+ }
+
+ $sql = str_replace('%n', $db->quote($hash_passwd, 'text'), $sql);
+ $sql = str_replace('%q', $db->quote($hash_curpass, 'text'), $sql);
+ }
+
+ // Handle clear text passwords securely (#1487034)
+ $sql_vars = array();
+ if (preg_match_all('/%[p|o]/', $sql, $m)) {
+ foreach ($m[0] as $var) {
+ if ($var == '%p') {
+ $sql = preg_replace('/%p/', '?', $sql, 1);
+ $sql_vars[] = (string) $passwd;
+ }
+ else { // %o
+ $sql = preg_replace('/%o/', '?', $sql, 1);
+ $sql_vars[] = (string) $curpass;
+ }
+ }
+ }
+
+ $local_part = $rcmail->user->get_username('local');
+ $domain_part = $rcmail->user->get_username('domain');
+ $username = $_SESSION['username'];
+ $host = $_SESSION['imap_host'];
+
+ // convert domains to/from punnycode
+ if ($rcmail->config->get('password_idn_ascii')) {
+ $domain_part = rcube_utils::idn_to_ascii($domain_part);
+ $username = rcube_utils::idn_to_ascii($username);
+ $host = rcube_utils::idn_to_ascii($host);
+ }
+ else {
+ $domain_part = rcube_utils::idn_to_utf8($domain_part);
+ $username = rcube_utils::idn_to_utf8($username);
+ $host = rcube_utils::idn_to_utf8($host);
+ }
+
+ // at least we should always have the local part
+ $sql = str_replace('%l', $db->quote($local_part, 'text'), $sql);
+ $sql = str_replace('%d', $db->quote($domain_part, 'text'), $sql);
+ $sql = str_replace('%u', $db->quote($username, 'text'), $sql);
+ $sql = str_replace('%h', $db->quote($host, 'text'), $sql);
+
+ $res = $db->query($sql, $sql_vars);
+
+ if (!$db->is_error()) {
+ if (strtolower(substr(trim($sql),0,6)) == 'select') {
+ if ($db->fetch_array($res)) {
+ return PASSWORD_SUCCESS;
+ }
+ }
+ else {
+ // This is the good case: 1 row updated
+ if ($db->affected_rows($res) == 1)
+ return PASSWORD_SUCCESS;
+ // @TODO: Some queries don't affect any rows
+ // Should we assume a success if there was no error?
+ }
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/virtualmin.php b/plugins/password/drivers/virtualmin.php
new file mode 100644
index 000000000..3001ad9d0
--- /dev/null
+++ b/plugins/password/drivers/virtualmin.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * Virtualmin Password Driver
+ *
+ * Driver that adds functionality to change the users Virtualmin password.
+ * The code is derrived from the Squirrelmail "Change Cyrus/SASL Password" Plugin
+ * by Thomas Bruederli.
+ *
+ * It only works with virtualmin on the same host where Roundcube runs
+ * and requires shell access and gcc in order to compile the binary.
+ *
+ * @version 3.0
+ * @author Martijn de Munnik
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_virtualmin_password
+{
+ function save($currpass, $newpass)
+ {
+ $rcmail = rcmail::get_instance();
+ $format = $rcmail->config->get('password_virtualmin_format', 0);
+ $username = $_SESSION['username'];
+
+ switch ($format) {
+ case 1: // username%domain
+ $domain = substr(strrchr($username, "%"), 1);
+ break;
+ case 2: // username.domain (could be bogus)
+ $pieces = explode(".", $username);
+ $domain = $pieces[count($pieces)-2]. "." . end($pieces);
+ break;
+ case 3: // domain.username (could be bogus)
+ $pieces = explode(".", $username);
+ $domain = $pieces[0]. "." . $pieces[1];
+ break;
+ case 4: // username-domain
+ $domain = substr(strrchr($username, "-"), 1);
+ break;
+ case 5: // domain-username
+ $domain = str_replace(strrchr($username, "-"), "", $username);
+ break;
+ case 6: // username_domain
+ $domain = substr(strrchr($username, "_"), 1);
+ break;
+ case 7: // domain_username
+ $pieces = explode("_", $username);
+ $domain = $pieces[0];
+ break;
+ default: // username@domain
+ $domain = substr(strrchr($username, "@"), 1);
+ }
+
+ if (!$domain) {
+ $domain = $rcmail->user->get_username('domain');
+ }
+
+ $username = escapeshellcmd($username);
+ $domain = escapeshellcmd($domain);
+ $newpass = escapeshellcmd($newpass);
+ $curdir = RCUBE_PLUGINS_DIR . 'password/helpers';
+
+ exec("$curdir/chgvirtualminpasswd modify-user --domain $domain --user $username --pass $newpass", $output, $returnvalue);
+
+ if ($returnvalue == 0) {
+ return PASSWORD_SUCCESS;
+ }
+ else {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to execute $curdir/chgvirtualminpasswd"
+ ), true, false);
+ }
+
+ return PASSWORD_ERROR;
+ }
+}
diff --git a/plugins/password/drivers/vpopmaild.php b/plugins/password/drivers/vpopmaild.php
new file mode 100644
index 000000000..bc0c8f9da
--- /dev/null
+++ b/plugins/password/drivers/vpopmaild.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * vpopmail Password Driver
+ *
+ * Driver to change passwords via vpopmaild
+ *
+ * @version 2.0
+ * @author Johannes Hessellund
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_vpopmaild_password
+{
+ function save($curpass, $passwd)
+ {
+ $rcmail = rcmail::get_instance();
+ $vpopmaild = new Net_Socket();
+ $host = $rcmail->config->get('password_vpopmaild_host');
+ $port = $rcmail->config->get('password_vpopmaild_port');
+
+ $result = $vpopmaild->connect($host, $port, null);
+ if (is_a($result, 'PEAR_Error')) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ $vpopmaild->setTimeout($rcmail->config->get('password_vpopmaild_timeout'),0);
+
+ $result = $vpopmaild->readLine();
+ if(!preg_match('/^\+OK/', $result)) {
+ $vpopmaild->disconnect();
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ $vpopmaild->writeLine("slogin ". $_SESSION['username'] . " " . $curpass);
+ $result = $vpopmaild->readLine();
+
+ if(!preg_match('/^\+OK/', $result) ) {
+ $vpopmaild->writeLine("quit");
+ $vpopmaild->disconnect();
+ return PASSWORD_ERROR;
+ }
+
+ $vpopmaild->writeLine("mod_user ". $_SESSION['username']);
+ $vpopmaild->writeLine("clear_text_password ". $passwd);
+ $vpopmaild->writeLine(".");
+ $result = $vpopmaild->readLine();
+ $vpopmaild->writeLine("quit");
+ $vpopmaild->disconnect();
+
+ if (!preg_match('/^\+OK/', $result)) {
+ return PASSWORD_ERROR;
+ }
+
+ return PASSWORD_SUCCESS;
+ }
+}
diff --git a/plugins/password/drivers/ximss.php b/plugins/password/drivers/ximss.php
new file mode 100644
index 000000000..54477f730
--- /dev/null
+++ b/plugins/password/drivers/ximss.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Communigate driver for the Password Plugin for Roundcube
+ *
+ * Tested with Communigate Pro 5.1.2
+ *
+ * Configuration options:
+ * password_ximss_host - Host name of Communigate server
+ * password_ximss_port - XIMSS port on Communigate server
+ *
+ * References:
+ * http://www.communigate.com/WebGuide/XMLAPI.html
+ *
+ * @version 2.0
+ * @author Erik Meitner <erik wanderings.us>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_ximss_password
+{
+ function save($pass, $newpass)
+ {
+ $rcmail = rcmail::get_instance();
+
+ $host = $rcmail->config->get('password_ximss_host');
+ $port = $rcmail->config->get('password_ximss_port');
+ $sock = stream_socket_client("tcp://$host:$port", $errno, $errstr, 30);
+
+ if ($sock === FALSE) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+
+ // send all requests at once(pipelined)
+ fwrite( $sock, '<login id="A001" authData="'.$_SESSION['username'].'" password="'.$pass.'" />'."\0");
+ fwrite( $sock, '<passwordModify id="A002" oldPassword="'.$pass.'" newPassword="'.$newpass.'" />'."\0");
+ fwrite( $sock, '<bye id="A003" />'."\0");
+
+ //example responses
+ // <session id="A001" urlID="4815-vN2Txjkggy7gjHRD10jw" userName="user@example.com"/>\0
+ // <response id="A001"/>\0
+ // <response id="A002"/>\0
+ // <response id="A003"/>\0
+ // or an error:
+ // <response id="A001" errorText="incorrect password or account name" errorNum="515"/>\0
+
+ $responseblob = '';
+ while (!feof($sock)) {
+ $responseblob .= fgets($sock, 1024);
+ }
+
+ fclose($sock);
+
+ foreach( explode( "\0",$responseblob) as $response ) {
+ $resp = simplexml_load_string("<xml>".$response."</xml>");
+
+ if( $resp->response[0]['id'] == 'A001' ) {
+ if( isset( $resp->response[0]['errorNum'] ) ) {
+ return PASSWORD_CONNECT_ERROR;
+ }
+ }
+ else if( $resp->response[0]['id'] == 'A002' ) {
+ if( isset( $resp->response[0]['errorNum'] )) {
+ return PASSWORD_ERROR;
+ }
+ }
+ else if( $resp->response[0]['id'] == 'A003' ) {
+ if( isset($resp->response[0]['errorNum'] )) {
+ //There was a problem during logout(This is probably harmless)
+ }
+ }
+ } //foreach
+
+ return PASSWORD_SUCCESS;
+ }
+}
diff --git a/plugins/password/drivers/xmail.php b/plugins/password/drivers/xmail.php
new file mode 100644
index 000000000..a7d00a279
--- /dev/null
+++ b/plugins/password/drivers/xmail.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * XMail Password Driver
+ *
+ * Driver for XMail password
+ *
+ * @version 2.0
+ * @author Helio Cavichiolo Jr <helio@hcsistemas.com.br>
+ *
+ * Setup xmail_host, xmail_user, xmail_pass and xmail_port into
+ * config.inc.php of password plugin as follows:
+ *
+ * $config['xmail_host'] = 'localhost';
+ * $config['xmail_user'] = 'YourXmailControlUser';
+ * $config['xmail_pass'] = 'YourXmailControlPass';
+ * $config['xmail_port'] = 6017;
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_xmail_password
+{
+ function save($currpass, $newpass)
+ {
+ $rcmail = rcmail::get_instance();
+ list($user,$domain) = explode('@', $_SESSION['username']);
+
+ $xmail = new XMail;
+
+ $xmail->hostname = $rcmail->config->get('xmail_host');
+ $xmail->username = $rcmail->config->get('xmail_user');
+ $xmail->password = $rcmail->config->get('xmail_pass');
+ $xmail->port = $rcmail->config->get('xmail_port');
+
+ if (!$xmail->connect()) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to connect to mail server"
+ ), true, false);
+ return PASSWORD_CONNECT_ERROR;
+ }
+ else if (!$xmail->send("userpasswd\t".$domain."\t".$user."\t".$newpass."\n")) {
+ $xmail->close();
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to change password"
+ ), true, false);
+ return PASSWORD_ERROR;
+ }
+ else {
+ $xmail->close();
+ return PASSWORD_SUCCESS;
+ }
+ }
+}
+
+class XMail {
+ var $socket;
+ var $hostname = 'localhost';
+ var $username = 'xmail';
+ var $password = '';
+ var $port = 6017;
+
+ function send($msg)
+ {
+ socket_write($this->socket,$msg);
+ if (substr(socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") {
+ return false;
+ }
+ return true;
+ }
+
+ function connect()
+ {
+ $this->socket = socket_create(AF_INET, SOCK_STREAM, 0);
+ if ($this->socket < 0)
+ return false;
+
+ $result = socket_connect($this->socket, $this->hostname, $this->port);
+ if ($result < 0) {
+ socket_close($this->socket);
+ return false;
+ }
+
+ if (substr(socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") {
+ socket_close($this->socket);
+ return false;
+ }
+
+ if (!$this->send("$this->username\t$this->password\n")) {
+ socket_close($this->socket);
+ return false;
+ }
+ return true;
+ }
+
+ function close()
+ {
+ $this->send("quit\n");
+ socket_close($this->socket);
+ }
+}
diff --git a/plugins/password/helpers/chgdbmailusers.c b/plugins/password/helpers/chgdbmailusers.c
new file mode 100644
index 000000000..be237556e
--- /dev/null
+++ b/plugins/password/helpers/chgdbmailusers.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+// set the UID this script will run as (root user)
+#define UID 0
+#define CMD "/usr/sbin/dbmail-users"
+
+/* INSTALLING:
+ gcc -o chgdbmailusers chgdbmailusers.c
+ chown root.apache chgdbmailusers
+ strip chgdbmailusers
+ chmod 4550 chgdbmailusers
+*/
+
+main(int argc, char *argv[])
+{
+ int cnt,rc,cc;
+ char cmnd[1024];
+
+ strcpy(cmnd, CMD);
+
+ if (argc > 1)
+ {
+ for (cnt = 1; cnt < argc; cnt++)
+ {
+ strcat(cmnd, " ");
+ strcat(cmnd, argv[cnt]);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "__ %s: failed %d %d\n", argv[0], rc, cc);
+ return 255;
+ }
+
+ cc = setuid(UID);
+ rc = system(cmnd);
+
+ if ((rc != 0) || (cc != 0))
+ {
+ fprintf(stderr, "__ %s: failed %d %d\n", argv[0], rc, cc);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/plugins/password/helpers/chgsaslpasswd.c b/plugins/password/helpers/chgsaslpasswd.c
new file mode 100644
index 000000000..bcdcb2e0d
--- /dev/null
+++ b/plugins/password/helpers/chgsaslpasswd.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <unistd.h>
+
+// set the UID this script will run as (cyrus user)
+#define UID 96
+// set the path to saslpasswd or saslpasswd2
+#define CMD "/usr/sbin/saslpasswd2"
+
+/* INSTALLING:
+ gcc -o chgsaslpasswd chgsaslpasswd.c
+ chown cyrus.apache chgsaslpasswd
+ strip chgsaslpasswd
+ chmod 4550 chgsaslpasswd
+*/
+
+main(int argc, char *argv[])
+{
+ int rc,cc;
+
+ cc = setuid(UID);
+ rc = execvp(CMD, argv);
+ if ((rc != 0) || (cc != 0))
+ {
+ fprintf(stderr, "__ %s: failed %d %d\n", argv[0], rc, cc);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/plugins/password/helpers/chgvirtualminpasswd.c b/plugins/password/helpers/chgvirtualminpasswd.c
new file mode 100644
index 000000000..4e2299c66
--- /dev/null
+++ b/plugins/password/helpers/chgvirtualminpasswd.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <unistd.h>
+
+// set the UID this script will run as (root user)
+#define UID 0
+#define CMD "/usr/sbin/virtualmin"
+
+/* INSTALLING:
+ gcc -o chgvirtualminpasswd chgvirtualminpasswd.c
+ chown root.apache chgvirtualminpasswd
+ strip chgvirtualminpasswd
+ chmod 4550 chgvirtualminpasswd
+*/
+
+main(int argc, char *argv[])
+{
+ int rc,cc;
+
+ cc = setuid(UID);
+ rc = execvp(CMD, argv);
+ if ((rc != 0) || (cc != 0))
+ {
+ fprintf(stderr, "__ %s: failed %d %d\n", argv[0], rc, cc);
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/plugins/password/helpers/chpass-wrapper.py b/plugins/password/helpers/chpass-wrapper.py
new file mode 100644
index 000000000..61bba849e
--- /dev/null
+++ b/plugins/password/helpers/chpass-wrapper.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+import sys
+import pwd
+import subprocess
+
+BLACKLIST = (
+ # add blacklisted users here
+ #'user1',
+)
+
+try:
+ username, password = sys.stdin.readline().split(':', 1)
+except ValueError, e:
+ sys.exit('Malformed input')
+
+try:
+ user = pwd.getpwnam(username)
+except KeyError, e:
+ sys.exit('No such user: %s' % username)
+
+if user.pw_uid < 1000:
+ sys.exit('Changing the password for user id < 1000 is forbidden')
+
+if username in BLACKLIST:
+ sys.exit('Changing password for user %s is forbidden (user blacklisted)' %
+ username)
+
+handle = subprocess.Popen('/usr/sbin/chpasswd', stdin = subprocess.PIPE)
+handle.communicate('%s:%s' % (username, password))
+
+sys.exit(handle.returncode)
diff --git a/plugins/password/helpers/dovecot_hmacmd5.php b/plugins/password/helpers/dovecot_hmacmd5.php
new file mode 100644
index 000000000..644b5377e
--- /dev/null
+++ b/plugins/password/helpers/dovecot_hmacmd5.php
@@ -0,0 +1,191 @@
+<?php
+
+/**
+ *
+ * dovecot_hmacmd5.php V1.01
+ *
+ * Generates HMAC-MD5 'contexts' for Dovecot's password files.
+ *
+ * (C) 2008 Hajo Noerenberg
+ *
+ * http://www.noerenberg.de/hajo/pub/dovecot_hmacmd5.php.txt
+ *
+ * Most of the code has been shamelessly stolen from various sources:
+ *
+ * (C) Paul Johnston 1999 - 2000 / http://pajhome.org.uk/crypt/md5/
+ * (C) William K. Cole 2008 / http://www.scconsult.com/bill/crampass.pl
+ * (C) Borfast 2002 / http://www.zend.com/code/codex.php?ozid=962&single=1
+ * (C) Thomas Weber / http://pajhome.org.uk/crypt/md5/contrib/md5.java.txt
+ *
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.0 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.txt>.
+ *
+ */
+
+/* Convert a 32-bit number to a hex string with ls-byte first
+ */
+
+function rhex($n) {
+ $hex_chr = "0123456789abcdef"; $r = '';
+ for($j = 0; $j <= 3; $j++)
+ $r .= $hex_chr[($n >> ($j * 8 + 4)) & 0x0F] . $hex_chr[($n >> ($j * 8)) & 0x0F];
+ return $r;
+}
+
+/* zeroFill() is needed because PHP doesn't have a zero-fill
+ * right shift operator like JavaScript's >>>
+ */
+
+function zeroFill($a, $b) {
+ $z = hexdec(80000000);
+ if ($z & $a) {
+ $a >>= 1;
+ $a &= (~$z);
+ $a |= 0x40000000;
+ $a >>= ($b-1);
+ } else {
+ $a >>= $b;
+ }
+ return $a;
+}
+
+/* Bitwise rotate a 32-bit number to the left
+ */
+
+function bit_rol($num, $cnt) {
+ return ($num << $cnt) | (zeroFill($num, (32 - $cnt)));
+}
+
+/* Add integers, wrapping at 2^32
+ */
+
+function safe_add($x, $y) {
+ return (($x&0x7FFFFFFF) + ($y&0x7FFFFFFF)) ^ ($x&0x80000000) ^ ($y&0x80000000);
+}
+
+/* These functions implement the four basic operations the algorithm uses.
+ */
+
+function md5_cmn($q, $a, $b, $x, $s, $t) {
+ return safe_add(bit_rol(safe_add(safe_add($a, $q), safe_add($x, $t)), $s), $b);
+}
+function md5_ff($a, $b, $c, $d, $x, $s, $t) {
+ return md5_cmn(($b & $c) | ((~$b) & $d), $a, $b, $x, $s, $t);
+}
+function md5_gg($a, $b, $c, $d, $x, $s, $t) {
+ return md5_cmn(($b & $d) | ($c & (~$d)), $a, $b, $x, $s, $t);
+}
+function md5_hh($a, $b, $c, $d, $x, $s, $t) {
+ return md5_cmn($b ^ $c ^ $d, $a, $b, $x, $s, $t);
+}
+function md5_ii($a, $b, $c, $d, $x, $s, $t) {
+ return md5_cmn($c ^ ($b | (~$d)), $a, $b, $x, $s, $t);
+}
+
+/* Calculate the first round of the MD5 algorithm
+ */
+
+function md5_oneround($s, $io) {
+
+ $s = str_pad($s, 64, chr(0x00));
+
+ $x = array_fill(0, 16, 0);
+
+ for($i = 0; $i < 64; $i++)
+ $x[$i >> 2] |= (($io ? 0x36 : 0x5c) ^ ord($s[$i])) << (($i % 4) * 8);
+
+ $a = $olda = 1732584193;
+ $b = $oldb = -271733879;
+ $c = $oldc = -1732584194;
+ $d = $oldd = 271733878;
+
+ $a = md5_ff($a, $b, $c, $d, $x[ 0], 7 , -680876936);
+ $d = md5_ff($d, $a, $b, $c, $x[ 1], 12, -389564586);
+ $c = md5_ff($c, $d, $a, $b, $x[ 2], 17, 606105819);
+ $b = md5_ff($b, $c, $d, $a, $x[ 3], 22, -1044525330);
+ $a = md5_ff($a, $b, $c, $d, $x[ 4], 7 , -176418897);
+ $d = md5_ff($d, $a, $b, $c, $x[ 5], 12, 1200080426);
+ $c = md5_ff($c, $d, $a, $b, $x[ 6], 17, -1473231341);
+ $b = md5_ff($b, $c, $d, $a, $x[ 7], 22, -45705983);
+ $a = md5_ff($a, $b, $c, $d, $x[ 8], 7 , 1770035416);
+ $d = md5_ff($d, $a, $b, $c, $x[ 9], 12, -1958414417);
+ $c = md5_ff($c, $d, $a, $b, $x[10], 17, -42063);
+ $b = md5_ff($b, $c, $d, $a, $x[11], 22, -1990404162);
+ $a = md5_ff($a, $b, $c, $d, $x[12], 7 , 1804603682);
+ $d = md5_ff($d, $a, $b, $c, $x[13], 12, -40341101);
+ $c = md5_ff($c, $d, $a, $b, $x[14], 17, -1502002290);
+ $b = md5_ff($b, $c, $d, $a, $x[15], 22, 1236535329);
+
+ $a = md5_gg($a, $b, $c, $d, $x[ 1], 5 , -165796510);
+ $d = md5_gg($d, $a, $b, $c, $x[ 6], 9 , -1069501632);
+ $c = md5_gg($c, $d, $a, $b, $x[11], 14, 643717713);
+ $b = md5_gg($b, $c, $d, $a, $x[ 0], 20, -373897302);
+ $a = md5_gg($a, $b, $c, $d, $x[ 5], 5 , -701558691);
+ $d = md5_gg($d, $a, $b, $c, $x[10], 9 , 38016083);
+ $c = md5_gg($c, $d, $a, $b, $x[15], 14, -660478335);
+ $b = md5_gg($b, $c, $d, $a, $x[ 4], 20, -405537848);
+ $a = md5_gg($a, $b, $c, $d, $x[ 9], 5 , 568446438);
+ $d = md5_gg($d, $a, $b, $c, $x[14], 9 , -1019803690);
+ $c = md5_gg($c, $d, $a, $b, $x[ 3], 14, -187363961);
+ $b = md5_gg($b, $c, $d, $a, $x[ 8], 20, 1163531501);
+ $a = md5_gg($a, $b, $c, $d, $x[13], 5 , -1444681467);
+ $d = md5_gg($d, $a, $b, $c, $x[ 2], 9 , -51403784);
+ $c = md5_gg($c, $d, $a, $b, $x[ 7], 14, 1735328473);
+ $b = md5_gg($b, $c, $d, $a, $x[12], 20, -1926607734);
+
+ $a = md5_hh($a, $b, $c, $d, $x[ 5], 4 , -378558);
+ $d = md5_hh($d, $a, $b, $c, $x[ 8], 11, -2022574463);
+ $c = md5_hh($c, $d, $a, $b, $x[11], 16, 1839030562);
+ $b = md5_hh($b, $c, $d, $a, $x[14], 23, -35309556);
+ $a = md5_hh($a, $b, $c, $d, $x[ 1], 4 , -1530992060);
+ $d = md5_hh($d, $a, $b, $c, $x[ 4], 11, 1272893353);
+ $c = md5_hh($c, $d, $a, $b, $x[ 7], 16, -155497632);
+ $b = md5_hh($b, $c, $d, $a, $x[10], 23, -1094730640);
+ $a = md5_hh($a, $b, $c, $d, $x[13], 4 , 681279174);
+ $d = md5_hh($d, $a, $b, $c, $x[ 0], 11, -358537222);
+ $c = md5_hh($c, $d, $a, $b, $x[ 3], 16, -722521979);
+ $b = md5_hh($b, $c, $d, $a, $x[ 6], 23, 76029189);
+ $a = md5_hh($a, $b, $c, $d, $x[ 9], 4 , -640364487);
+ $d = md5_hh($d, $a, $b, $c, $x[12], 11, -421815835);
+ $c = md5_hh($c, $d, $a, $b, $x[15], 16, 530742520);
+ $b = md5_hh($b, $c, $d, $a, $x[ 2], 23, -995338651);
+
+ $a = md5_ii($a, $b, $c, $d, $x[ 0], 6 , -198630844);
+ $d = md5_ii($d, $a, $b, $c, $x[ 7], 10, 1126891415);
+ $c = md5_ii($c, $d, $a, $b, $x[14], 15, -1416354905);
+ $b = md5_ii($b, $c, $d, $a, $x[ 5], 21, -57434055);
+ $a = md5_ii($a, $b, $c, $d, $x[12], 6 , 1700485571);
+ $d = md5_ii($d, $a, $b, $c, $x[ 3], 10, -1894986606);
+ $c = md5_ii($c, $d, $a, $b, $x[10], 15, -1051523);
+ $b = md5_ii($b, $c, $d, $a, $x[ 1], 21, -2054922799);
+ $a = md5_ii($a, $b, $c, $d, $x[ 8], 6 , 1873313359);
+ $d = md5_ii($d, $a, $b, $c, $x[15], 10, -30611744);
+ $c = md5_ii($c, $d, $a, $b, $x[ 6], 15, -1560198380);
+ $b = md5_ii($b, $c, $d, $a, $x[13], 21, 1309151649);
+ $a = md5_ii($a, $b, $c, $d, $x[ 4], 6 , -145523070);
+ $d = md5_ii($d, $a, $b, $c, $x[11], 10, -1120210379);
+ $c = md5_ii($c, $d, $a, $b, $x[ 2], 15, 718787259);
+ $b = md5_ii($b, $c, $d, $a, $x[ 9], 21, -343485551);
+
+ $a = safe_add($a, $olda);
+ $b = safe_add($b, $oldb);
+ $c = safe_add($c, $oldc);
+ $d = safe_add($d, $oldd);
+
+ return rhex($a) . rhex($b) . rhex($c) . rhex($d);
+}
+
+function dovecot_hmacmd5 ($s) {
+ if (strlen($s) > 64) $s=pack("H*", md5($s));
+ return "{CRAM-MD5}" . md5_oneround($s, 0) . md5_oneround($s, 1);
+}
diff --git a/plugins/password/helpers/passwd-expect b/plugins/password/helpers/passwd-expect
new file mode 100644
index 000000000..7db21ad1f
--- /dev/null
+++ b/plugins/password/helpers/passwd-expect
@@ -0,0 +1,267 @@
+#
+# This scripts changes a password on the local system or a remote host.
+# Connections to the remote (this can also be localhost) are made by ssh, rsh,
+# telnet or rlogin.
+
+# @author Gaudenz Steinlin <gaudenz@soziologie.ch>
+
+# For sudo support alter sudoers (using visudo) so that it contains the
+# following information (replace 'apache' if your webserver runs under another
+# user):
+# -----
+# # Needed for Horde's passwd module
+# Runas_Alias REGULARUSERS = ALL, !root
+# apache ALL=(REGULARUSERS) NOPASSWD:/usr/bin/passwd
+# -----
+
+# @stdin The username, oldpassword, newpassword (in this order)
+# will be taken from stdin
+# @param -prompt regexp for the shell prompt
+# @param -password regexp password prompt
+# @param -oldpassword regexp for the old password
+# @param -newpassword regexp for the new password
+# @param -verify regexp for verifying the password
+# @param -success regexp for success changing the password
+# @param -login regexp for the telnet prompt for the loginname
+# @param -host hostname to be connected
+# @param -timeout timeout for each step
+# @param -log file for writing error messages
+# @param -output file for loging the output
+# @param -telnet use telnet
+# @param -ssh use ssh (default)
+# @param -rlogin use rlogin
+# @param -slogin use slogin
+# @param -sudo use sudo
+# @param -program command for changing passwords
+#
+# @return 0 on success, 1 on failure
+#
+
+
+# default values
+set host "localhost"
+set login "ssh"
+set program "passwd"
+set prompt_string "(%|\\\$|>)"
+set fingerprint_string "The authenticity of host.* can't be established.*\nRSA key fingerprint is.*\nAre you sure you want to continue connecting.*"
+set password_string "(P|p)assword.*"
+set oldpassword_string "((O|o)ld|login|\\\(current\\\) UNIX) (P|p)assword.*"
+set newpassword_string "(N|n)ew.* (P|p)assword.*"
+set badoldpassword_string "(Authentication token manipulation error).*"
+set badpassword_string "((passwd|BAD PASSWORD).*|(passwd|Bad:).*\r)"
+set verify_string "((R|r)e-*enter.*(P|p)assword|Retype new( UNIX)? password|(V|v)erification|(V|v)erify|(A|a)gain).*"
+set success_string "((P|p)assword.* changed|successfully)"
+set login_string "(((L|l)ogin|(U|u)sername).*)"
+set timeout 20
+set log "/tmp/passwd.out"
+set output false
+set output_file "/tmp/passwd.log"
+
+# read input from stdin
+fconfigure stdin -blocking 1
+
+gets stdin user
+gets stdin password(old)
+gets stdin password(new)
+
+# alternative: read input from command line
+#if {$argc < 3} {
+# send_user "Too few arguments: Usage $argv0 username oldpass newpass"
+# exit 1
+#}
+#set user [lindex $argv 0]
+#set password(old) [lindex $argv 1]
+#set password(new) [lindex $argv 2]
+
+# no output to the user
+log_user 0
+
+# read in other options
+for {set i 0} {$i<$argc} {incr i} {
+ set arg [lindex $argv $i]
+ switch -- $arg "-prompt" {
+ incr i
+ set prompt_string [lindex $argv $i]
+ continue
+ } "-password" {
+ incr i
+ set password_string [lindex $argv $i]
+ continue
+ } "-oldpassword" {
+ incr i
+ set oldpassword_string [lindex $argv $i]
+ continue
+ } "-newpassword" {
+ incr i
+ set newpassword_string [lindex $argv $i]
+ continue
+ } "-verify" {
+ incr i
+ set verify_string [lindex $argv $i]
+ continue
+ } "-success" {
+ incr i
+ set success_string [lindex $argv $i]
+ continue
+ } "-login" {
+ incr i
+ set login_string [lindex $argv $i]
+ continue
+ } "-host" {
+ incr i
+ set host [lindex $argv $i]
+ continue
+ } "-timeout" {
+ incr i
+ set timeout [lindex $argv $i]
+ continue
+ } "-log" {
+ incr i
+ set log [lindex $argv $i]
+ continue
+ } "-output" {
+ incr i
+ set output_file [lindex $argv $i]
+ set output true
+ continue
+ } "-telnet" {
+ set login "telnet"
+ continue
+ } "-ssh" {
+ set login "ssh"
+ continue
+ } "-ssh-exec" {
+ set login "ssh-exec"
+ continue
+ } "-rlogin" {
+ set login "rlogin"
+ continue
+ } "-slogin" {
+ set login "slogin"
+ continue
+ } "-sudo" {
+ set login "sudo"
+ continue
+ } "-program" {
+ incr i
+ set program [lindex $argv $i]
+ continue
+ }
+}
+
+# log session
+if {$output} {
+ log_file $output_file
+}
+
+set err [open $log "w" "0600"]
+
+# start remote session
+if {[string match $login "rlogin"]} {
+ set pid [spawn rlogin $host -l $user]
+} elseif {[string match $login "slogin"]} {
+ set pid [spawn slogin $host -l $user]
+} elseif {[string match $login "ssh"]} {
+ set pid [spawn ssh $host -l $user]
+} elseif {[string match $login "ssh-exec"]} {
+ set pid [spawn ssh $host -l $user $program]
+} elseif {[string match $login "sudo"]} {
+ set pid [spawn sudo -u $user $program]
+} elseif {[string match $login "telnet"]} {
+ set pid [spawn telnet $host]
+ expect -re $login_string {
+ sleep .5
+ send "$user\r"
+ }
+} else {
+ puts $err "Invalid login mode. Valid modes: rlogin, slogin, ssh, telnet, sudo\n"
+ close $err
+ exit 1
+}
+
+set old_password_notentered true
+
+if {![string match $login "sudo"]} {
+ # log in
+ expect {
+ -re $fingerprint_string {sleep .5
+ send yes\r
+ exp_continue}
+ -re $password_string {sleep .5
+ send $password(old)\r}
+ timeout {puts $err "Could not login to system (no password prompt)\n"
+ close $err
+ exit 1}
+ }
+
+ # start password changing program
+ expect {
+ -re $prompt_string {sleep .5
+ send $program\r}
+ # The following is for when passwd is the login shell or ssh-exec is used
+ -re $oldpassword_string {sleep .5
+ send $password(old)\r
+ set old_password_notentered false}
+ timeout {puts $err "Could not login to system (bad old password?)\n"
+ close $err
+ exit 1}
+ }
+}
+
+# send old password
+if {$old_password_notentered} {
+ expect {
+ -re $oldpassword_string {sleep .5
+ send $password(old)\r}
+ timeout {puts $err "Could not start passwd program (no old password prompt)\n"
+ close $err
+ exit 1}
+ }
+}
+
+# send new password
+expect {
+ -re $newpassword_string {sleep .5
+ send $password(new)\r}
+ -re $badoldpassword_string {puts $err "Old password is incorrect\n"
+ close $err
+ exit 1}
+ timeout {puts "Could not change password (bad old password?)\n"
+ close $err
+ exit 1}
+}
+
+# send new password again
+expect {
+ -re $badpassword_string {puts $err "$expect_out(0,string)"
+ close $err
+ send \003
+ sleep .5
+ exit 1}
+ -re $verify_string {sleep .5
+ send $password(new)\r}
+ timeout {puts $err "New password not valid (too short, bad password, too similar, ...)\n"
+ close $err
+ send \003
+ sleep .5
+ exit 1}
+}
+
+# check response
+expect {
+ -re $success_string {sleep .5
+ send exit\r}
+ -re $badpassword_string {puts $err "$expect_out(0,string)"
+ close $err
+ exit 1}
+ timeout {puts $err "Could not change password.\n"
+ close $err
+ exit 1}
+}
+
+# exit succsessfully
+expect {
+ eof {close $err
+ exit 0}
+}
+close $err
diff --git a/plugins/password/localization/ar.inc b/plugins/password/localization/ar.inc
new file mode 100644
index 000000000..db7c424cd
--- /dev/null
+++ b/plugins/password/localization/ar.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'كلمة المرور الحالية:';
+$labels['newpasswd'] = 'كلمة المرور الجديدة:';
+$labels['confpasswd'] = 'تأكيد كلمة المرور الجديدة:';
+$messages['nopassword'] = 'من فضلك أدخل كلمة المرور الجديدة.';
+$messages['nocurpassword'] = 'من فضلك أدخل كلمة المرور الحالية.';
+$messages['passwordincorrect'] = 'كلمة المرور الحالية غير صحيحة.';
+$messages['passwordinconsistency'] = 'كلمة المرور غير مطابقة حاول مجددا';
+$messages['crypterror'] = 'تعذر حفظ كلمة المرور الجديدة. وظيفة التشفير مفقودة.';
+$messages['connecterror'] = 'تعذر حفظ كلمة المرور الجديدة. خطأ بالإتصال.';
+$messages['internalerror'] = 'تعذر حفظ كلمة المرور الجديدة.';
+$messages['passwordshort'] = 'كلمة المرور يجب على الأقل $length أحرف';
+$messages['passwordweak'] = ' كلمة المرور يجب أن تتضمن رقم واحد على الأقل وحرف ترقيم واحد.';
+$messages['passwordforbidden'] = 'كلمة المرور تحتوى على أحرف ممنوعة';
+?>
diff --git a/plugins/password/localization/ar_SA.inc b/plugins/password/localization/ar_SA.inc
new file mode 100644
index 000000000..d91b52333
--- /dev/null
+++ b/plugins/password/localization/ar_SA.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'كلمة المرور الحالية';
+$labels['newpasswd'] = 'كلمة المرور الجديدة';
+$labels['confpasswd'] = 'تأكيد كلمة المرور الجديدة';
+$messages['nopassword'] = 'من فضلك أدخل كلمة مرور جديدة';
+$messages['nocurpassword'] = 'من فضلك أدخل كلمة المرور الحالية';
+$messages['passwordincorrect'] = 'كلمة المرور الحالية غير صحيحة';
+$messages['passwordinconsistency'] = 'كلمة المرور غير مطابقة, أعد المحاولة';
+$messages['crypterror'] = 'تعذر حفظ كلمة المرور الجديدة. دالة التشفير مفقودة.';
+$messages['connecterror'] = 'تعذر حفظ كلمة المرور الجديدة. خطأ في الإتصال';
+$messages['internalerror'] = 'تعذر حفظ كلمة المرور الجديدة';
+$messages['passwordshort'] = 'كلمة المرور يجب ان تحتوي على الاقل $length احرف.';
+$messages['passwordweak'] = 'كلمة المرور يجب ان تتضمن على الاقل رقم و علامة ترميز.';
+$messages['passwordforbidden'] = 'كلمة المرور تحتوي حروفاً ممنوعة';
+?>
diff --git a/plugins/password/localization/ast.inc b/plugins/password/localization/ast.inc
new file mode 100644
index 000000000..aae336854
--- /dev/null
+++ b/plugins/password/localization/ast.inc
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Contraseña actual:';
+$labels['newpasswd'] = 'Contraseña nueva:';
+$labels['confpasswd'] = 'Confirmar contraseña:';
+$messages['nopassword'] = 'Por favor, introduz una contraseña nueva.';
+$messages['nocurpassword'] = 'Por favor, introduz la contraseña actual.';
+$messages['passwordincorrect'] = 'La contraseña actual ye incorreuta.';
+$messages['passwordinconsistency'] = 'Les contraseñes nun concasen. Por favor, inténtalo otra vegada.';
+$messages['crypterror'] = 'Nun pudo guardase la contraseña nueva. Falta la función de cifráu.';
+$messages['connecterror'] = 'Nun pudo guardase la contraseña nueva. Fallu de conexón.';
+$messages['internalerror'] = 'Nun pudo guardase la contraseña nueva. ';
+$messages['passwordshort'] = 'La contraseña tien de tener polo menos $length caráuteres.';
+$messages['passwordweak'] = 'La contraseña tien de tener polo menos un númberu y un signu de puntuación.';
+$messages['passwordforbidden'] = 'La contraseña contien caráuteres prohibíos.';
+$messages['firstloginchange'] = 'Esti ye\'l to primer aniciu sesión. Por favor, camuda la to contraseña.';
+?>
diff --git a/plugins/password/localization/az_AZ.inc b/plugins/password/localization/az_AZ.inc
new file mode 100644
index 000000000..01bb7a91e
--- /dev/null
+++ b/plugins/password/localization/az_AZ.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Hal-hazırki şifrə:';
+$labels['newpasswd'] = 'Yeni şifrə:';
+$labels['confpasswd'] = 'Yeni şifrə: (təkrar)';
+$messages['nopassword'] = 'Yeni şifrəni daxil edin.';
+$messages['nocurpassword'] = 'Hal-hazırda istifadə etdiyiniz şifrəni daxil edin.';
+$messages['passwordincorrect'] = 'Yalnış şifrə daxil etdiniz.';
+$messages['passwordinconsistency'] = 'Yeni daxil etdiyiniz şifrələr bir-birinə uyğun deyildir.';
+$messages['crypterror'] = 'Yeni şifrənin saxlanılması mümkün olmadı. Şifrələmə metodu tapılmadı.';
+$messages['connecterror'] = 'Yeni şifrənin saxlanılması mümkün olmadı. Qoşulma səhvi.';
+$messages['internalerror'] = 'Yeni şifrənin saxlanılması mümkün olmadı.';
+$messages['passwordshort'] = 'Yeni şifrə $length simvoldan uzun olmalıdır.';
+$messages['passwordweak'] = 'Şifrədə heç olmasa minimum bir rəqəm və simvol olmalıdır.';
+$messages['passwordforbidden'] = 'Şifrədə icazə verilməyən simvollar vardır.';
+?>
diff --git a/plugins/password/localization/be_BE.inc b/plugins/password/localization/be_BE.inc
new file mode 100644
index 000000000..4ac446134
--- /dev/null
+++ b/plugins/password/localization/be_BE.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Змяніць пароль';
+$labels['curpasswd'] = 'Бягучы пароль:';
+$labels['newpasswd'] = 'Новы пароль:';
+$labels['confpasswd'] = 'Паўтарыце новы пароль:';
+$messages['nopassword'] = 'Увядзіце новы пароль.';
+$messages['nocurpassword'] = 'Увядзіце бягучы пароль.';
+$messages['passwordincorrect'] = 'Няслушны бягучы пароль.';
+$messages['passwordinconsistency'] = 'Паролі не супадаюць. Паспрабуйце яшчэ раз.';
+$messages['crypterror'] = 'Не ўдалося захаваць новы пароль. Бракуе функцыі шыфравання.';
+$messages['connecterror'] = 'Не ўдалося захаваць новы пароль. Памылка злучэння.';
+$messages['internalerror'] = 'Не ўдалося захаваць новы пароль.';
+$messages['passwordshort'] = 'Пароль мусіць быць мінімум $length знакаў.';
+$messages['passwordweak'] = 'Пароль мусіць утрымліваць мінімум адну лічбу і адзін знак пунктуацыі.';
+$messages['passwordforbidden'] = 'Пароль утрымлівае забароненыя знакі.';
+$messages['firstloginchange'] = 'Гэта ваш першы ўваход. Трэба змяніць пароль.';
+?>
diff --git a/plugins/password/localization/bg_BG.inc b/plugins/password/localization/bg_BG.inc
new file mode 100644
index 000000000..d543b5548
--- /dev/null
+++ b/plugins/password/localization/bg_BG.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Текуща парола:';
+$labels['newpasswd'] = 'Нова парола:';
+$labels['confpasswd'] = 'Повторно нова парола:';
+$messages['nopassword'] = 'Моля въведете нова парола.';
+$messages['nocurpassword'] = 'Моля въведете текущата парола.';
+$messages['passwordincorrect'] = 'Невалидна текуща парола.';
+$messages['passwordinconsistency'] = 'Паролите не съвпадат, опитайте отново.';
+$messages['crypterror'] = 'Невъзможна промяна на паролата. Липсва PHP функция за криптиране.';
+$messages['connecterror'] = 'Невъзможна промяна на паролата. Грешка при свързване със сървър.';
+$messages['internalerror'] = 'Паролата не може да бъде променена.';
+$messages['passwordshort'] = 'Паролата трябва да е дълга поне $length знака.';
+$messages['passwordweak'] = 'Паролата трябва да включва поне един цифра и поне един знак за пунктуация.';
+$messages['passwordforbidden'] = 'Паролата съдържа непозволени символи.';
+?>
diff --git a/plugins/password/localization/br.inc b/plugins/password/localization/br.inc
new file mode 100644
index 000000000..4e0486277
--- /dev/null
+++ b/plugins/password/localization/br.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Kemmañ ar ger-tremen';
+$labels['curpasswd'] = 'Ger-tremen bremañ :';
+$labels['newpasswd'] = 'Ger-tremen nevez :';
+$labels['confpasswd'] = 'Kadarnaat ar ger-tremen :';
+$messages['nopassword'] = 'Roit ur ger-tremen nevez, mar plij.';
+$messages['nocurpassword'] = 'Roit ar ger-tremen red, mar plij.';
+$messages['passwordincorrect'] = 'Direizh eo ar ger-tremen red.';
+$messages['passwordinconsistency'] = 'Ar gerioù-tremen ne glotont ket an eil gant eben, roit anezhe en-dro.';
+$messages['crypterror'] = 'N\'haller ket enrollañ ar ger-tremen nevez. Arc\'hwel enrinegañ o vank.';
+$messages['connecterror'] = 'N\'haller ket enrollañ ar ger-tremen nevez. Fazi gant ar c\'hennask.';
+$messages['internalerror'] = 'N\'haller ket enrollañ ar ger-tremen nevez.';
+$messages['passwordshort'] = 'Ret eo d\'ar ger-tremen bezañ hiroc\'h eget $length arouezenn.';
+$messages['passwordweak'] = 'En ho ker-tremen e tle bezañ ur sifr hag un arouezenn boentaouiñ da nebeutañ';
+$messages['passwordforbidden'] = 'Arouezennoù difennet zo er ger-tremen.';
+$messages['firstloginchange'] = 'Emaoc\'h o kennaskañ evit ar wezh kentañ. Kemmañ ho ger-tremen mar plij.';
+?>
diff --git a/plugins/password/localization/bs_BA.inc b/plugins/password/localization/bs_BA.inc
new file mode 100644
index 000000000..6ca96aa1b
--- /dev/null
+++ b/plugins/password/localization/bs_BA.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Promijeni šifru';
+$labels['curpasswd'] = 'Trenutna šifra:';
+$labels['newpasswd'] = 'Nova šifra:';
+$labels['confpasswd'] = 'Potvrdite novu šifru:';
+$messages['nopassword'] = 'Molimo vas da upišete novu šifru.';
+$messages['nocurpassword'] = 'Molimo vas da upišete trenutnu šifru.';
+$messages['passwordincorrect'] = 'Trenutna šifra je netačna.';
+$messages['passwordinconsistency'] = 'Šifre se ne podudaraju, molimo vas da pokušate ponovo.';
+$messages['crypterror'] = 'Nije moguće sačuvati šifre. Nedostaje funkcija za enkripciju.';
+$messages['connecterror'] = 'Nije moguće sačuvati šifre. Greška u povezivanju.';
+$messages['internalerror'] = 'Nije moguće sačuvati novu šifru.';
+$messages['passwordshort'] = 'Šifra mora sadržavati barem $length znakova.';
+$messages['passwordweak'] = 'Šifra mora imati barem jedan broj i jedan interpunkcijski znak.';
+$messages['passwordforbidden'] = 'Šifra sadrži nedozvoljene znakove.';
+$messages['firstloginchange'] = 'Ovo je vaša prva prijava. Molimo vas da promijenite vašu šifru.';
+?>
diff --git a/plugins/password/localization/ca_ES.inc b/plugins/password/localization/ca_ES.inc
new file mode 100644
index 000000000..d74a4dc50
--- /dev/null
+++ b/plugins/password/localization/ca_ES.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Canvia la contrasenya';
+$labels['curpasswd'] = 'Contrasenya actual:';
+$labels['newpasswd'] = 'Nova contrasenya:';
+$labels['confpasswd'] = 'Confirmeu la nova contrasenya:';
+$messages['nopassword'] = 'Si us plau, introduïu la nova contrasenya.';
+$messages['nocurpassword'] = 'Si us plau, introduïu la contrasenya actual.';
+$messages['passwordincorrect'] = 'Contrasenya actual incorrecta.';
+$messages['passwordinconsistency'] = 'La contrasenya nova no coincideix, torneu-ho a provar.';
+$messages['crypterror'] = 'No s\'ha pogut desar la nova contrasenya. No existeix la funció d\'encriptació.';
+$messages['connecterror'] = 'No s\'ha pogut desar la nova contrasenya. Error de connexió.';
+$messages['internalerror'] = 'No s\'ha pogut desar la nova contrasenya.';
+$messages['passwordshort'] = 'La nova contrasenya ha de tenir com a mínim $length caràcters.';
+$messages['passwordweak'] = 'La nova contrasenya ha d\'incloure com a mínim un nombre i un caràcter de puntuació.';
+$messages['passwordforbidden'] = 'La contrasenya conté caràcters no permesos.';
+$messages['firstloginchange'] = 'Aquest és el vostre primer accés. Si us plau, canvieu-vos la contrasenya.';
+?>
diff --git a/plugins/password/localization/cs_CZ.inc b/plugins/password/localization/cs_CZ.inc
new file mode 100644
index 000000000..45870a35c
--- /dev/null
+++ b/plugins/password/localization/cs_CZ.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Změna hesla';
+$labels['curpasswd'] = 'Aktuální heslo:';
+$labels['newpasswd'] = 'Nové heslo:';
+$labels['confpasswd'] = 'Nové heslo (pro kontrolu):';
+$messages['nopassword'] = 'Prosím zadejte nové heslo.';
+$messages['nocurpassword'] = 'Prosím zadejte aktuální heslo.';
+$messages['passwordincorrect'] = 'Zadané aktuální heslo není správné.';
+$messages['passwordinconsistency'] = 'Zadaná hesla se neshodují. Prosím zkuste to znovu.';
+$messages['crypterror'] = 'Heslo se nepodařilo uložit. Chybí šifrovací funkce.';
+$messages['connecterror'] = 'Heslo se nepodařilo uložit. Problém s připojením.';
+$messages['internalerror'] = 'Heslo se nepodařilo uložit.';
+$messages['passwordshort'] = 'Heslo musí mít alespoň $length znaků.';
+$messages['passwordweak'] = 'Heslo musí obsahovat alespoň jedno číslo a jedno interpuknční znaménko.';
+$messages['passwordforbidden'] = 'Heslo obsahuje nepovolené znaky.';
+$messages['firstloginchange'] = 'Vaše první přihlášení, změňte si prosím heslo.';
+?>
diff --git a/plugins/password/localization/cy_GB.inc b/plugins/password/localization/cy_GB.inc
new file mode 100644
index 000000000..5cd335fc4
--- /dev/null
+++ b/plugins/password/localization/cy_GB.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Newid cyfrinair';
+$labels['curpasswd'] = 'Cyfrinair Presennol:';
+$labels['newpasswd'] = 'Cyfrinair Newydd:';
+$labels['confpasswd'] = 'Cadarnhau Cyfrinair Newydd:';
+$messages['nopassword'] = 'Rhowch eich cyfrinair newydd.';
+$messages['nocurpassword'] = 'Rhowch eich cyfrinair presennol.';
+$messages['passwordincorrect'] = 'Roedd y cyfrinair presennol yn anghywir.';
+$messages['passwordinconsistency'] = 'Nid yw\'r cyfrineiriau yn cymharu, ceisiwch eto.';
+$messages['crypterror'] = 'Methwyd cadw\'r cyfrinair newydd. Ffwythiant amgodi ar goll.';
+$messages['connecterror'] = 'Methwyd cadw\'r cyfrinair newydd. Gwall cysylltiad.';
+$messages['internalerror'] = 'Methwyd cadw\'r cyfrinair newydd.';
+$messages['passwordshort'] = 'Rhaid i\'r cyfrinair fod o leia $length llythyren o hyd.';
+$messages['passwordweak'] = 'Rhaid i\'r cyfrinair gynnwys o leia un rhif a un cymeriad atalnodi.';
+$messages['passwordforbidden'] = 'Mae\'r cyfrinair yn cynnwys llythrennau wedi gwahardd.';
+$messages['firstloginchange'] = 'Dyma eich mewngofnodiad cynta. Newidiwch eich cyfrinair.';
+?>
diff --git a/plugins/password/localization/da_DK.inc b/plugins/password/localization/da_DK.inc
new file mode 100644
index 000000000..d88381e29
--- /dev/null
+++ b/plugins/password/localization/da_DK.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Ændre adgangskode ';
+$labels['curpasswd'] = 'Nuværende adgangskode:';
+$labels['newpasswd'] = 'Ny adgangskode:';
+$labels['confpasswd'] = 'Bekræft ny adgangskode:';
+$messages['nopassword'] = 'Indtast venligst en ny adgangskode.';
+$messages['nocurpassword'] = 'Indtast venligst nuværende adgangskode.';
+$messages['passwordincorrect'] = 'Nuværende adgangskode er forkert.';
+$messages['passwordinconsistency'] = 'Adgangskoderne er ikke ens, prøv igen.';
+$messages['crypterror'] = 'Kunne ikke gemme den nye adgangskode. Krypteringsfunktion mangler.';
+$messages['connecterror'] = 'Kunne ikke gemme den nye adgangskode. Fejl ved forbindelsen.';
+$messages['internalerror'] = 'Kunne ikke gemme den nye adgangskode.';
+$messages['passwordshort'] = 'Adgangskoden skal være mindst $length tegn lang.';
+$messages['passwordweak'] = 'Adgangskoden skal indeholde mindst et tal og et tegnsætningstegn (-.,)';
+$messages['passwordforbidden'] = 'Adgangskoden indeholder forbudte tegn.';
+$messages['firstloginchange'] = 'Dette er første gang du logger ind, ændre venligst din adgangskode';
+?>
diff --git a/plugins/password/localization/de_CH.inc b/plugins/password/localization/de_CH.inc
new file mode 100644
index 000000000..68945be34
--- /dev/null
+++ b/plugins/password/localization/de_CH.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Passwort ändern';
+$labels['curpasswd'] = 'Aktuelles Passwort';
+$labels['newpasswd'] = 'Neues Passwort';
+$labels['confpasswd'] = 'Passwort Wiederholung';
+$messages['nopassword'] = 'Bitte geben Sie ein neues Passwort ein';
+$messages['nocurpassword'] = 'Bitte geben Sie Ihr aktuelles Passwort an';
+$messages['passwordincorrect'] = 'Das aktuelle Passwort ist nicht korrekt';
+$messages['passwordinconsistency'] = 'Das neue Passwort und dessen Wiederholung stimmen nicht überein';
+$messages['crypterror'] = 'Neues Passwort nicht gespeichert: Verschlüsselungsfunktion fehlt';
+$messages['connecterror'] = 'Neues Passwort nicht gespeichert: Verbindungsfehler';
+$messages['internalerror'] = 'Neues Passwort nicht gespeichert';
+$messages['passwordshort'] = 'Passwort muss mindestens $length Zeichen lang sein.';
+$messages['passwordweak'] = 'Passwort muss mindestens eine Zahl und ein Sonderzeichen enthalten.';
+$messages['passwordforbidden'] = 'Passwort enthält unzulässige Zeichen.';
+$messages['firstloginchange'] = 'Dies ist Ihre erste Anmeldung. Bitte ändern Sie Ihr Passwort.';
+?>
diff --git a/plugins/password/localization/de_DE.inc b/plugins/password/localization/de_DE.inc
new file mode 100644
index 000000000..d27e305cd
--- /dev/null
+++ b/plugins/password/localization/de_DE.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Passwort ändern';
+$labels['curpasswd'] = 'Aktuelles Kennwort:';
+$labels['newpasswd'] = 'Neues Kennwort:';
+$labels['confpasswd'] = 'Neues Kennwort bestätigen:';
+$messages['nopassword'] = 'Bitte geben Sie ein neues Kennwort ein.';
+$messages['nocurpassword'] = 'Bitte geben Sie ihr aktuelles Kennwort ein.';
+$messages['passwordincorrect'] = 'Das aktuelle Kennwort ist falsch.';
+$messages['passwordinconsistency'] = 'Das neue Passwort und dessen Wiederholung stimmen nicht überein';
+$messages['crypterror'] = 'Neues Passwort nicht gespeichert: Verschlüsselungsfunktion fehlt';
+$messages['connecterror'] = 'Neues Passwort nicht gespeichert: Verbindungsfehler';
+$messages['internalerror'] = 'Neues Passwort nicht gespeichert';
+$messages['passwordshort'] = 'Passwort muss mindestens $length Zeichen lang sein.';
+$messages['passwordweak'] = 'Passwort muss mindestens eine Zahl und ein Sonderzeichen enthalten.';
+$messages['passwordforbidden'] = 'Passwort enthält unzulässige Zeichen.';
+$messages['firstloginchange'] = 'Dies ist Ihr erster Login. Bitte ändern Sie Ihr Passwort.';
+?>
diff --git a/plugins/password/localization/el_GR.inc b/plugins/password/localization/el_GR.inc
new file mode 100644
index 000000000..f3baa916d
--- /dev/null
+++ b/plugins/password/localization/el_GR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Αλλαγή συνθηματικού';
+$labels['curpasswd'] = 'Τρεχων κωδικος προσβασης:';
+$labels['newpasswd'] = 'Νεος κωδικος προσβασης:';
+$labels['confpasswd'] = 'Επιβεβαιωση κωδικου προσβασης:';
+$messages['nopassword'] = 'Εισαγετε εναν νεο κωδικο.';
+$messages['nocurpassword'] = 'Εισαγετε τον τρεχων κωδικο.';
+$messages['passwordincorrect'] = 'Ο τρεχων κωδικος ειναι λαθος.';
+$messages['passwordinconsistency'] = 'Οι κωδικοί πρόσβασης δεν ταιριάζουν, προσπαθήστε ξανά.';
+$messages['crypterror'] = 'Δεν μπορεσε να αποθηκεύθει ο νέος κωδικός πρόσβασης. Η λειτουργία κρυπτογράφησης λείπει.';
+$messages['connecterror'] = 'Δεν μπορεσε να αποθηκεύθει ο νέος κωδικός πρόσβασης. Σφάλμα σύνδεσης.';
+$messages['internalerror'] = 'Δεν μπορεσε να αποθηκεύθει ο νέος κωδικός πρόσβασης. ';
+$messages['passwordshort'] = 'Ο κωδικός πρόσβασης πρέπει να είναι τουλάχιστον $μήκος χαρακτήρων.';
+$messages['passwordweak'] = 'Ο κωδικός πρόσβασης πρέπει να περιλαμβάνει τουλάχιστον έναν αριθμό και ένα σημείο στίξης. ';
+$messages['passwordforbidden'] = 'Ο κωδικός πρόσβασης περιέχει μη επιτρεπτούς χαρακτήρες. ';
+$messages['firstloginchange'] = 'Αυτή είναι η πρώτη σας είσοδος. Παρακαλώ αλλάξτε το συνθηματικό σας.';
+?>
diff --git a/plugins/password/localization/en_CA.inc b/plugins/password/localization/en_CA.inc
new file mode 100644
index 000000000..e67ee7bfe
--- /dev/null
+++ b/plugins/password/localization/en_CA.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Current Password:';
+$labels['newpasswd'] = 'New Password:';
+$labels['confpasswd'] = 'Confirm New Password:';
+$messages['nopassword'] = 'Please input new password.';
+$messages['nocurpassword'] = 'Please input current password.';
+$messages['passwordincorrect'] = 'Current password incorrect.';
+$messages['passwordinconsistency'] = 'Passwords do not match, please try again.';
+$messages['crypterror'] = 'Could not save new password. Encryption function missing.';
+$messages['connecterror'] = 'Could not save new password. Connection error.';
+$messages['internalerror'] = 'Could not save new password.';
+$messages['passwordshort'] = 'Password must be at least $length characters long.';
+$messages['passwordweak'] = 'Password must include at least one number and one punctuation character.';
+$messages['passwordforbidden'] = 'Password contains forbidden characters.';
+?>
diff --git a/plugins/password/localization/en_GB.inc b/plugins/password/localization/en_GB.inc
new file mode 100644
index 000000000..d5387cb91
--- /dev/null
+++ b/plugins/password/localization/en_GB.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Change password';
+$labels['curpasswd'] = 'Current Password:';
+$labels['newpasswd'] = 'New Password:';
+$labels['confpasswd'] = 'Confirm New Password:';
+$messages['nopassword'] = 'Please enter a new password.';
+$messages['nocurpassword'] = 'Please enter the current password.';
+$messages['passwordincorrect'] = 'Current password is incorrect.';
+$messages['passwordinconsistency'] = 'Passwords do not match. Please try again.';
+$messages['crypterror'] = 'New password could not be saved. The encryption function is missing.';
+$messages['connecterror'] = 'New password could not be saved. There is a connection error.';
+$messages['internalerror'] = 'New password could not be saved.';
+$messages['passwordshort'] = 'Password must be at least $length characters long.';
+$messages['passwordweak'] = 'Password must include at least one number and one symbol.';
+$messages['passwordforbidden'] = 'Password contains forbidden characters.';
+$messages['firstloginchange'] = 'This is your first login. Please change your password.';
+?>
diff --git a/plugins/password/localization/en_US.inc b/plugins/password/localization/en_US.inc
new file mode 100644
index 000000000..278a20374
--- /dev/null
+++ b/plugins/password/localization/en_US.inc
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+
+$labels = array();
+$labels['changepasswd'] = 'Change password';
+$labels['curpasswd'] = 'Current Password:';
+$labels['newpasswd'] = 'New Password:';
+$labels['confpasswd'] = 'Confirm New Password:';
+
+$messages = array();
+$messages['nopassword'] = 'Please input new password.';
+$messages['nocurpassword'] = 'Please input current password.';
+$messages['passwordincorrect'] = 'Current password incorrect.';
+$messages['passwordinconsistency'] = 'Passwords do not match, please try again.';
+$messages['crypterror'] = 'Could not save new password. Encryption function missing.';
+$messages['connecterror'] = 'Could not save new password. Connection error.';
+$messages['internalerror'] = 'Could not save new password.';
+$messages['passwordshort'] = 'Password must be at least $length characters long.';
+$messages['passwordweak'] = 'Password must include at least one number and one punctuation character.';
+$messages['passwordforbidden'] = 'Password contains forbidden characters.';
+$messages['firstloginchange'] = 'This is your first login. Please change your password.';
+
+?>
diff --git a/plugins/password/localization/eo.inc b/plugins/password/localization/eo.inc
new file mode 100644
index 000000000..214a68dac
--- /dev/null
+++ b/plugins/password/localization/eo.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Nuna pasvorto:';
+$labels['newpasswd'] = 'Nova pasvorto:';
+$labels['confpasswd'] = 'Konfirmi novan pasvorton:';
+$messages['nopassword'] = 'Bonvole tajpu novan pasvorton.';
+$messages['nocurpassword'] = 'Bonvole tajpu nunan pasvorton.';
+$messages['passwordincorrect'] = 'Nuna pasvorto nekorekta.';
+$messages['passwordinconsistency'] = 'Pasvortoj ne kongruas, bonvole provu denove.';
+$messages['crypterror'] = 'Pasvorto ne konserveblas: funkcio de ĉifrado mankas.';
+$messages['connecterror'] = 'Pasvorto ne konserveblas: eraro de konekto.';
+$messages['internalerror'] = 'Nova pasvorto ne konserveblas.';
+$messages['passwordshort'] = 'Pasvorto longu almenaŭ $length signojn.';
+$messages['passwordweak'] = 'La pasvorto enhavu almenaŭ unu ciferon kaj unu interpunktan signon.';
+$messages['passwordforbidden'] = 'La pasvorto enhavas malpermesitajn signojn.';
+?>
diff --git a/plugins/password/localization/es_419.inc b/plugins/password/localization/es_419.inc
new file mode 100644
index 000000000..4c2a2cd38
--- /dev/null
+++ b/plugins/password/localization/es_419.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Cambiar contraseña';
+$labels['curpasswd'] = 'Contraseña actual: ';
+$labels['newpasswd'] = 'Contraseña nueva:';
+$labels['confpasswd'] = 'Confirmar contraseña nueva:';
+$messages['nopassword'] = 'Por favor, ingresa la nueva contraseña.';
+$messages['nocurpassword'] = 'Por favor, ingresa la contraseña actual.';
+$messages['passwordincorrect'] = 'Contraseña actual incorrecta.';
+$messages['passwordinconsistency'] = 'Las contraseñas no concuerdan, por favor intenta nuevamente.';
+$messages['crypterror'] = 'No se puedo guardar la nueva contraseña. No se encuentra la función de encriptación.';
+$messages['connecterror'] = 'No se puedo guardar la nueva contraseña. Error de conexión.';
+$messages['internalerror'] = 'No se puedo guardar la nueva contraseña.';
+$messages['passwordshort'] = 'La contraseña debe tener al menos $length carácteres.';
+$messages['passwordweak'] = 'La contraseña debe incluir por lo menos un número y un signo de puntuación.';
+$messages['passwordforbidden'] = 'La contraseña contiene carácteres ilegales.';
+$messages['firstloginchange'] = 'Esta es la primera vez que ingresas. Por favor cambia tu contraseña.';
+?>
diff --git a/plugins/password/localization/es_AR.inc b/plugins/password/localization/es_AR.inc
new file mode 100644
index 000000000..ea043625f
--- /dev/null
+++ b/plugins/password/localization/es_AR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Cambiar contraseña';
+$labels['curpasswd'] = 'Contraseña Actual:';
+$labels['newpasswd'] = 'Contraseña Nueva:';
+$labels['confpasswd'] = 'Confirmar Contraseña:';
+$messages['nopassword'] = 'Por favor introduce una nueva contraseña.';
+$messages['nocurpassword'] = 'Por favor introduce la contraseña actual.';
+$messages['passwordincorrect'] = 'Contraseña actual incorrecta.';
+$messages['passwordinconsistency'] = 'Las contraseñas no coinciden, por favor inténtalo de nuevo.';
+$messages['crypterror'] = 'No se pudo guardar la contraseña nueva. Falta la función de cifrado.';
+$messages['connecterror'] = 'No se pudo guardar la contraseña nueva. Error de conexión';
+$messages['internalerror'] = 'No se pudo guardar la contraseña nueva.';
+$messages['passwordshort'] = 'Tu contraseña debe tener una longitud mínima de $length.';
+$messages['passwordweak'] = 'Tu nueva contraseña debe incluir al menos un número y un signo de puntuación.';
+$messages['passwordforbidden'] = 'La contraseña contiene caracteres inválidos.';
+$messages['firstloginchange'] = 'Este es tu primer inicio de sesión. Por favor, cambia tu contraseña.';
+?>
diff --git a/plugins/password/localization/es_ES.inc b/plugins/password/localization/es_ES.inc
new file mode 100644
index 000000000..2e97e6644
--- /dev/null
+++ b/plugins/password/localization/es_ES.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Cambiar contraseña';
+$labels['curpasswd'] = 'Contraseña actual:';
+$labels['newpasswd'] = 'Contraseña nueva:';
+$labels['confpasswd'] = 'Confirmar contraseña:';
+$messages['nopassword'] = 'Por favor, introduzca una contraseña nueva.';
+$messages['nocurpassword'] = 'Por favor, introduzca la contraseña actual.';
+$messages['passwordincorrect'] = 'La contraseña actual es incorrecta.';
+$messages['passwordinconsistency'] = 'Las contraseñas no coinciden. Por favor, inténtelo de nuevo.';
+$messages['crypterror'] = 'No se pudo guardar la contraseña nueva. Falta la función de cifrado.';
+$messages['connecterror'] = 'No se pudo guardar la contraseña nueva. Error de conexión.';
+$messages['internalerror'] = 'No se pudo guardar la contraseña nueva.';
+$messages['passwordshort'] = 'La contraseña debe tener al menos $length caracteres.';
+$messages['passwordweak'] = 'La contraseña debe incluir al menos un número y un signo de puntuación.';
+$messages['passwordforbidden'] = 'La contraseña introducida contiene caracteres no permitidos.';
+$messages['firstloginchange'] = 'Este es su primer inicio de sesión. Por favor, cambie su contraseña.';
+?>
diff --git a/plugins/password/localization/et_EE.inc b/plugins/password/localization/et_EE.inc
new file mode 100644
index 000000000..6c270f8a1
--- /dev/null
+++ b/plugins/password/localization/et_EE.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Muuda parooli';
+$labels['curpasswd'] = 'Vana parool:';
+$labels['newpasswd'] = 'Uus parool:';
+$labels['confpasswd'] = 'Uus parool uuesti:';
+$messages['nopassword'] = 'Palun sisesta uus parool.';
+$messages['nocurpassword'] = 'Palun sisesta vana parool.';
+$messages['passwordincorrect'] = 'Vana parool on vale.';
+$messages['passwordinconsistency'] = 'Paroolid ei kattu, palun proovi uuesti.';
+$messages['crypterror'] = 'Serveris ei ole parooli krüpteerimiseks vajalikku funktsiooni.';
+$messages['connecterror'] = 'Parooli salvestamine nurjus. Ühenduse tõrge.';
+$messages['internalerror'] = 'Uue parooli andmebaasi salvestamine nurjus.';
+$messages['passwordshort'] = 'Parool peab olema vähemalt $length märki pikk.';
+$messages['passwordweak'] = 'Parool peab sisaldama vähemalt üht numbrit ja märki.';
+$messages['passwordforbidden'] = 'Parool sisaldab keelatud märki.';
+$messages['firstloginchange'] = 'See on sinu esimene sisselogimine, palun muuda oma parooli.';
+?>
diff --git a/plugins/password/localization/eu_ES.inc b/plugins/password/localization/eu_ES.inc
new file mode 100644
index 000000000..7f93d0110
--- /dev/null
+++ b/plugins/password/localization/eu_ES.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Pasahitza aldatu';
+$labels['curpasswd'] = 'Oraingo pasahitza:';
+$labels['newpasswd'] = 'Pasahitz berria:';
+$labels['confpasswd'] = 'Konfirmatu pasahitz berria:';
+$messages['nopassword'] = 'Sartu pasahitz berria.';
+$messages['nocurpassword'] = 'Sartu oraingo pasahitza.';
+$messages['passwordincorrect'] = 'Oraingo pasahitza ez da zuzena.';
+$messages['passwordinconsistency'] = 'Pasahitz berria ez datoz bat, saiatu berriz.';
+$messages['crypterror'] = 'Ezin izan da pasahitz berria gorde. Ez da enkriptazio funtziorik aurkitu.';
+$messages['connecterror'] = 'Ezin izan da pasahitz berria gorde. Konexio arazoak egon dira.';
+$messages['internalerror'] = 'Ezin izan da pasahitz berria gorde.';
+$messages['passwordshort'] = 'Gutxienez $length karakteretakoa izan behar du pasahitzak.';
+$messages['passwordweak'] = 'Gutxienez zenbaki bat eta puntuazio karaktere bat izan behar du pasahitzak.';
+$messages['passwordforbidden'] = 'Galarazitako karaktereak daude pasahitzean.';
+$messages['firstloginchange'] = 'Zure lehenengo sarrera da. Pasahitza aldatu mesedez.';
+?>
diff --git a/plugins/password/localization/fa_AF.inc b/plugins/password/localization/fa_AF.inc
new file mode 100644
index 000000000..3df6a3057
--- /dev/null
+++ b/plugins/password/localization/fa_AF.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'رمز عبور کنونی';
+$labels['newpasswd'] = 'رمز عبور جدید';
+$labels['confpasswd'] = 'تایید رمز عبور جدید';
+$messages['nopassword'] = 'لطفا رمز عبور جدیدی وارد کنید';
+$messages['nocurpassword'] = 'لطفا رمز عبور کنونی را وارد کنید';
+$messages['passwordincorrect'] = 'رمز عبور کنونی اشتباه است';
+$messages['passwordinconsistency'] = 'رمزهای عبور با هم مطابقت ندارند، لطفا دوباره سعی کنید';
+$messages['crypterror'] = 'امکان ذخیره رمز عبور جدید وجود ندارد. تابع رمزگذاری یافت نشد';
+$messages['connecterror'] = 'امکان ذخیره رمز عبور جدید وجود ندارد. لطفا دوباره سعی کنید';
+$messages['internalerror'] = 'امکان ذخیره رمز عبور جدید وجود ندارد';
+$messages['passwordshort'] = 'طول رمز عبور می بایست حداقل به طول $length کاراکتر باشد';
+$messages['passwordweak'] = 'رمز عبور می بایست دارای حداقل یک عدد و یک کاراکتر علامت گذاری باشد';
+$messages['passwordforbidden'] = 'رمز عبور شامل کاراکترهای غیر مجاز است';
+?>
diff --git a/plugins/password/localization/fa_IR.inc b/plugins/password/localization/fa_IR.inc
new file mode 100644
index 000000000..900f9f5ac
--- /dev/null
+++ b/plugins/password/localization/fa_IR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'تغییر گذرواژه';
+$labels['curpasswd'] = 'گذرواژه فعلی:';
+$labels['newpasswd'] = 'گذرواژه جدید:';
+$labels['confpasswd'] = 'تایید گذرواژه جدید:';
+$messages['nopassword'] = 'لطفا گذرواژه جدید را وارد نمایید.';
+$messages['nocurpassword'] = ' لطفا گذرواژه فعلی را وارد نمایید.';
+$messages['passwordincorrect'] = 'گذرواژه فعلی اشتباه است.';
+$messages['passwordinconsistency'] = 'گذرواژه‌ها با هم مطابقت ندارند، دوباره سعی نمایید.';
+$messages['crypterror'] = 'گذرواژه جدید نمی‌تواند ذخیره شود. نبود تابع رمزگذاری.';
+$messages['connecterror'] = 'گذرواژه جدید نمی‌تواند ذخیره شود. خطای ارتباط.';
+$messages['internalerror'] = 'گذرواژه جدید نتوانست ذخیره نشد.';
+$messages['passwordshort'] = 'گذرواژه باید حداقل $length کاراکتر طول داشته باشد.';
+$messages['passwordweak'] = 'گذرواژه باید شامل حداقل یک عدد و یک کاراکتر نشانه‌ای باشد.';
+$messages['passwordforbidden'] = 'گذرواژه شامل کاراکترهای غیرمجاز است.';
+$messages['firstloginchange'] = 'این اولین ورود شما است، لطفا گذرواژه خود را تغییر دهید.';
+?>
diff --git a/plugins/password/localization/fi_FI.inc b/plugins/password/localization/fi_FI.inc
new file mode 100644
index 000000000..5cf0db192
--- /dev/null
+++ b/plugins/password/localization/fi_FI.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Vaihda salasana';
+$labels['curpasswd'] = 'Nykyinen salasana:';
+$labels['newpasswd'] = 'Uusi salasana:';
+$labels['confpasswd'] = 'Vahvista uusi salasana:';
+$messages['nopassword'] = 'Syötä uusi salasana.';
+$messages['nocurpassword'] = 'Syötä nykyinen salasana.';
+$messages['passwordincorrect'] = 'Nykyinen salasana on väärin.';
+$messages['passwordinconsistency'] = 'Salasanat eivät täsmää, yritä uudelleen.';
+$messages['crypterror'] = 'Uuden salasanan tallennus epäonnistui. Kryptausfunktio puuttuu.';
+$messages['connecterror'] = 'Uuden salasanan tallennus epäonnistui. Yhteysongelma.';
+$messages['internalerror'] = 'Uuden salasanan tallennus epäonnistui.';
+$messages['passwordshort'] = 'Salasanassa täytyy olla vähintään $length merkkiä.';
+$messages['passwordweak'] = 'Salasanan täytyy sisältää vähintään yksi numero ja yksi välimerkki.';
+$messages['passwordforbidden'] = 'Salasana sisältää virheellisiä merkkejä.';
+$messages['firstloginchange'] = 'Tämä on ensimmäinen kirjautumiskertasi. Vaihda salasanasi.';
+?>
diff --git a/plugins/password/localization/fo_FO.inc b/plugins/password/localization/fo_FO.inc
new file mode 100644
index 000000000..875f79b69
--- /dev/null
+++ b/plugins/password/localization/fo_FO.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Nú verandi loyniorð:';
+$labels['newpasswd'] = 'Nýtt loyniorð:';
+$labels['confpasswd'] = 'Endurtak nýggja loyniorð:';
+$messages['nopassword'] = 'Vinarliga skriva inn nýtt loyniorð.';
+$messages['nocurpassword'] = 'Vinarliga skriva inn núverandi loyniorð.';
+$messages['passwordincorrect'] = 'Verandi loyniorð er skeift.';
+$messages['passwordinconsistency'] = 'Loyniorðini eru ikki líka, vinarliga royn aftur.';
+$messages['crypterror'] = 'Kann ikki goyma nýggja loyniorð. Brongling manglar.';
+$messages['connecterror'] = 'Kann ikki goyma nýtt loyniorð. Sambands feilur.';
+$messages['internalerror'] = 'Kundi ikki goyma nýggja loyniorðið.';
+$messages['passwordshort'] = 'Loyniorði má hvørfall verða $length tekin langt.';
+$messages['passwordweak'] = 'Loyniorði má innihalda minst eitt nummar og eitt punktum tekin.';
+$messages['passwordforbidden'] = 'Loyniorð inniheldur ólóglig tekin.';
+?>
diff --git a/plugins/password/localization/fr_FR.inc b/plugins/password/localization/fr_FR.inc
new file mode 100644
index 000000000..03c914e11
--- /dev/null
+++ b/plugins/password/localization/fr_FR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Changer le mot de passe';
+$labels['curpasswd'] = 'Mot de passe actuel :';
+$labels['newpasswd'] = 'Nouveau mot de passe :';
+$labels['confpasswd'] = 'Confirmer le nouveau mot de passe :';
+$messages['nopassword'] = 'Veuillez saisir le nouveau mot de passe.';
+$messages['nocurpassword'] = 'Veuillez saisir le mot de passe actuel.';
+$messages['passwordincorrect'] = 'Le mot de passe actuel est erroné.';
+$messages['passwordinconsistency'] = 'Les mots de passe ne correspondent pas, veuillez ressayer.';
+$messages['crypterror'] = 'Impossible d\'enregistrer le nouveau mot de passe. La fonction de chiffrement est manquante.';
+$messages['connecterror'] = 'Impossible d\'enregistrer le nouveau mot de passe. Erreur de connexion.';
+$messages['internalerror'] = 'Impossible d\'enregistrer le nouveau mot de passe.';
+$messages['passwordshort'] = 'Le mot de passe doit comporter au moins $length caractères.';
+$messages['passwordweak'] = 'Le mot de passe doit comporter au moins un chiffre et un signe de ponctuation.';
+$messages['passwordforbidden'] = 'Le mot de passe contient des caractères interdits.';
+$messages['firstloginchange'] = 'Ceci est votre première connexion. Veuillez changer votre mot de passe.';
+?>
diff --git a/plugins/password/localization/fy_NL.inc b/plugins/password/localization/fy_NL.inc
new file mode 100644
index 000000000..413a80ce5
--- /dev/null
+++ b/plugins/password/localization/fy_NL.inc
@@ -0,0 +1,19 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['newpasswd'] = 'Nij wachtwurd:';
+?>
diff --git a/plugins/password/localization/gl_ES.inc b/plugins/password/localization/gl_ES.inc
new file mode 100644
index 000000000..b0f5e39b2
--- /dev/null
+++ b/plugins/password/localization/gl_ES.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Cambiar contrasinal';
+$labels['curpasswd'] = 'Contrasinal actual:';
+$labels['newpasswd'] = 'Contrasinal novo:';
+$labels['confpasswd'] = 'Confirmar contrasinal:';
+$messages['nopassword'] = 'Por favor, introduce un contrasinal novo.';
+$messages['nocurpassword'] = 'Por favor, introduce o contrasinal actual.';
+$messages['passwordincorrect'] = 'O contrasinal actual é incorrecto.';
+$messages['passwordinconsistency'] = 'Os contrasinais non cadran. Por favor, inténtao outra vez.';
+$messages['crypterror'] = 'Non foi posíbel gardar o contrasinal novo. Falta a función de cifrado.';
+$messages['connecterror'] = 'Non foi posíbel gardar o contrasinal novo. Erro de conexión';
+$messages['internalerror'] = 'Non foi posíbel gardar o contrasinal novo.';
+$messages['passwordshort'] = 'O contrasinal debe ter polo menos $length caracteres.';
+$messages['passwordweak'] = 'O contrasinal debe incluir polo menos un número e un signo de puntuación.';
+$messages['passwordforbidden'] = 'O contrasinal contén caracteres non permitidos.';
+$messages['firstloginchange'] = 'É a primeira vez que se conecta. Por favor, troque o seu contrasinal.';
+?>
diff --git a/plugins/password/localization/he_IL.inc b/plugins/password/localization/he_IL.inc
new file mode 100644
index 000000000..c60acd7c1
--- /dev/null
+++ b/plugins/password/localization/he_IL.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'שנה סיסמה';
+$labels['curpasswd'] = 'סיסמה נוכחית:';
+$labels['newpasswd'] = 'סיסמה חדשה:';
+$labels['confpasswd'] = 'אימות הסיסמה החדשה:';
+$messages['nopassword'] = 'נא להקליד סיסמה חדשה';
+$messages['nocurpassword'] = 'נא להקיש הסיסמה הנוכחית';
+$messages['passwordincorrect'] = 'הוקשה סיסמה נוכחית שגויה';
+$messages['passwordinconsistency'] = 'הסיסמאות שהוקשו אינן תואמות, נא לנסות שנית.';
+$messages['crypterror'] = 'לא נשמרה הסיסמה החדשה. חסר מנגנון הצפנה.';
+$messages['connecterror'] = 'לא נשמרה הסיסמה החדשה. שגיאת תקשורת.';
+$messages['internalerror'] = 'לא ניתן לשמור על הסיסמה החדשה.';
+$messages['passwordshort'] = 'הסיסמה צריכה להיות לפחות בעלת $length תווים';
+$messages['passwordweak'] = 'הסיסמה חייבת לכלול לפחות סיפרה אחת ולפחות סימן פיסוק אחד.';
+$messages['passwordforbidden'] = 'הסיסמה מכילה תווים אסורים.';
+$messages['firstloginchange'] = 'זוהי כניסתך הראשונה. אנא שנה את סיסמתך.';
+?>
diff --git a/plugins/password/localization/hr_HR.inc b/plugins/password/localization/hr_HR.inc
new file mode 100644
index 000000000..9815bf504
--- /dev/null
+++ b/plugins/password/localization/hr_HR.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Važeća zaporka:';
+$labels['newpasswd'] = 'Nova zaporka:';
+$labels['confpasswd'] = 'Potvrda nove zaporke:';
+$messages['nopassword'] = 'Molimo unesite novu zaporku.';
+$messages['nocurpassword'] = 'Molimo unesite trenutnu zaporku.';
+$messages['passwordincorrect'] = 'Trenutna zaporka je nevažeća.';
+$messages['passwordinconsistency'] = 'Zaporke su različite, pokušajte ponovo.';
+$messages['crypterror'] = 'Nemoguće promijeniti zaporku. Nedostaje enkripcijska funkcija.';
+$messages['connecterror'] = 'Nemoguće promijeniti zaporku. Greška prilikom spajanja.';
+$messages['internalerror'] = 'Nemoguće promijeniti zaporku.';
+$messages['passwordshort'] = 'Zaporka mora sadržavati barem $length znakova.';
+$messages['passwordweak'] = 'Zaporka mora sadržavati barem jedanu znamenku i jedan interpunkcijski znak.';
+$messages['passwordforbidden'] = 'Zaporka sadrži nedozvoljene znakove.';
+?>
diff --git a/plugins/password/localization/hu_HU.inc b/plugins/password/localization/hu_HU.inc
new file mode 100644
index 000000000..46fd82a42
--- /dev/null
+++ b/plugins/password/localization/hu_HU.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Jelszó módosítás';
+$labels['curpasswd'] = 'Jelenlegi jelszó:';
+$labels['newpasswd'] = 'Új jelszó:';
+$labels['confpasswd'] = 'Új jelszó mégegyszer:';
+$messages['nopassword'] = 'Kérjük adja meg az új jelszót.';
+$messages['nocurpassword'] = 'Kérjük adja meg a jelenlegi jelszót.';
+$messages['passwordincorrect'] = 'Érvénytelen a jelenlegi jelszó.';
+$messages['passwordinconsistency'] = 'A beírt jelszavak nem azonosak. Próbálja újra.';
+$messages['crypterror'] = 'Hiba történt a kérés feldolgozása során.';
+$messages['connecterror'] = 'Az új jelszó mentése nem sikerült. Hiba a kapcsolatban';
+$messages['internalerror'] = 'Hiba történt a kérés feldolgozása során.';
+$messages['passwordshort'] = 'A jelszónak legalább $length karakter hosszunak kell lennie.';
+$messages['passwordweak'] = 'A jelszónak mindenképpen kell tartalmaznia egy számot és egy írásjelet.';
+$messages['passwordforbidden'] = 'A jelszó tiltott karaktert is tartalmaz.';
+$messages['firstloginchange'] = 'Ez az első belépésed. Változtass jelszót.';
+?>
diff --git a/plugins/password/localization/hy_AM.inc b/plugins/password/localization/hy_AM.inc
new file mode 100644
index 000000000..824f38642
--- /dev/null
+++ b/plugins/password/localization/hy_AM.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Փոխել գաղտնաբառը';
+$labels['curpasswd'] = 'Ներկա գաղտնաբառ`';
+$labels['newpasswd'] = 'Նոր գաղտնաբառ`';
+$labels['confpasswd'] = 'Կրկնեք նոր գաղտնաբառը`';
+$messages['nopassword'] = 'Ներմուցեք նոր գաղտնաբառը։';
+$messages['nocurpassword'] = 'Ներմուցեք առկա գաղտնաբառը։';
+$messages['passwordincorrect'] = 'Առկա գաղտնաբառը սխալ է։';
+$messages['passwordinconsistency'] = 'Նոր գաղտնաբառերը չեն համընկնում, կրկին փորձեք։';
+$messages['crypterror'] = 'Նոր գաղտնաբառի պահպանումը ձախողվեց։ Բացակայում է գաղտնագրման ֆունկցիան։';
+$messages['connecterror'] = 'Նոր գաղտնաբառի պահպանումը ձախողվեց։ Կապի սխալ։';
+$messages['internalerror'] = 'Նոր գաղտնաբառի պահպանումը ձախողվեց։';
+$messages['passwordshort'] = 'Գաղտնաբառերը պետք է լինեն առնվազն $length նիշ երկարությամբ։';
+$messages['passwordweak'] = 'Գաղտնաբառերը պետք է պարունակեն առնվազն մեկ թիվ և մեկ կետադրական նիշ։';
+$messages['passwordforbidden'] = 'Գաղտնաբառը պարունակում է արգելված նիշ։';
+$messages['firstloginchange'] = 'Սա ձեր առաջին մուտքն է։ Խնդրում ենք փոխել գաղտնաբառը։';
+?>
diff --git a/plugins/password/localization/ia.inc b/plugins/password/localization/ia.inc
new file mode 100644
index 000000000..45479634d
--- /dev/null
+++ b/plugins/password/localization/ia.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Cambiar contrasigno';
+$labels['curpasswd'] = 'Contrasigno actual:';
+$labels['newpasswd'] = 'Nove contrasigno:';
+$labels['confpasswd'] = 'Confirmar nove contrasigno:';
+$messages['nopassword'] = 'Entra un nove contrasigno.';
+$messages['nocurpassword'] = 'Entra le contrasigno actual.';
+$messages['passwordincorrect'] = 'Le contrasigno actual es incorrecte.';
+$messages['passwordinconsistency'] = 'Le contrasignos non es identic. Essaya lo de novo.';
+$messages['crypterror'] = 'Impossibile salveguardar le nove contrasigno. Le function de cryptographia manca.';
+$messages['connecterror'] = 'Impossibile salveguardar le nove contrasigno. Error de connexion.';
+$messages['internalerror'] = 'Impossibile salveguardar le nove contrasigno.';
+$messages['passwordshort'] = 'Le contrasigno debe haber al minus $length characteres.';
+$messages['passwordweak'] = 'Le contrasigno debe includer al minus un numero e un character de punctuation.';
+$messages['passwordforbidden'] = 'Le contrasigno contine characteres interdicte.';
+$messages['firstloginchange'] = 'Iste es vostre prime session. Per favor, cambia vostre contrasigno.';
+?>
diff --git a/plugins/password/localization/id_ID.inc b/plugins/password/localization/id_ID.inc
new file mode 100644
index 000000000..3a42abdf3
--- /dev/null
+++ b/plugins/password/localization/id_ID.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Sandi saat ini:';
+$labels['newpasswd'] = 'Sandi Baru:';
+$labels['confpasswd'] = 'Konfirmasi Sandi Baru:';
+$messages['nopassword'] = 'Masukkan sandi baru.';
+$messages['nocurpassword'] = 'Masukkan sandi saat ini.';
+$messages['passwordincorrect'] = 'Sandi saat ini salah.';
+$messages['passwordinconsistency'] = 'Sandi tidak cocok, harap coba lagi.';
+$messages['crypterror'] = 'Tidak dapat menyimpan sandi baru. Fungsi enkripsi tidak ditemukan.';
+$messages['connecterror'] = 'Tidak dapat menyimpan sandi baru. Koneksi error.';
+$messages['internalerror'] = 'Tidak dapat menyimpan sandi baru.';
+$messages['passwordshort'] = 'Panjang password minimal $length karakter';
+$messages['passwordweak'] = 'Sandi harus menyertakan setidaknya satu angka dan satu tanda baca.';
+$messages['passwordforbidden'] = 'Sandi mengandung karakter terlarang.';
+?>
diff --git a/plugins/password/localization/it_IT.inc b/plugins/password/localization/it_IT.inc
new file mode 100644
index 000000000..d9bdb4fd5
--- /dev/null
+++ b/plugins/password/localization/it_IT.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Modifica la Password';
+$labels['curpasswd'] = 'Password corrente:';
+$labels['newpasswd'] = 'Nuova password:';
+$labels['confpasswd'] = 'Conferma la nuova Password:';
+$messages['nopassword'] = 'Per favore inserire la nuova password.';
+$messages['nocurpassword'] = 'Per favore inserire la password corrente.';
+$messages['passwordincorrect'] = 'La password corrente non è corretta.';
+$messages['passwordinconsistency'] = 'Le password non coincidono, per favore reinserire.';
+$messages['crypterror'] = 'Impossibile salvare la nuova password. Funzione di crittografia mancante.';
+$messages['connecterror'] = 'Imposibile salvare la nuova password. Errore di connessione.';
+$messages['internalerror'] = 'Impossibile salvare la nuova password.';
+$messages['passwordshort'] = 'La password deve essere lunga almeno $length caratteri.';
+$messages['passwordweak'] = 'La password deve includere almeno una cifra decimale e un simbolo di punteggiatura.';
+$messages['passwordforbidden'] = 'La password contiene caratteri proibiti.';
+$messages['firstloginchange'] = 'Questo è il tuo primo accesso. Si prega di cambiare la propria password.';
+?>
diff --git a/plugins/password/localization/ja_JP.inc b/plugins/password/localization/ja_JP.inc
new file mode 100644
index 000000000..7c97215c3
--- /dev/null
+++ b/plugins/password/localization/ja_JP.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'パスワードの変更';
+$labels['curpasswd'] = '現在のパスワード:';
+$labels['newpasswd'] = '新しいパスワード:';
+$labels['confpasswd'] = '新しいパスワード (確認):';
+$messages['nopassword'] = '新しいパスワードを入力してください。';
+$messages['nocurpassword'] = '現在のパスワードを入力してください。';
+$messages['passwordincorrect'] = '現在のパスワードが間違っています。';
+$messages['passwordinconsistency'] = 'パスワードが一致しません。もう一度やり直してください。';
+$messages['crypterror'] = 'パスワードを保存できませんでした。暗号化関数がみあたりません。';
+$messages['connecterror'] = '新しいパスワードを保存できませんでした。接続エラーです。';
+$messages['internalerror'] = '新しいパスワードを保存できませんでした。';
+$messages['passwordshort'] = 'パスワードは少なくとも $length 文字の長さが必要です。';
+$messages['passwordweak'] = 'パスワードは少なくとも数字の 1 文字と記号の 1 文字を含んでいなければなりません。';
+$messages['passwordforbidden'] = 'パスワードに禁止された文字が含まれています。';
+$messages['firstloginchange'] = 'これは初めてのログインです。パスワードを変更してください。';
+?>
diff --git a/plugins/password/localization/km_KH.inc b/plugins/password/localization/km_KH.inc
new file mode 100644
index 000000000..5e92faf41
--- /dev/null
+++ b/plugins/password/localization/km_KH.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'ពាក្យ​សម្ងាត់​បច្ចុប្បន្ន៖';
+$labels['newpasswd'] = 'ពាក្យ​សម្ងាត់​ថ្មី៖';
+$labels['confpasswd'] = 'បញ្ជាក់​ពាក្យ​សម្ងាត់​ថ្មី៖';
+$messages['nopassword'] = 'សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​ថ្មី។';
+$messages['nocurpassword'] = 'សូម​បញ្ចូល​ពាក្យ​សម្ងាត់​បច្ចុប្បន្ន​ឲ្យ​បាន​ត្រូវ។';
+$messages['passwordincorrect'] = 'ពាក្យ​សម្ងាត់​បច្ចុប្បន្ន​គឺ​មិន​ត្រូវ​ឡើយ។';
+$messages['passwordinconsistency'] = 'ពាក្យ​សម្ងាត់​មិន​ត្រូវ​គ្នា​ទេ សូម​ព្យាយាម​ម្ដង​ទៀត។';
+$messages['crypterror'] = 'មិន​អាច​រក្សា​ទុក​ពាក្យ​សម្ងាត់​ថ្មី​បាន​ទេ។ បាត់​មុខងារ​កូដនីយកម្ម។';
+$messages['connecterror'] = 'មិន​អាច​រក្សា​ទុក​ពាក្យ​សម្ងាត់​ថ្មី​បាន​ទេ។ ការ​តភ្ជាប់​មាន​បញ្ហា។';
+$messages['internalerror'] = 'មិន​អាច​រក្សា​ទុក​ពាក្យ​សម្ងាត់​ថ្មី​បាន​ទេ។';
+$messages['passwordshort'] = 'ពាក្យ​សម្ងាត់​ត្រូវ​តែ​មាន​យ៉ាង​តិច $length តួ។';
+$messages['passwordweak'] = 'ពាក្យ​សម្ងាត់​ត្រូវ​តែ​មាន​បញ្ចូល​យ៉ាង​ហោច​ណាស់​លេខ​មួយ​តួ និង​អក្សរ​សញ្ញា​មួយ​តួ។';
+$messages['passwordforbidden'] = 'ពាក្យ​សម្ងាត់​មាន​អក្សរ​ដែល​ត្រូវហាម​ឃាត់។';
+?>
diff --git a/plugins/password/localization/ko_KR.inc b/plugins/password/localization/ko_KR.inc
new file mode 100644
index 000000000..1d6374295
--- /dev/null
+++ b/plugins/password/localization/ko_KR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = '암호 변경';
+$labels['curpasswd'] = '현재 암호:';
+$labels['newpasswd'] = '새로운 암호:';
+$labels['confpasswd'] = '새로운 암호 확인:';
+$messages['nopassword'] = '새로운 암호를 입력하세요.';
+$messages['nocurpassword'] = '현재 사용 중인 암호를 입력하세요.';
+$messages['passwordincorrect'] = '현재 사용 중인 암호가 올바르지 않습니다.';
+$messages['passwordinconsistency'] = '암호가 일치하지 않습니다. 다시 시도해주세요.';
+$messages['crypterror'] = '새로운 암호를 저장할 수 없습니다. 암호화 기능이 누락되었습니다.';
+$messages['connecterror'] = '새로운 암호를 저장할 수 없습니다. 연결 오류입니다.';
+$messages['internalerror'] = '새로운 암호를 저장할 수 없습니다.';
+$messages['passwordshort'] = '암호는 문자가 $length개 이상이어야 합니다.';
+$messages['passwordweak'] = '암호는 숫자 및 특수문자를 각각 한 개 이상 포함해야 합니다.';
+$messages['passwordforbidden'] = '암호가 금지된 문자을 포함하고 있습니다.';
+$messages['firstloginchange'] = '처음 로그인하셨습니다. 암호를 변경해주세요.';
+?>
diff --git a/plugins/password/localization/ku.inc b/plugins/password/localization/ku.inc
new file mode 100644
index 000000000..574539b21
--- /dev/null
+++ b/plugins/password/localization/ku.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Şîfreyê biguherîne';
+$labels['curpasswd'] = 'Şîfreya niha:';
+$labels['newpasswd'] = 'Şîfreya nû:';
+$labels['confpasswd'] = 'Şîfreya nû bipejirîne:';
+$messages['nopassword'] = 'Şîfreya nû binivîse.';
+$messages['nocurpassword'] = 'Şîfreya niha binivîse.';
+$messages['passwordincorrect'] = 'Şîfreya niha xelet e.';
+$messages['passwordinconsistency'] = 'Şîfre hevdu nagirin, dîsa biceribîne.';
+$messages['crypterror'] = 'Şîfreya nû nehat tomarkirin. Fonksiyona şîfrekirinê hat jibîrkirin.';
+$messages['connecterror'] = 'Şîfreya nû nehat tomarkirin. Çewtiya girêdanê.';
+$messages['internalerror'] = 'Şîfre nehat tomarkirin.';
+$messages['passwordshort'] = 'Divê şîfre ji $length karakteran kêmtir nebe.';
+$messages['passwordweak'] = 'Divê di şîfreyê de herî kêm hejmarek û karakterekî xalbendiyê hebe.';
+$messages['passwordforbidden'] = 'Şîfre karakterên qedexe dihewîne.';
+$messages['firstloginchange'] = 'Ev têketina te ya yekemîn e. Ji kerema xwe şîfreya xwe biguherîne.';
+?>
diff --git a/plugins/password/localization/ku_IQ.inc b/plugins/password/localization/ku_IQ.inc
new file mode 100644
index 000000000..67ec86de1
--- /dev/null
+++ b/plugins/password/localization/ku_IQ.inc
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'گۆڕینی تێپەڕەوشە';
+$labels['curpasswd'] = 'تێپەڕەوشەی ئێستا:';
+$labels['newpasswd'] = 'تێپەڕەوشەی نوێ:';
+$labels['confpasswd'] = 'پشتڕاستکردنەوەی تێپەڕەوشەی نوێ:';
+$messages['nopassword'] = 'تکایە تێپەڕەوشەی نوێ بنووسە.';
+$messages['nocurpassword'] = 'تکایە تێپەڕەوشەی ئێستا بنووسە.';
+$messages['passwordincorrect'] = 'تێپەڕەوشەی ئێستا نادروستە.';
+$messages['passwordinconsistency'] = 'تێپەڕەوشەکان هاویەک نین، تکایە دووبارە هەوڵبدەوە.';
+$messages['connecterror'] = 'نەتوانرا تێپەڕەوشەی نوێ پاشەکەوت بکرێت. هەڵەی پەیوەندیکردن.';
+$messages['internalerror'] = 'نەتوانرا تێپەڕەوشەی نوێ پاشەکەوت بکرێت.';
+$messages['passwordforbidden'] = 'تێپەڕەوشە نووسەی ڕێپێنەدراوی تێدایە.';
+$messages['firstloginchange'] = 'ئەمە یەکەم چوونەژوورەوەتە. تکایە تێپەڕەوشەکەت بگۆڕە.';
+?>
diff --git a/plugins/password/localization/lb_LU.inc b/plugins/password/localization/lb_LU.inc
new file mode 100644
index 000000000..2093b82ab
--- /dev/null
+++ b/plugins/password/localization/lb_LU.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Aktuellt Passwuert:';
+$labels['newpasswd'] = 'Neit Passwuert:';
+$labels['confpasswd'] = 'Neit Passwuert bestätegen:';
+$messages['nopassword'] = 'Gëff wann ech gelift en neit Passwuert an.';
+$messages['nocurpassword'] = 'Gëff wann ech gelift dat aktuellt Passwuert an.';
+$messages['passwordincorrect'] = 'Aktuellt Passwuert net korrekt.';
+$messages['passwordinconsistency'] = 'D\'Passwierder passen net, probéier wann ech gelift nach eng Kéier.';
+$messages['crypterror'] = 'Passwuert konnt net gespäichert ginn. Verschlësselungs-Funktioun feelt.';
+$messages['connecterror'] = 'Passwuert konnt net gespäichert ginn. Connectiouns-Feeler.';
+$messages['internalerror'] = 'Neit Passwuert konnt net gespäichert ginn.';
+$messages['passwordshort'] = 'D\'Passwuert muss mindestens $length Zeeche laang sinn.';
+$messages['passwordweak'] = 'D\'Passwuert muss mindestens eng Zuel an ee Sazzeechen enthalen.';
+$messages['passwordforbidden'] = 'D\'Passwuert enthält verbueden Zeechen.';
+?>
diff --git a/plugins/password/localization/lt_LT.inc b/plugins/password/localization/lt_LT.inc
new file mode 100644
index 000000000..3351c305e
--- /dev/null
+++ b/plugins/password/localization/lt_LT.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Keisti slaptažodį';
+$labels['curpasswd'] = 'Dabartinis slaptažodis:';
+$labels['newpasswd'] = 'Naujasis slaptažodis:';
+$labels['confpasswd'] = 'Pakartokite naująjį slaptažodį:';
+$messages['nopassword'] = 'Prašom įvesti naująjį slaptažodį.';
+$messages['nocurpassword'] = 'Prašom įvesti dabartinį slaptažodį.';
+$messages['passwordincorrect'] = 'Dabartinis slaptažodis neteisingas.';
+$messages['passwordinconsistency'] = 'Slaptažodžiai nesutapo. Bandykite dar kartą.';
+$messages['crypterror'] = 'Nepavyko įrašyti naujojo slaptažodžio. Trūksta šifravimo funkcijos.';
+$messages['connecterror'] = 'Nepavyko įrašyti naujojo slaptažodžio. Ryšio klaida.';
+$messages['internalerror'] = 'Nepavyko įrašyti naujojo slaptažodžio.';
+$messages['passwordshort'] = 'Slaptažodis turi būti sudarytas bent iš $length simbolių.';
+$messages['passwordweak'] = 'Slaptažodyje turi būti bent vienas skaitmuo ir vienas skyrybos ženklas.';
+$messages['passwordforbidden'] = 'Slaptažodyje rasta neleistinų simbolių.';
+$messages['firstloginchange'] = 'Tai yra pirmasis jūsų prisijungimas. Prašau, pasikeiskite savo slaptažodį.';
+?>
diff --git a/plugins/password/localization/lv_LV.inc b/plugins/password/localization/lv_LV.inc
new file mode 100644
index 000000000..9e0e0e740
--- /dev/null
+++ b/plugins/password/localization/lv_LV.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Pašreizējā parole:';
+$labels['newpasswd'] = 'Jaunā parole:';
+$labels['confpasswd'] = 'Apstiprināt jauno paroli:';
+$messages['nopassword'] = 'Lūdzu ievadiet jauno paroli.';
+$messages['nocurpassword'] = 'Lūdzu ievadiet pašreizējo paroli.';
+$messages['passwordincorrect'] = 'Pašreizējā parole nav pareiza.';
+$messages['passwordinconsistency'] = 'Paroles nesakrīt. Lūdzu, ievadiet vēlreiz.';
+$messages['crypterror'] = 'Nevarēja saglabāt jauno paroli. Trūkst kriptēšanas funkcijas.';
+$messages['connecterror'] = 'Nevarēja saglabāt jauno paroli. Savienojuma kļūda.';
+$messages['internalerror'] = 'Nevarēja saglabāt jauno paroli.';
+$messages['passwordshort'] = 'Jaunajai parolei jābūt vismaz $length simbolu garai.';
+$messages['passwordweak'] = 'Jaunajai parolei jāsatur vismaz viens cipars un speciālais simbols.';
+$messages['passwordforbidden'] = 'Parole satur neatļautus simbolus.';
+?>
diff --git a/plugins/password/localization/ml_IN.inc b/plugins/password/localization/ml_IN.inc
new file mode 100644
index 000000000..6b8ac9e32
--- /dev/null
+++ b/plugins/password/localization/ml_IN.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'രഹസ്യവാക്ക് മാറ്റുക';
+$labels['curpasswd'] = 'ഇപ്പോഴത്തെ രഹസ്യവാക്ക്';
+$labels['newpasswd'] = 'പുതിയ രഹസ്യവാക്ക്';
+$labels['confpasswd'] = 'പുതിയ രഹസ്യവാക്ക് സ്ഥിരീകരിക്കുക';
+$messages['nopassword'] = 'ദയവായി പുതിയ രഹസ്യവാക്ക് നൽകുക';
+$messages['nocurpassword'] = 'ദയവായി ഇപ്പോഴത്തെ രഹസ്യവാക്ക് നൽകുക';
+$messages['passwordincorrect'] = 'ഇപ്പോഴത്തെ രഹസ്യവാക്ക് തെറ്റാണ്.';
+$messages['passwordinconsistency'] = 'രഹസ്യവാക്കുകൾ ചേരുന്നില്ല, ദയവായി വീണ്ടും ശ്രമിക്കുക';
+$messages['crypterror'] = 'പുതിയ രഹസ്യവാക്ക് സൂക്ഷിക്കാൻ സാധിച്ചില്ല. എൻക്രിപ്ഷൻ ഫങ്ങ്ഷൻ ലഭ്യമല്ല.';
+$messages['connecterror'] = 'പുതിയ രഹസ്യവാക്ക് സൂക്ഷിക്കാൻ സാധിച്ചില്ല. ബന്ധം സ്ഥാപിക്കുന്നതിൽ പിഴവ്.';
+$messages['internalerror'] = 'പുതിയ രഹസ്യവാക്ക് സൂക്ഷിക്കാൻ സാധിച്ചില്ല.';
+$messages['passwordshort'] = 'രഹസ്യവാക്കിനു് കുറഞ്ഞത് $length അക്ഷരങ്ങൾ നീളം വേണം';
+$messages['passwordweak'] = 'രഹസ്യവാക്കിൽ കുറഞ്ഞത് ഒരു സംഖ്യയും, ഒരു പ്രത്യേക അക്ഷരവും വേണം';
+$messages['passwordforbidden'] = 'രഹസ്യവാക്കിൽ അനുവദനീയമല്ലാത്ത അക്ഷരങ്ങൾ ഉണ്ട്';
+$messages['firstloginchange'] = 'ഇത് താങ്കളുടെ ആദ്യത്തെ പ്രവേശനമാണ്. ദയവായി താങ്കളുടെ രഹസ്യവാക്ക് മാറ്റുക.';
+?>
diff --git a/plugins/password/localization/nb_NO.inc b/plugins/password/localization/nb_NO.inc
new file mode 100644
index 000000000..5d69740f0
--- /dev/null
+++ b/plugins/password/localization/nb_NO.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Nåværende passord:';
+$labels['newpasswd'] = 'Nytt passord:';
+$labels['confpasswd'] = 'Bekreft nytt passord';
+$messages['nopassword'] = 'Vennligst skriv inn nytt passord';
+$messages['nocurpassword'] = 'Vennligst skriv inn nåværende passord';
+$messages['passwordincorrect'] = 'Nåværende passord er feil.';
+$messages['passwordinconsistency'] = 'Passordene er ikke like, vennligst prøv igjen.';
+$messages['crypterror'] = 'Kunne ikke lagre nytt passord. Krypteringsfunksjonen mangler.';
+$messages['connecterror'] = 'Kunne ikke lagre nytt passord. Tilkoblingsfeil.';
+$messages['internalerror'] = 'Kunne ikke lagre nytt passord';
+$messages['passwordshort'] = 'Passordet må minimum inneholde $length tegn.';
+$messages['passwordweak'] = 'Passordet må inneholde minst ett tall og ett tegnsettingssymbol.';
+$messages['passwordforbidden'] = 'Passordet inneholder forbudte tegn.';
+?>
diff --git a/plugins/password/localization/nl_NL.inc b/plugins/password/localization/nl_NL.inc
new file mode 100644
index 000000000..41ca116cc
--- /dev/null
+++ b/plugins/password/localization/nl_NL.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Wijzig wachtwoord';
+$labels['curpasswd'] = 'Huidig wachtwoord:';
+$labels['newpasswd'] = 'Nieuw wachtwoord:';
+$labels['confpasswd'] = 'Bevestig nieuw wachtwoord:';
+$messages['nopassword'] = 'Vul uw nieuwe wachtwoord in.';
+$messages['nocurpassword'] = 'Vul uw huidige wachtwoord in.';
+$messages['passwordincorrect'] = 'Huidig wachtwoord is onjuist.';
+$messages['passwordinconsistency'] = 'Wachtwoorden komen niet overeen, probeer het opnieuw.';
+$messages['crypterror'] = 'Nieuwe wachtwoord kan niet opgeslagen worden; de server mist een versleutelfunctie.';
+$messages['connecterror'] = 'Nieuwe wachtwoord kan niet opgeslagen worden; verbindingsfout.';
+$messages['internalerror'] = 'Uw nieuwe wachtwoord kan niet worden opgeslagen.';
+$messages['passwordshort'] = 'Het wachtwoord moet minimaal $length tekens lang zijn.';
+$messages['passwordweak'] = 'Het wachtwoord moet minimaal één cijfer en één leesteken bevatten.';
+$messages['passwordforbidden'] = 'Het wachtwoord bevat tekens die niet toegestaan zijn.';
+$messages['firstloginchange'] = 'Dit is uw eerste aanmelding. Verander uw wachtwoord alstublieft.';
+?>
diff --git a/plugins/password/localization/nn_NO.inc b/plugins/password/localization/nn_NO.inc
new file mode 100644
index 000000000..9a8fd78aa
--- /dev/null
+++ b/plugins/password/localization/nn_NO.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Noverande passord:';
+$labels['newpasswd'] = 'Nytt passord:';
+$labels['confpasswd'] = 'Bekreft nytt passord';
+$messages['nopassword'] = 'Venlegast skriv inn nytt passord.';
+$messages['nocurpassword'] = 'Venlegast skriv inn noverande passord.';
+$messages['passwordincorrect'] = 'Noverande passord er feil.';
+$messages['passwordinconsistency'] = 'Passorda er ikkje like, venlegast prøv igjen.';
+$messages['crypterror'] = 'Kunne ikkje lagre nytt passord. Krypteringsfunksjonen manglar.';
+$messages['connecterror'] = 'Kunne ikkje lagre nytt passord. Tilkoblingsfeil.';
+$messages['internalerror'] = 'Kunne ikkje lagre nytt passord.';
+$messages['passwordshort'] = 'Passordet må minimum innehalde $length teikn.';
+$messages['passwordweak'] = 'Passordet må innehalde minst eitt tal og eitt skilleteikn.';
+$messages['passwordforbidden'] = 'Passordet inneheld forbodne teikn.';
+?>
diff --git a/plugins/password/localization/pl_PL.inc b/plugins/password/localization/pl_PL.inc
new file mode 100644
index 000000000..00a7aa7e3
--- /dev/null
+++ b/plugins/password/localization/pl_PL.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Zmiana hasła';
+$labels['curpasswd'] = 'Aktualne hasło:';
+$labels['newpasswd'] = 'Nowe hasło:';
+$labels['confpasswd'] = 'Potwierdź hasło:';
+$messages['nopassword'] = 'Wprowadź nowe hasło.';
+$messages['nocurpassword'] = 'Wprowadź aktualne hasło.';
+$messages['passwordincorrect'] = 'Błędne aktualne hasło, spróbuj ponownie.';
+$messages['passwordinconsistency'] = 'Hasła nie pasują, spróbuj ponownie.';
+$messages['crypterror'] = 'Nie udało się zapisać nowego hasła. Brak funkcji kodującej.';
+$messages['connecterror'] = 'Nie udało się zapisać nowego hasła. Błąd połączenia.';
+$messages['internalerror'] = 'Nie udało się zapisać nowego hasła.';
+$messages['passwordshort'] = 'Hasło musi posiadać co najmniej $length znaków.';
+$messages['passwordweak'] = 'Hasło musi zawierać co najmniej jedną cyfrę i znak interpunkcyjny.';
+$messages['passwordforbidden'] = 'Hasło zawiera niedozwolone znaki.';
+$messages['firstloginchange'] = 'To jest twoje pierwsze logowanie. Proszę zmień hasło.';
+?>
diff --git a/plugins/password/localization/pt_BR.inc b/plugins/password/localization/pt_BR.inc
new file mode 100644
index 000000000..1eeccb0b2
--- /dev/null
+++ b/plugins/password/localization/pt_BR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Alterar a senha';
+$labels['curpasswd'] = 'Senha atual:';
+$labels['newpasswd'] = 'Nova senha:';
+$labels['confpasswd'] = 'Confirmar nova senha:';
+$messages['nopassword'] = 'Por favor, informe a nova senha.';
+$messages['nocurpassword'] = 'Por favor, informe a senha atual.';
+$messages['passwordincorrect'] = 'Senha atual incorreta.';
+$messages['passwordinconsistency'] = 'Senhas não combinam, por favor tente novamente.';
+$messages['crypterror'] = 'Não foi possível gravar a nova senha. Função de criptografia ausente.';
+$messages['connecterror'] = 'Não foi possível gravar a nova senha. Erro de conexão.';
+$messages['internalerror'] = 'Não foi possível gravar a nova senha.';
+$messages['passwordshort'] = 'A senha precisa ter ao menos $length caracteres.';
+$messages['passwordweak'] = 'A senha precisa conter ao menos um número e um caractere de pontuação.';
+$messages['passwordforbidden'] = 'A senha contém caracteres proibidos.';
+$messages['firstloginchange'] = 'Este é o seu primeiro acesso. Por favor altere sua senha.';
+?>
diff --git a/plugins/password/localization/pt_PT.inc b/plugins/password/localization/pt_PT.inc
new file mode 100644
index 000000000..6317ede9c
--- /dev/null
+++ b/plugins/password/localization/pt_PT.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Alterar palavra-passe';
+$labels['curpasswd'] = 'Palavra-passe actual:';
+$labels['newpasswd'] = 'Nova palavra-passe:';
+$labels['confpasswd'] = 'Confirmar palavra-passe:';
+$messages['nopassword'] = 'Introduza a nova palavra-passe.';
+$messages['nocurpassword'] = 'Introduza a palavra-passe actual.';
+$messages['passwordincorrect'] = 'Palavra-passe actual incorrecta.';
+$messages['passwordinconsistency'] = 'As palavras-passe não combinam, tente novamente.';
+$messages['crypterror'] = 'Não foi possível gravar a nova palavra-passe. Função de criptografia inexistente.';
+$messages['connecterror'] = 'Não foi possível gravar a nova palavra-passe. Erro de ligação.';
+$messages['internalerror'] = 'Não foi possível gravar a nova palavra-passe.';
+$messages['passwordshort'] = 'A palavra-passe deve ter pelo menos $length caracteres';
+$messages['passwordweak'] = 'A palavra-passe deve incluir pelo menos um numero e um sinal de pontuação.';
+$messages['passwordforbidden'] = 'A palavra-passe contém caracteres não suportados.';
+$messages['firstloginchange'] = 'Este é o seu primeiro acesso. Por favor, altere a sua palavra-passe.';
+?>
diff --git a/plugins/password/localization/ro_RO.inc b/plugins/password/localization/ro_RO.inc
new file mode 100644
index 000000000..74fd80765
--- /dev/null
+++ b/plugins/password/localization/ro_RO.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Schimbă parola';
+$labels['curpasswd'] = 'Parola curentă:';
+$labels['newpasswd'] = 'Parola nouă:';
+$labels['confpasswd'] = 'Confirmare parola nouă:';
+$messages['nopassword'] = 'Te rog să introduci noua parolă.';
+$messages['nocurpassword'] = 'Te rog să introduci parola curentă';
+$messages['passwordincorrect'] = 'Parola curentă este incorectă.';
+$messages['passwordinconsistency'] = 'Parolele nu se potrivesc, te rog să mai încerci';
+$messages['crypterror'] = 'Nu am reușit să salvez noua parolă. Funcția de criptare lipsește.';
+$messages['connecterror'] = 'Nu am reușit să salvez noua parolă. Eroare connexiune.';
+$messages['internalerror'] = 'Nu am reușit să salvez noua parolă.';
+$messages['passwordshort'] = 'Parola trebuie să aibă minim $length caractere.';
+$messages['passwordweak'] = 'Parola trebuie să conțina cel puțin un număr si un semn de punctuație.';
+$messages['passwordforbidden'] = 'Parola conține caractere nepermise.';
+$messages['firstloginchange'] = 'Aceasta este prima autentificare. Te rugăm să schimbi parola.';
+?>
diff --git a/plugins/password/localization/ru_RU.inc b/plugins/password/localization/ru_RU.inc
new file mode 100644
index 000000000..d7c03477a
--- /dev/null
+++ b/plugins/password/localization/ru_RU.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Изменить пароль';
+$labels['curpasswd'] = 'Текущий пароль:';
+$labels['newpasswd'] = 'Новый пароль:';
+$labels['confpasswd'] = 'Подтвердите новый пароль:';
+$messages['nopassword'] = 'Пожалуйста, введите новый пароль.';
+$messages['nocurpassword'] = 'Пожалуйста, введите текущий пароль.';
+$messages['passwordincorrect'] = 'Текущий пароль неверен.';
+$messages['passwordinconsistency'] = 'Пароли не совпадают, попробуйте ещё раз, пожалуйста.';
+$messages['crypterror'] = 'Не могу сохранить новый пароль. Отсутствует криптографическая функция.';
+$messages['connecterror'] = 'Не могу сохранить новый пароль. Ошибка соединения.';
+$messages['internalerror'] = 'Не могу сохранить новый пароль.';
+$messages['passwordshort'] = 'Длина пароля должна быть как минимум $length символов.';
+$messages['passwordweak'] = 'Пароль должен включать в себя как минимум одну цифру и один знак пунктуации.';
+$messages['passwordforbidden'] = 'Пароль содержит недопустимые символы.';
+$messages['firstloginchange'] = 'Вы выполнили вход впервые. Измените ваш пароль.';
+?>
diff --git a/plugins/password/localization/sk_SK.inc b/plugins/password/localization/sk_SK.inc
new file mode 100644
index 000000000..4cf8cb91f
--- /dev/null
+++ b/plugins/password/localization/sk_SK.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Zmeniť heslo';
+$labels['curpasswd'] = 'Aktuálne heslo:';
+$labels['newpasswd'] = 'Nové heslo:';
+$labels['confpasswd'] = 'Potvrďte nové heslo:';
+$messages['nopassword'] = 'Prosím zadajte nové heslo.';
+$messages['nocurpassword'] = 'Prosím zadajte aktuálne heslo.';
+$messages['passwordincorrect'] = 'Aktuálne heslo je nesprávne.';
+$messages['passwordinconsistency'] = 'Heslá nie sú rovnaké, skúste to znova.';
+$messages['crypterror'] = 'Nové heslo nemožno uložiť. Chýba šifrovacia funkcia.';
+$messages['connecterror'] = 'Nové heslo nemožno uložiť. Chyba spojenia.';
+$messages['internalerror'] = 'Nové heslo nemožno uložiť.';
+$messages['passwordshort'] = 'Heslo musí mať najmenej $length znakov.';
+$messages['passwordweak'] = 'Heslo musí obsahovať aspoň jedno číslo a jedno interpunkčné znamienko.';
+$messages['passwordforbidden'] = 'Heslo obsahuje nepovolené znaky.';
+$messages['firstloginchange'] = 'Prihlásili ste sa po prvýkrát. Prosím zmeňte si prístupové heslo.';
+?>
diff --git a/plugins/password/localization/sl_SI.inc b/plugins/password/localization/sl_SI.inc
new file mode 100644
index 000000000..ec9010c77
--- /dev/null
+++ b/plugins/password/localization/sl_SI.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Obstoječe geslo:';
+$labels['newpasswd'] = 'Novo geslo:';
+$labels['confpasswd'] = 'Potrdi novo geslo:';
+$messages['nopassword'] = 'Vnesite novo geslo.';
+$messages['nocurpassword'] = 'Vnesite obstoječe geslo.';
+$messages['passwordincorrect'] = 'Obstoječe geslo ni veljavno.';
+$messages['passwordinconsistency'] = 'Gesli se ne ujemata, poskusite znova.';
+$messages['crypterror'] = 'Novega gesla ni bilo mogoče shraniti. Prišlo je do napake pri šifriranju.';
+$messages['connecterror'] = 'Novega gesla ni bilo mogoče shraniti. Prišlo je do napake v povezavi.';
+$messages['internalerror'] = 'Novega gesla ni bilo mogoče shraniti.';
+$messages['passwordshort'] = 'Geslo mora vsebovati vsaj $length znakov';
+$messages['passwordweak'] = 'Geslo mora vključevati vsaj eno številko in ločilo.';
+$messages['passwordforbidden'] = 'Geslo vsebuje neveljavne znake.';
+?>
diff --git a/plugins/password/localization/sq_AL.inc b/plugins/password/localization/sq_AL.inc
new file mode 100644
index 000000000..3b615b619
--- /dev/null
+++ b/plugins/password/localization/sq_AL.inc
@@ -0,0 +1,24 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Ndrysho fjalëkalimin';
+$labels['newpasswd'] = 'Fjalëkalimi i ri:';
+$labels['confpasswd'] = 'Konfirmo fjalëkalimin e ri:';
+$messages['nopassword'] = 'Ju lutem shkruani fjalëkalimin e ri.';
+$messages['nocurpassword'] = 'Ju lutem shkruani fjalëkalimin e tanishëm.';
+$messages['passwordincorrect'] = 'Fjalëkalimi i tanishëm nuk është i saktë.';
+?>
diff --git a/plugins/password/localization/sr_CS.inc b/plugins/password/localization/sr_CS.inc
new file mode 100644
index 000000000..77e2d1251
--- /dev/null
+++ b/plugins/password/localization/sr_CS.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Тренутна лозинка:';
+$labels['newpasswd'] = 'Нова лозинка:';
+$labels['confpasswd'] = 'Поновите лозинку:';
+$messages['nopassword'] = 'Молимо унесите нову лозинку.';
+$messages['nocurpassword'] = 'Молимо унесите тренутну лозинку.';
+$messages['passwordincorrect'] = 'Тренутна лозинка је нетачна.';
+$messages['passwordinconsistency'] = 'Лозинке се не поклапају, молимо покушајте поново.';
+$messages['crypterror'] = 'Није могуће сачувати нову лозинку. Недостаје функција за кодирање.';
+$messages['connecterror'] = 'Није могуће сачувати нову лозинку. Грешка у Вези.';
+$messages['internalerror'] = 'Није могуће сачувати нову лозинку.';
+$messages['passwordshort'] = 'Лозинка мора имати најмање $lenght знакова.';
+$messages['passwordweak'] = 'Лозинка мора да садржи најмање један број и један интерпункцијски знак.';
+$messages['passwordforbidden'] = 'Лозинка садржи недозвољене знакове.';
+?>
diff --git a/plugins/password/localization/sv_SE.inc b/plugins/password/localization/sv_SE.inc
new file mode 100644
index 000000000..26ee37d06
--- /dev/null
+++ b/plugins/password/localization/sv_SE.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Ändra lösenord';
+$labels['curpasswd'] = 'Nuvarande lösenord:';
+$labels['newpasswd'] = 'Nytt lösenord:';
+$labels['confpasswd'] = 'Bekräfta nytt lösenord:';
+$messages['nopassword'] = 'Ange nytt lösenord.';
+$messages['nocurpassword'] = 'Ange nuvarande lösenord.';
+$messages['passwordincorrect'] = 'Felaktigt nuvarande lösenord.';
+$messages['passwordinconsistency'] = 'Bekräftelsen av lösenordet stämmer inte, försök igen.';
+$messages['crypterror'] = 'Lösenordet kunde inte ändras. Krypteringsfunktionen saknas.';
+$messages['connecterror'] = 'Lösenordet kunde inte ändras. Anslutningen misslyckades.';
+$messages['internalerror'] = 'Lösenordet kunde inte ändras.';
+$messages['passwordshort'] = 'Lösenordet måste vara minst $length tecken långt.';
+$messages['passwordweak'] = 'Lösenordet måste innehålla minst en siffra och ett specialtecken.';
+$messages['passwordforbidden'] = 'Lösenordet innehåller otillåtna tecken.';
+$messages['firstloginchange'] = 'Du loggar in för första gången. Vänligen ändra ditt lösenord.';
+?>
diff --git a/plugins/password/localization/ti.inc b/plugins/password/localization/ti.inc
new file mode 100644
index 000000000..fd334a957
--- /dev/null
+++ b/plugins/password/localization/ti.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'ህልው መሕለፊ ቃል:';
+$labels['newpasswd'] = 'ሓዱሽ መሕለፊ ቃል:';
+$labels['confpasswd'] = 'መረጋገፂ ሓዱሽ መሕለፊ ቃል :';
+$messages['nopassword'] = 'ሓዱሽ መሕለፊ ቃል አብዚ ይእቶ::';
+$messages['nocurpassword'] = 'ህልው መሕለፊ ቃል ኣብዚ ይእቶ::';
+$messages['passwordincorrect'] = 'ህልው መሕለፊ ቃል ከምኡ ኣይኮነን::';
+$messages['passwordinconsistency'] = 'መሕለፍቲ ቃላት ሓድ ኣይኮኑን ::ተውሳኺ ፈተነ የድሊ::';
+$messages['crypterror'] = 'መመስጥሪ ፋንክሽን ስለዝሳእነ እቲ መሕለፊ ቃል ኣይተቐመጠን::';
+$messages['connecterror'] = 'ናይ ርክብ ጸገም ስለዘሎ እቲ መሕለፊ ቃል ኣይተቐመጠን::';
+$messages['internalerror'] = 'እቲ መሕለፊ ቃል ኣይተቐመጠን::';
+$messages['passwordshort'] = 'ንውሓት መሕለፊ ቃል $length ፊዳላት ክኾን አለዎ::';
+$messages['passwordweak'] = 'መሕለፊ ቃል እንተውሓደ ሓደ ኣሃዝን ሓደ ስርዓተ ነጥብን ከጠቓልል አለዎ::';
+$messages['passwordforbidden'] = 'እቲ መሕለፊ ቃል ውጉዳት ፊዳላት አለውዎ::';
+?>
diff --git a/plugins/password/localization/tr_TR.inc b/plugins/password/localization/tr_TR.inc
new file mode 100644
index 000000000..f74eed924
--- /dev/null
+++ b/plugins/password/localization/tr_TR.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = 'Parolayı değiştir';
+$labels['curpasswd'] = 'Şimdiki Parola:';
+$labels['newpasswd'] = 'Yeni Parola:';
+$labels['confpasswd'] = 'Yeni Parolayı Onaylayın:';
+$messages['nopassword'] = 'Yeni parolayı giriniz.';
+$messages['nocurpassword'] = 'Şimdiki parolayı giriniz.';
+$messages['passwordincorrect'] = 'Şimdiki parolayı yanlış girdiniz.';
+$messages['passwordinconsistency'] = 'Girdiğiniz parolalar uyuşmuyor.Tekrar deneyiniz.';
+$messages['crypterror'] = 'Yeni parola kaydedilemedi. Şifreleme fonksiyonu mevcut değil.';
+$messages['connecterror'] = 'Yeni parola kaydedilemedi. Bağlantı hatası!...';
+$messages['internalerror'] = 'Yeni parola kaydedilemedi.';
+$messages['passwordshort'] = 'Parola en az $length karakterden oluşmalı.';
+$messages['passwordweak'] = 'Parola en az bir sayı ve bir noktalama işareti içermeli.';
+$messages['passwordforbidden'] = 'Parola uygunsuz karakter(ler) içeriyor.';
+$messages['firstloginchange'] = 'Bu ilk girişiniz. Parolanızı değiştiriniz.';
+?>
diff --git a/plugins/password/localization/uk_UA.inc b/plugins/password/localization/uk_UA.inc
new file mode 100644
index 000000000..d9e96d15e
--- /dev/null
+++ b/plugins/password/localization/uk_UA.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Поточний пароль:';
+$labels['newpasswd'] = 'Новий пароль:';
+$labels['confpasswd'] = 'Підтвердіть новий пароль:';
+$messages['nopassword'] = 'Будь ласка, введіть новий пароль.';
+$messages['nocurpassword'] = 'Будь ласка, введіть поточний пароль.';
+$messages['passwordincorrect'] = 'Поточний пароль неправильний.';
+$messages['passwordinconsistency'] = 'Паролі не збігаються, спробуйте ще раз.';
+$messages['crypterror'] = 'Не вдалося зберегти новий пароль. Функція шифрування відсутня.';
+$messages['connecterror'] = 'Не вдалося зберегти новий пароль. Помилка з\'єднання.';
+$messages['internalerror'] = 'Не вдалося зберегти новий пароль.';
+$messages['passwordshort'] = 'Пароль повинен бути не менше $length символів.';
+$messages['passwordweak'] = 'Пароль повинен містити як мінімум одну цифру і один розділовий знак.';
+$messages['passwordforbidden'] = 'Пароль містить заборонені символи.';
+?>
diff --git a/plugins/password/localization/vi_VN.inc b/plugins/password/localization/vi_VN.inc
new file mode 100644
index 000000000..8dcf706d8
--- /dev/null
+++ b/plugins/password/localization/vi_VN.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = 'Mật khẩu hiện tại';
+$labels['newpasswd'] = 'Mật khẩu mới:';
+$labels['confpasswd'] = 'Xác nhận mật khẩu mới';
+$messages['nopassword'] = 'Mời nhập mật khẩu mới';
+$messages['nocurpassword'] = 'Mời nhập mật khẩu hiện tại';
+$messages['passwordincorrect'] = 'Mật khẩu hiện thời không đúng';
+$messages['passwordinconsistency'] = 'Mật khẩu không khớp, hãy thử lại';
+$messages['crypterror'] = 'Không thể lưu mật khẩu mới. Thiếu chức năng mã hóa';
+$messages['connecterror'] = 'Không thể lưu mật mã mới. Lổi kết nối';
+$messages['internalerror'] = 'Không thể lưu mật khẩu mới';
+$messages['passwordshort'] = 'Mật khẩu phải dài ít nhất $ ký tự';
+$messages['passwordweak'] = 'Mật khẩu phải bao gồm ít nhất 1 con số và 1 ký tự dấu câu';
+$messages['passwordforbidden'] = 'Mật khẩu bao gồm ký tự không hợp lệ';
+?>
diff --git a/plugins/password/localization/zh_CN.inc b/plugins/password/localization/zh_CN.inc
new file mode 100644
index 000000000..681e5c7e2
--- /dev/null
+++ b/plugins/password/localization/zh_CN.inc
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['curpasswd'] = '当前密码:';
+$labels['newpasswd'] = '新密码:';
+$labels['confpasswd'] = '确认新密码:';
+$messages['nopassword'] = '请输入新密码。';
+$messages['nocurpassword'] = '请输入当前的密码。';
+$messages['passwordincorrect'] = '当前密码不正确。';
+$messages['passwordinconsistency'] = '两次输入的密码不一致,请重试。';
+$messages['crypterror'] = '无法保存新密码,缺少加密功能。';
+$messages['connecterror'] = '无法保存新密码,连接出错。';
+$messages['internalerror'] = '无法保存新密码。';
+$messages['passwordshort'] = '密码至少为 $length 位。';
+$messages['passwordweak'] = '密码必须至少包含一个数字和一个标点符号。';
+$messages['passwordforbidden'] = '密码包含禁止使用的字符。';
+?>
diff --git a/plugins/password/localization/zh_TW.inc b/plugins/password/localization/zh_TW.inc
new file mode 100644
index 000000000..22d88f042
--- /dev/null
+++ b/plugins/password/localization/zh_TW.inc
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | plugins/password/localization/<lang>.inc |
+ | |
+ | Localization file of the Roundcube Webmail Password plugin |
+ | Copyright (C) 2012-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-password/
+*/
+$labels['changepasswd'] = '更改密碼';
+$labels['curpasswd'] = '目前的密碼';
+$labels['newpasswd'] = '新密碼';
+$labels['confpasswd'] = '確認新密碼';
+$messages['nopassword'] = '請輸入新密碼';
+$messages['nocurpassword'] = '請輸入目前的密碼';
+$messages['passwordincorrect'] = '目前的密碼錯誤';
+$messages['passwordinconsistency'] = '密碼不相符,請重新輸入';
+$messages['crypterror'] = '無法更新密碼:無加密機制';
+$messages['connecterror'] = '無法更新密碼:連線失敗';
+$messages['internalerror'] = '無法更新密碼';
+$messages['passwordshort'] = '您的密碼至少需 $length 個字元長';
+$messages['passwordweak'] = '您的新密碼至少需含有一個數字與一個標點符號';
+$messages['passwordforbidden'] = '您的密碼含有禁用字元';
+$messages['firstloginchange'] = '這是你第一次登入。請更改你的密碼。';
+?>
diff --git a/plugins/password/password.js b/plugins/password/password.js
new file mode 100644
index 000000000..d0fd75a11
--- /dev/null
+++ b/plugins/password/password.js
@@ -0,0 +1,47 @@
+/**
+ * Password plugin script
+ *
+ * @licstart The following is the entire license notice for the
+ * JavaScript code in this file.
+ *
+ * Copyright (c) 2012-2014, The Roundcube Dev Team
+ *
+ * The JavaScript code in this page is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * @licend The above is the entire license notice
+ * for the JavaScript code in this file.
+ */
+
+window.rcmail && rcmail.addEventListener('init', function(evt) {
+ // register command handler
+ rcmail.register_command('plugin.password-save', function() {
+ var input_curpasswd = rcube_find_object('_curpasswd'),
+ input_newpasswd = rcube_find_object('_newpasswd'),
+ input_confpasswd = rcube_find_object('_confpasswd');
+
+ if (input_curpasswd && input_curpasswd.value == '') {
+ alert(rcmail.gettext('nocurpassword', 'password'));
+ input_curpasswd.focus();
+ }
+ else if (input_newpasswd && input_newpasswd.value == '') {
+ alert(rcmail.gettext('nopassword', 'password'));
+ input_newpasswd.focus();
+ }
+ else if (input_confpasswd && input_confpasswd.value == '') {
+ alert(rcmail.gettext('nopassword', 'password'));
+ input_confpasswd.focus();
+ }
+ else if (input_newpasswd && input_confpasswd && input_newpasswd.value != input_confpasswd.value) {
+ alert(rcmail.gettext('passwordinconsistency', 'password'));
+ input_newpasswd.focus();
+ }
+ else {
+ rcmail.gui_objects.passform.submit();
+ }
+ }, true);
+
+ $('input:not(:hidden):first').focus();
+});
diff --git a/plugins/password/password.php b/plugins/password/password.php
new file mode 100644
index 000000000..9239cd0b0
--- /dev/null
+++ b/plugins/password/password.php
@@ -0,0 +1,370 @@
+<?php
+
+/**
+ * Password Plugin for Roundcube
+ *
+ * @version @package_version@
+ * @author Aleksander Machniak <alec@alec.pl>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+define('PASSWORD_CRYPT_ERROR', 1);
+define('PASSWORD_ERROR', 2);
+define('PASSWORD_CONNECT_ERROR', 3);
+define('PASSWORD_SUCCESS', 0);
+
+/**
+ * Change password plugin
+ *
+ * Plugin that adds functionality to change a users password.
+ * It provides common functionality and user interface and supports
+ * several backends to finally update the password.
+ *
+ * For installation and configuration instructions please read the README file.
+ *
+ * @author Aleksander Machniak
+ */
+class password extends rcube_plugin
+{
+ public $task = 'settings|login';
+ public $noframe = true;
+ public $noajax = true;
+
+ private $newuser = false;
+
+ function init()
+ {
+ $rcmail = rcmail::get_instance();
+
+ $this->load_config();
+
+ if ($rcmail->task == 'settings') {
+ if (!$this->check_host_login_exceptions()) {
+ return;
+ }
+
+ $this->add_texts('localization/');
+
+ $this->add_hook('settings_actions', array($this, 'settings_actions'));
+
+ $this->register_action('plugin.password', array($this, 'password_init'));
+ $this->register_action('plugin.password-save', array($this, 'password_save'));
+
+ if (strpos($rcmail->action, 'plugin.password') === 0) {
+ $this->include_script('password.js');
+ }
+ }
+ else if ($rcmail->config->get('password_force_new_user')) {
+ $this->add_hook('user_create', array($this, 'user_create'));
+ $this->add_hook('login_after', array($this, 'login_after'));
+ }
+ }
+
+ function settings_actions($args)
+ {
+ // register as settings action
+ $args['actions'][] = array(
+ 'action' => 'plugin.password',
+ 'class' => 'password',
+ 'label' => 'password',
+ 'title' => 'changepasswd',
+ 'domain' => 'password',
+ );
+
+ return $args;
+ }
+
+ function password_init()
+ {
+ $this->register_handler('plugin.body', array($this, 'password_form'));
+
+ $rcmail = rcmail::get_instance();
+ $rcmail->output->set_pagetitle($this->gettext('changepasswd'));
+
+ if (rcube_utils::get_input_value('_first', rcube_utils::INPUT_GET)) {
+ $rcmail->output->command('display_message', $this->gettext('firstloginchange'), 'notice');
+ }
+
+ $rcmail->output->send('plugin');
+ }
+
+ function password_save()
+ {
+ $this->register_handler('plugin.body', array($this, 'password_form'));
+
+ $rcmail = rcmail::get_instance();
+ $rcmail->output->set_pagetitle($this->gettext('changepasswd'));
+
+ $confirm = $rcmail->config->get('password_confirm_current');
+ $required_length = intval($rcmail->config->get('password_minimum_length'));
+ $check_strength = $rcmail->config->get('password_require_nonalpha');
+
+ if (($confirm && !isset($_POST['_curpasswd'])) || !isset($_POST['_newpasswd'])) {
+ $rcmail->output->command('display_message', $this->gettext('nopassword'), 'error');
+ }
+ else {
+ $charset = strtoupper($rcmail->config->get('password_charset', 'ISO-8859-1'));
+ $rc_charset = strtoupper($rcmail->output->get_charset());
+
+ $sespwd = $rcmail->decrypt($_SESSION['password']);
+ $curpwd = $confirm ? rcube_utils::get_input_value('_curpasswd', rcube_utils::INPUT_POST, true, $charset) : $sespwd;
+ $newpwd = rcube_utils::get_input_value('_newpasswd', rcube_utils::INPUT_POST, true);
+ $conpwd = rcube_utils::get_input_value('_confpasswd', rcube_utils::INPUT_POST, true);
+
+ // check allowed characters according to the configured 'password_charset' option
+ // by converting the password entered by the user to this charset and back to UTF-8
+ $orig_pwd = $newpwd;
+ $chk_pwd = rcube_charset::convert($orig_pwd, $rc_charset, $charset);
+ $chk_pwd = rcube_charset::convert($chk_pwd, $charset, $rc_charset);
+
+ // WARNING: Default password_charset is ISO-8859-1, so conversion will
+ // change national characters. This may disable possibility of using
+ // the same password in other MUA's.
+ // We're doing this for consistence with Roundcube core
+ $newpwd = rcube_charset::convert($newpwd, $rc_charset, $charset);
+ $conpwd = rcube_charset::convert($conpwd, $rc_charset, $charset);
+
+ if ($chk_pwd != $orig_pwd) {
+ $rcmail->output->command('display_message', $this->gettext('passwordforbidden'), 'error');
+ }
+ // other passwords validity checks
+ else if ($conpwd != $newpwd) {
+ $rcmail->output->command('display_message', $this->gettext('passwordinconsistency'), 'error');
+ }
+ else if ($confirm && $sespwd != $curpwd) {
+ $rcmail->output->command('display_message', $this->gettext('passwordincorrect'), 'error');
+ }
+ else if ($required_length && strlen($newpwd) < $required_length) {
+ $rcmail->output->command('display_message', $this->gettext(
+ array('name' => 'passwordshort', 'vars' => array('length' => $required_length))), 'error');
+ }
+ else if ($check_strength && (!preg_match("/[0-9]/", $newpwd) || !preg_match("/[^A-Za-z0-9]/", $newpwd))) {
+ $rcmail->output->command('display_message', $this->gettext('passwordweak'), 'error');
+ }
+ // password is the same as the old one, do nothing, return success
+ else if ($sespwd == $newpwd && !$rcmail->config->get('password_force_save')) {
+ $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
+ }
+ // try to save the password
+ else if (!($res = $this->_save($curpwd, $newpwd))) {
+ $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
+
+ // allow additional actions after password change (e.g. reset some backends)
+ $plugin = $rcmail->plugins->exec_hook('password_change', array(
+ 'old_pass' => $curpwd, 'new_pass' => $newpwd));
+
+ // Reset session password
+ $_SESSION['password'] = $rcmail->encrypt($plugin['new_pass']);
+
+ // Log password change
+ if ($rcmail->config->get('password_log')) {
+ rcube::write_log('password', sprintf('Password changed for user %s (ID: %d) from %s',
+ $rcmail->get_user_name(), $rcmail->user->ID, rcube_utils::remote_ip()));
+ }
+ }
+ else {
+ $rcmail->output->command('display_message', $res, 'error');
+ }
+ }
+
+ $rcmail->overwrite_action('plugin.password');
+ $rcmail->output->send('plugin');
+ }
+
+ function password_form()
+ {
+ $rcmail = rcmail::get_instance();
+
+ // add some labels to client
+ $rcmail->output->add_label(
+ 'password.nopassword',
+ 'password.nocurpassword',
+ 'password.passwordinconsistency'
+ );
+
+ $rcmail->output->set_env('product_name', $rcmail->config->get('product_name'));
+
+ $table = new html_table(array('cols' => 2));
+
+ if ($rcmail->config->get('password_confirm_current')) {
+ // show current password selection
+ $field_id = 'curpasswd';
+ $input_curpasswd = new html_passwordfield(array('name' => '_curpasswd', 'id' => $field_id,
+ 'size' => 20, 'autocomplete' => 'off'));
+
+ $table->add('title', html::label($field_id, rcube::Q($this->gettext('curpasswd'))));
+ $table->add(null, $input_curpasswd->show());
+ }
+
+ // show new password selection
+ $field_id = 'newpasswd';
+ $input_newpasswd = new html_passwordfield(array('name' => '_newpasswd', 'id' => $field_id,
+ 'size' => 20, 'autocomplete' => 'off'));
+
+ $table->add('title', html::label($field_id, rcube::Q($this->gettext('newpasswd'))));
+ $table->add(null, $input_newpasswd->show());
+
+ // show confirm password selection
+ $field_id = 'confpasswd';
+ $input_confpasswd = new html_passwordfield(array('name' => '_confpasswd', 'id' => $field_id,
+ 'size' => 20, 'autocomplete' => 'off'));
+
+ $table->add('title', html::label($field_id, rcube::Q($this->gettext('confpasswd'))));
+ $table->add(null, $input_confpasswd->show());
+
+ $rules = '';
+
+ $required_length = intval($rcmail->config->get('password_minimum_length'));
+ if ($required_length > 0) {
+ $rules .= html::tag('li', array('id' => 'required-length'), $this->gettext(array(
+ 'name' => 'passwordshort',
+ 'vars' => array('length' => $required_length)
+ )));
+ }
+
+ if ($rcmail->config->get('password_require_nonalpha')) {
+ $rules .= html::tag('li', array('id' => 'require-nonalpha'), $this->gettext('passwordweak'));
+ }
+
+ if (!empty($rules)) {
+ $rules = html::tag('ul', array('id' => 'ruleslist'), $rules);
+ }
+
+ $out = html::div(array('class' => 'box'),
+ html::div(array('id' => 'prefs-title', 'class' => 'boxtitle'), $this->gettext('changepasswd')) .
+ html::div(array('class' => 'boxcontent'), $table->show() .
+ $rules .
+ html::p(null,
+ $rcmail->output->button(array(
+ 'command' => 'plugin.password-save',
+ 'type' => 'input',
+ 'class' => 'button mainaction',
+ 'label' => 'save'
+ )))));
+
+ $rcmail->output->add_gui_object('passform', 'password-form');
+
+ return $rcmail->output->form_tag(array(
+ 'id' => 'password-form',
+ 'name' => 'password-form',
+ 'method' => 'post',
+ 'action' => './?_task=settings&_action=plugin.password-save',
+ ), $out);
+ }
+
+ private function _save($curpass, $passwd)
+ {
+ $config = rcmail::get_instance()->config;
+ $driver = $config->get('password_driver', 'sql');
+ $class = "rcube_{$driver}_password";
+ $file = $this->home . "/drivers/$driver.php";
+
+ if (!file_exists($file)) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Unable to open driver file ($file)"
+ ), true, false);
+ return $this->gettext('internalerror');
+ }
+
+ include_once $file;
+
+ if (!class_exists($class, false) || !method_exists($class, 'save')) {
+ rcube::raise_error(array(
+ 'code' => 600,
+ 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Password plugin: Broken driver $driver"
+ ), true, false);
+ return $this->gettext('internalerror');
+ }
+
+ $object = new $class;
+ $result = $object->save($curpass, $passwd);
+
+ if (is_array($result)) {
+ $message = $result['message'];
+ $result = $result['code'];
+ }
+
+ switch ($result) {
+ case PASSWORD_SUCCESS:
+ return;
+ case PASSWORD_CRYPT_ERROR:
+ $reason = $this->gettext('crypterror');
+ break;
+ case PASSWORD_CONNECT_ERROR:
+ $reason = $this->gettext('connecterror');
+ break;
+ case PASSWORD_ERROR:
+ default:
+ $reason = $this->gettext('internalerror');
+ }
+
+ if ($message) {
+ $reason .= ' ' . $message;
+ }
+
+ return $reason;
+ }
+
+ function user_create($args)
+ {
+ $this->newuser = true;
+ return $args;
+ }
+
+ function login_after($args)
+ {
+ if ($this->newuser && $this->check_host_login_exceptions()) {
+ $args['_task'] = 'settings';
+ $args['_action'] = 'plugin.password';
+ $args['_first'] = 'true';
+ }
+
+ return $args;
+ }
+
+ // Check if host and login is allowed to change the password, false = not allowed, true = not allowed
+ private function check_host_login_exceptions()
+ {
+ $rcmail = rcmail::get_instance();
+
+ // Host exceptions
+ $hosts = $rcmail->config->get('password_hosts');
+ if (!empty($hosts) && !in_array($_SESSION['storage_host'], $hosts)) {
+ return false;
+ }
+
+ // Login exceptions
+ if ($exceptions = $rcmail->config->get('password_login_exceptions')) {
+ $exceptions = array_map('trim', (array) $exceptions);
+ $exceptions = array_filter($exceptions);
+ $username = $_SESSION['username'];
+
+ foreach ($exceptions as $ec) {
+ if ($username === $ec) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/plugins/password/tests/Password.php b/plugins/password/tests/Password.php
new file mode 100644
index 000000000..b64c6b889
--- /dev/null
+++ b/plugins/password/tests/Password.php
@@ -0,0 +1,23 @@
+<?php
+
+class Password_Plugin extends PHPUnit_Framework_TestCase
+{
+
+ function setUp()
+ {
+ include_once __DIR__ . '/../password.php';
+ }
+
+ /**
+ * Plugin object construction test
+ */
+ function test_constructor()
+ {
+ $rcube = rcube::get_instance();
+ $plugin = new password($rcube->api);
+
+ $this->assertInstanceOf('password', $plugin);
+ $this->assertInstanceOf('rcube_plugin', $plugin);
+ }
+}
+