/**
  * Establish a connection to the LDAP server
  */
 public function connect($host = null)
 {
     // Net_LDAP3 does not support IDNA yet
     // also parse_host() here is very Roundcube specific
     $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
     return parent::connect($host);
 }
示例#2
0
 /**
  * Handler for submitted form (ajax request)
  *
  * Check fields and save to default identity if valid.
  * Afterwards the session flag is removed and we're done.
  */
 function save_data()
 {
     $rcmail = rcmail::get_instance();
     $identity = $rcmail->user->get_identity();
     $ident_level = intval($rcmail->config->get('identities_level', 0));
     $save_data = array('name' => rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST), 'email' => rcube_utils::get_input_value('_email', rcube_utils::INPUT_POST), 'organization' => rcube_utils::get_input_value('_organization', rcube_utils::INPUT_POST), 'signature' => rcube_utils::get_input_value('_signature', rcube_utils::INPUT_POST));
     // don't let the user alter the e-mail address if disabled by config
     if (in_array($ident_level, array(1, 3, 4))) {
         $save_data['email'] = $identity['email'];
     }
     if (empty($save_data['name']) || empty($save_data['email'])) {
         $rcmail->output->show_message('formincomplete', 'error');
     } else {
         if (!rcube_utils::check_email($save_data['email'] = rcube_utils::idn_to_ascii($save_data['email']))) {
             $rcmail->output->show_message('emailformaterror', 'error', array('email' => $save_data['email']));
         } else {
             // save data
             $rcmail->user->update_identity($identity['identity_id'], $save_data);
             $rcmail->session->remove('plugin.newuserdialog');
             // hide dialog
             $rcmail->output->command('new_user_dialog_close');
             $rcmail->output->show_message('successfullysaved', 'confirmation');
         }
     }
     $rcmail->output->send();
 }
 function lookup_user_name($args)
 {
     if ($this->init_ldap($args['host'])) {
         $results = $this->ldap->search('*', $args['user'], true);
         if (count($results->records) == 1) {
             $user_name = is_array($results->records[0]['name']) ? $results->records[0]['name'][0] : $results->records[0]['name'];
             $user_email = is_array($results->records[0]['email']) ? $results->records[0]['email'][0] : $results->records[0]['email'];
             $args['user_name'] = $user_name;
             $args['email_list'] = array();
             if (!$args['user_email'] && strpos($user_email, '@')) {
                 $args['user_email'] = rcube_utils::idn_to_ascii($user_email);
             }
             foreach (array_keys($results[0]) as $key) {
                 if (!preg_match('/^email($|:)/', $key)) {
                     continue;
                 }
                 foreach ((array) $results->records[0][$key] as $alias) {
                     if (strpos($alias, '@')) {
                         $args['email_list'][] = rcube_utils::idn_to_ascii($alias);
                     }
                 }
             }
         }
     }
     return $args;
 }
 public function create_identity($p)
 {
     $rcmail = rcmail::get_instance();
     // prefs are set in create_user()
     if ($this->prefs) {
         if ($this->prefs['full_name']) {
             $p['record']['name'] = $this->prefs['full_name'];
         }
         if (($this->identities_level == 0 || $this->identities_level == 2) && $this->prefs['email_address']) {
             $p['record']['email'] = $this->prefs['email_address'];
         }
         if ($this->prefs['___signature___']) {
             $p['record']['signature'] = $this->prefs['___signature___'];
         }
         if ($this->prefs['reply_to']) {
             $p['record']['reply-to'] = $this->prefs['reply_to'];
         }
         if (($this->identities_level == 0 || $this->identities_level == 1) && isset($this->prefs['identities']) && $this->prefs['identities'] > 1) {
             for ($i = 1; $i < $this->prefs['identities']; $i++) {
                 unset($ident_data);
                 $ident_data = array('name' => '', 'email' => '');
                 // required data
                 if ($this->prefs['full_name' . $i]) {
                     $ident_data['name'] = $this->prefs['full_name' . $i];
                 }
                 if ($this->identities_level == 0 && $this->prefs['email_address' . $i]) {
                     $ident_data['email'] = $this->prefs['email_address' . $i];
                 } else {
                     $ident_data['email'] = $p['record']['email'];
                 }
                 if ($this->prefs['reply_to' . $i]) {
                     $ident_data['reply-to'] = $this->prefs['reply_to' . $i];
                 }
                 if ($this->prefs['___sig' . $i . '___']) {
                     $ident_data['signature'] = $this->prefs['___sig' . $i . '___'];
                 }
                 // insert identity
                 $rcmail->user->insert_identity($ident_data);
             }
         }
         // copy address book
         $contacts = $rcmail->get_address_book(null, true);
         if ($contacts && count($this->abook)) {
             foreach ($this->abook as $rec) {
                 // #1487096 handle multi-address and/or too long items
                 $rec['email'] = array_shift(explode(';', $rec['email']));
                 if (rcube_utils::check_email(rcube_utils::idn_to_ascii($rec['email']))) {
                     $rec['email'] = rcube_utils::idn_to_utf8($rec['email']);
                     $contacts->insert($rec, true);
                 }
             }
         }
         // mark identity as complete for following hooks
         $p['complete'] = true;
     }
     return $p;
 }
 function lookup_user_name($args)
 {
     if ($this->init_ldap($args['host'])) {
         $results = $this->ldap->search('*', $args['user'], true);
         if (count($results->records) == 1) {
             $user_name = is_array($results->records[0]['name']) ? $results->records[0]['name'][0] : $results->records[0]['name'];
             $user_email = is_array($results->records[0]['email']) ? $results->records[0]['email'][0] : $results->records[0]['email'];
             $args['user_name'] = $user_name;
             if (!$args['user_email'] && strpos($user_email, '@')) {
                 $args['user_email'] = rcube_utils::idn_to_ascii($user_email);
             }
         }
     }
     return $args;
 }
示例#6
0
 /**
  * User > Email
  */
 function user2email($p)
 {
     $r = $this->findinvirtual('/\\s' . preg_quote($p['user'], '/') . '\\s*$/');
     $result = array();
     for ($i = 0; $i < count($r); $i++) {
         $arr = preg_split('/\\s+/', $r[$i]);
         if (count($arr) > 0 && strpos($arr[0], '@')) {
             $result[] = rcube_utils::idn_to_ascii(trim(str_replace('\\@', '@', $arr[0])));
             if ($p['first']) {
                 $p['email'] = $result[0];
                 break;
             }
         }
     }
     $p['email'] = empty($result) ? NULL : $result;
     return $p;
 }
示例#7
0
 /**
  * User > Email
  */
 function user2email($p)
 {
     $dbh = $this->get_dbh();
     $sql_result = $dbh->query(preg_replace('/%u/', $dbh->escape($p['user']), $this->config['email']));
     while ($sql_arr = $dbh->fetch_array($sql_result)) {
         if (strpos($sql_arr[0], '@')) {
             if ($p['extended'] && count($sql_arr) > 1) {
                 $result[] = array('email' => rcube_utils::idn_to_ascii($sql_arr[0]), 'name' => (string) $sql_arr[1], 'organization' => (string) $sql_arr[2], 'reply-to' => (string) rcube_utils::idn_to_ascii($sql_arr[3]), 'bcc' => (string) rcube_utils::idn_to_ascii($sql_arr[4]), 'signature' => (string) $sql_arr[5], 'html_signature' => (int) $sql_arr[6]);
             } else {
                 $result[] = $sql_arr[0];
             }
             if ($p['first']) {
                 break;
             }
         }
     }
     $p['email'] = $result;
     return $p;
 }
 /**
  * Authenticate hook handler
  */
 function authenticate($args)
 {
     if (!empty($_SERVER['REMOTE_USER']) && !empty($_SERVER['KRB5CCNAME'])) {
         // Load plugin's config file
         $this->load_config();
         $rcmail = rcmail::get_instance();
         $host = $rcmail->config->get('krb_authentication_host');
         if (is_string($host) && trim($host) !== '' && empty($args['host'])) {
             $args['host'] = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
         }
         if (!empty($_SERVER['REMOTE_USER'])) {
             $args['user'] = $_SERVER['REMOTE_USER'];
             $args['pass'] = null;
         }
         $args['cookiecheck'] = false;
         $args['valid'] = true;
     }
     return $args;
 }
 function authenticate($args)
 {
     // Load plugin's config file
     $this->load_config();
     $host = rcmail::get_instance()->config->get('http_authentication_host');
     if (is_string($host) && trim($host) !== '' && empty($args['host'])) {
         $args['host'] = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
     }
     // Allow entering other user data in login form,
     // e.g. after log out (#1487953)
     if (!empty($args['user'])) {
         return $args;
     }
     if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
         $args['user'] = $_SERVER['PHP_AUTH_USER'];
         $args['pass'] = $_SERVER['PHP_AUTH_PW'];
     }
     $args['cookiecheck'] = false;
     $args['valid'] = true;
     return $args;
 }
 function user2email($params)
 {
     $this->log_msg('Search email for user: '******'user']);
     if ($this->init_ldap()) {
         foreach ($this->ldap->search('*', $params['user'], 1)->records as $record) {
             $email = rcube_utils::idn_to_ascii(self::record_attr('email', $record));
             $this->log_msg("Found email: {$email}");
             if ($params['extended']) {
                 $params['email'][] = array('email' => $email, 'name' => self::record_attr('name', $record), 'organization' => self::record_attr('organization', $record));
             } else {
                 $params['email'][] = $email;
             }
             if ($params['first']) {
                 break;
             }
         }
     }
     if (!$params['email']) {
         $this->log_msg('No email found');
     }
     return $params;
 }
示例#11
0
 /**
  * Return the mail domain configured for the given host
  *
  * @param string  $host   IMAP host
  * @param boolean $encode If true, domain name will be converted to IDN ASCII
  *
  * @return string Resolved SMTP host
  */
 public function mail_domain($host, $encode = true)
 {
     $domain = $host;
     if (is_array($this->prop['mail_domain'])) {
         if (isset($this->prop['mail_domain'][$host])) {
             $domain = $this->prop['mail_domain'][$host];
         }
     } else {
         if (!empty($this->prop['mail_domain'])) {
             $domain = rcube_utils::parse_host($this->prop['mail_domain']);
         }
     }
     if ($encode) {
         $domain = rcube_utils::idn_to_ascii($domain);
     }
     return $domain;
 }
 /**
  * Loads configuration, initializes plugin (including sieve connection)
  */
 function start($mode = null)
 {
     // register UI objects
     $this->rc->output->add_handlers(array('filterslist' => array($this, 'filters_list'), 'filtersetslist' => array($this, 'filtersets_list'), 'filterframe' => array($this, 'filter_frame'), 'filterform' => array($this, 'filter_form'), 'filtersetform' => array($this, 'filterset_form')));
     // Get connection parameters
     $host = $this->rc->config->get('managesieve_host', 'localhost');
     $port = $this->rc->config->get('managesieve_port');
     $tls = $this->rc->config->get('managesieve_usetls', false);
     $host = rcube_utils::parse_host($host);
     $host = rcube_utils::idn_to_ascii($host);
     // remove tls:// prefix, set TLS flag
     if (($host = preg_replace('|^tls://|i', '', $host, 1, $cnt)) && $cnt) {
         $tls = true;
     }
     if (empty($port)) {
         $port = getservbyname('sieve', 'tcp');
         if (empty($port)) {
             $port = self::PORT;
         }
     }
     $plugin = $this->rc->plugins->exec_hook('managesieve_connect', array('user' => $_SESSION['username'], 'password' => $this->rc->decrypt($_SESSION['password']), 'host' => $host, 'port' => $port, 'usetls' => $tls, 'auth_type' => $this->rc->config->get('managesieve_auth_type'), 'disabled' => $this->rc->config->get('managesieve_disabled_extensions'), 'debug' => $this->rc->config->get('managesieve_debug', false), 'auth_cid' => $this->rc->config->get('managesieve_auth_cid'), 'auth_pw' => $this->rc->config->get('managesieve_auth_pw')));
     // try to connect to managesieve server and to fetch the script
     $this->sieve = new rcube_sieve($plugin['user'], $plugin['password'], $plugin['host'], $plugin['port'], $plugin['auth_type'], $plugin['usetls'], $plugin['disabled'], $plugin['debug'], $plugin['auth_cid'], $plugin['auth_pw']);
     if (!($error = $this->sieve->error())) {
         // Get list of scripts
         $list = $this->list_scripts();
         // reset current script when entering filters UI (#1489412)
         if ($this->rc->action == 'plugin.managesieve') {
             $this->rc->session->remove('managesieve_current');
         }
         if ($mode != 'vacation') {
             if (!empty($_GET['_set']) || !empty($_POST['_set'])) {
                 $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
             } else {
                 if (!empty($_SESSION['managesieve_current'])) {
                     $script_name = $_SESSION['managesieve_current'];
                 }
             }
         }
         if ($script_name === null || $script_name === '') {
             // get (first) active script
             if (!empty($this->active[0])) {
                 $script_name = $this->active[0];
             } else {
                 if ($list) {
                     $script_name = $list[0];
                 } else {
                     // if script not exists build default script contents
                     $script_file = $this->rc->config->get('managesieve_default');
                     $script_name = $this->rc->config->get('managesieve_script_name');
                     if (empty($script_name)) {
                         $script_name = 'roundcube';
                     }
                     if ($script_file && is_readable($script_file)) {
                         $content = file_get_contents($script_file);
                     }
                     // add script and set it active
                     if ($this->sieve->save_script($script_name, $content)) {
                         $this->activate_script($script_name);
                         $this->list[] = $script_name;
                     }
                 }
             }
         }
         if ($script_name) {
             $this->sieve->load($script_name);
         }
         $error = $this->sieve->error();
     }
     // finally set script objects
     if ($error) {
         switch ($error) {
             case SIEVE_ERROR_CONNECTION:
             case SIEVE_ERROR_LOGIN:
                 $this->rc->output->show_message('managesieve.filterconnerror', 'error');
                 rcube::raise_error(array('code' => 403, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Unable to connect to managesieve on {$host}:{$port}"), true, false);
                 break;
             default:
                 $this->rc->output->show_message('managesieve.filterunknownerror', 'error');
                 break;
         }
         // reload interface in case of possible error when specified script wasn't found (#1489412)
         if ($script_name !== null && !empty($list) && !in_array($script_name, $list)) {
             $this->rc->output->command('reload', 500);
         }
         // to disable 'Add filter' button set env variable
         $this->rc->output->set_env('filterconnerror', true);
         $this->script = array();
     } else {
         $this->exts = $this->sieve->get_extensions();
         $this->init_script();
         $this->rc->output->set_env('currentset', $this->sieve->current);
         $_SESSION['managesieve_current'] = $this->sieve->current;
     }
     return $error;
 }
示例#13
0
文件: acl.php 项目: BIGGANI/zpanelx
 /**
  * Handler for ACL update/create action
  */
 private function action_save()
 {
     $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true));
     // UTF7-IMAP
     $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_GPC));
     $acl = trim(rcube_utils::get_input_value('_acl', rcube_utils::INPUT_GPC));
     $oldid = trim(rcube_utils::get_input_value('_old', rcube_utils::INPUT_GPC));
     $acl = array_intersect(str_split($acl), $this->rights_supported());
     $users = $oldid ? array($user) : explode(',', $user);
     $result = 0;
     foreach ($users as $user) {
         $user = trim($user);
         if (!empty($this->specials) && in_array($user, $this->specials)) {
             $username = $this->gettext($user);
         } else {
             if (!empty($user)) {
                 if (!strpos($user, '@') && ($realm = $this->get_realm())) {
                     $user .= '@' . rcube_utils::idn_to_ascii(preg_replace('/^@/', '', $realm));
                 }
                 $username = $user;
             }
         }
         if (!$acl || !$user || !strlen($mbox)) {
             continue;
         }
         $user = $this->mod_login($user);
         $username = $this->mod_login($username);
         if ($user != $_SESSION['username'] && $username != $_SESSION['username']) {
             if ($this->rc->storage->set_acl($mbox, $user, $acl)) {
                 $ret = array('id' => rcube_utils::html_identifier($user), 'username' => $username, 'acl' => implode($acl), 'old' => $oldid);
                 $this->rc->output->command('acl_update', $ret);
                 $result++;
             }
         }
     }
     if ($result) {
         $this->rc->output->show_message($oldid ? 'acl.updatesuccess' : 'acl.createsuccess', 'confirmation');
     } else {
         $this->rc->output->show_message($oldid ? 'acl.updateerror' : 'acl.createerror', 'error');
     }
 }
示例#14
0
 /**
  * Perfom login to the mail server and to the webmail service.
  * This will also create a new user entry if auto_create_user is configured.
  *
  * @param string Mail storage (IMAP) user name
  * @param string Mail storage (IMAP) password
  * @param string Mail storage (IMAP) host
  *
  * @return boolean True on success, False on failure
  */
 function login($username, $pass, $host = NULL)
 {
     if (empty($username)) {
         return false;
     }
     $config = $this->config->all();
     if (!$host) {
         $host = $config['default_host'];
     }
     // Validate that selected host is in the list of configured hosts
     if (is_array($config['default_host'])) {
         $allowed = false;
         foreach ($config['default_host'] as $key => $host_allowed) {
             if (!is_numeric($key)) {
                 $host_allowed = $key;
             }
             if ($host == $host_allowed) {
                 $allowed = true;
                 break;
             }
         }
         if (!$allowed) {
             return false;
         }
     } else {
         if (!empty($config['default_host']) && $host != rcube_utils::parse_host($config['default_host'])) {
             return false;
         }
     }
     // parse $host URL
     $a_host = parse_url($host);
     if ($a_host['host']) {
         $host = $a_host['host'];
         $ssl = isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl', 'imaps', 'tls')) ? $a_host['scheme'] : null;
         if (!empty($a_host['port'])) {
             $port = $a_host['port'];
         } else {
             if ($ssl && $ssl != 'tls' && (!$config['default_port'] || $config['default_port'] == 143)) {
                 $port = 993;
             }
         }
     }
     if (!$port) {
         $port = $config['default_port'];
     }
     /* Modify username with domain if required
           Inspired by Marco <P0L0_notspam_binware.org>
        */
     // Check if we need to add domain
     if (!empty($config['username_domain']) && strpos($username, '@') === false) {
         if (is_array($config['username_domain']) && isset($config['username_domain'][$host])) {
             $username .= '@' . rcube_utils::parse_host($config['username_domain'][$host], $host);
         } else {
             if (is_string($config['username_domain'])) {
                 $username .= '@' . rcube_utils::parse_host($config['username_domain'], $host);
             }
         }
     }
     // Convert username to lowercase. If storage backend
     // is case-insensitive we need to store always the same username (#1487113)
     if ($config['login_lc']) {
         $username = mb_strtolower($username);
     }
     // try to resolve email address from virtuser table
     if (strpos($username, '@') && ($virtuser = rcube_user::email2user($username))) {
         $username = $virtuser;
     }
     // Here we need IDNA ASCII
     // Only rcube_contacts class is using domain names in Unicode
     $host = rcube_utils::idn_to_ascii($host);
     if (strpos($username, '@')) {
         // lowercase domain name
         list($local, $domain) = explode('@', $username);
         $username = $local . '@' . mb_strtolower($domain);
         $username = rcube_utils::idn_to_ascii($username);
     }
     // user already registered -> overwrite username
     if ($user = rcube_user::query($username, $host)) {
         $username = $user->data['username'];
     }
     $storage = $this->get_storage();
     // try to log in
     if (!($login = $storage->connect($host, $username, $pass, $port, $ssl))) {
         // try with lowercase
         $username_lc = mb_strtolower($username);
         if ($username_lc != $username) {
             // try to find user record again -> overwrite username
             if (!$user && ($user = rcube_user::query($username_lc, $host))) {
                 $username_lc = $user->data['username'];
             }
             if ($login = $storage->connect($host, $username_lc, $pass, $port, $ssl)) {
                 $username = $username_lc;
             }
         }
     }
     // exit if login failed
     if (!$login) {
         return false;
     }
     // user already registered -> update user's record
     if (is_object($user)) {
         // update last login timestamp
         $user->touch();
     } else {
         if ($config['auto_create_user']) {
             if ($created = rcube_user::create($username, $host)) {
                 $user = $created;
             } else {
                 self::raise_error(array('code' => 620, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Failed to create a user record. Maybe aborted by a plugin?"), true, false);
             }
         } else {
             self::raise_error(array('code' => 621, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Access denied for new user {$username}. 'auto_create_user' is disabled"), true, false);
         }
     }
     // login succeeded
     if (is_object($user) && $user->ID) {
         // Configure environment
         $this->set_user($user);
         $this->set_storage_prop();
         $this->session_configure();
         // fix some old settings according to namespace prefix
         $this->fix_namespace_settings($user);
         // create default folders on first login
         if ($config['create_default_folders'] && (!empty($created) || empty($user->data['last_login']))) {
             $storage->create_default_folders();
         }
         // set session vars
         $_SESSION['user_id'] = $user->ID;
         $_SESSION['username'] = $user->data['username'];
         $_SESSION['storage_host'] = $host;
         $_SESSION['storage_port'] = $port;
         $_SESSION['storage_ssl'] = $ssl;
         $_SESSION['password'] = $this->encrypt($pass);
         $_SESSION['login_time'] = time();
         if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_') {
             $_SESSION['timezone'] = floatval($_REQUEST['_timezone']);
         }
         if (isset($_REQUEST['_dstactive']) && $_REQUEST['_dstactive'] != '_default_') {
             $_SESSION['dst_active'] = intval($_REQUEST['_dstactive']);
         }
         // force reloading complete list of subscribed mailboxes
         $storage->clear_cache('mailboxes', true);
         return true;
     }
     return false;
 }
示例#15
0
 /**
  * Establish a connection to the LDAP server
  */
 private function _connect()
 {
     $rcube = rcube::get_instance();
     if (!function_exists('ldap_connect')) {
         rcube::raise_error(array('code' => 100, 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "No ldap support in this installation of PHP"), true, true);
     }
     if (is_resource($this->conn)) {
         return true;
     }
     if (!is_array($this->prop['hosts'])) {
         $this->prop['hosts'] = array($this->prop['hosts']);
     }
     if (empty($this->prop['ldap_version'])) {
         $this->prop['ldap_version'] = 3;
     }
     foreach ($this->prop['hosts'] as $host) {
         $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
         $hostname = $host . ($this->prop['port'] ? ':' . $this->prop['port'] : '');
         $this->_debug("C: Connect [{$hostname}] [{$this->prop['name']}]");
         if ($lc = @ldap_connect($host, $this->prop['port'])) {
             if ($this->prop['use_tls'] === true) {
                 if (!ldap_start_tls($lc)) {
                     continue;
                 }
             }
             $this->_debug("S: OK");
             ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->prop['ldap_version']);
             $this->prop['host'] = $host;
             $this->conn = $lc;
             if (isset($this->prop['referrals'])) {
                 ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->prop['referrals']);
             }
             break;
         }
         $this->_debug("S: NOT OK");
     }
     // See if the directory is writeable.
     if ($this->prop['writable']) {
         $this->readonly = false;
     }
     if (!is_resource($this->conn)) {
         rcube::raise_error(array('code' => 100, 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Could not connect to any LDAP server, last tried {$hostname}"), true);
         return false;
     }
     $bind_pass = $this->prop['bind_pass'];
     $bind_user = $this->prop['bind_user'];
     $bind_dn = $this->prop['bind_dn'];
     $this->base_dn = $this->prop['base_dn'];
     $this->groups_base_dn = $this->prop['groups']['base_dn'] ? $this->prop['groups']['base_dn'] : $this->base_dn;
     // User specific access, generate the proper values to use.
     if ($this->prop['user_specific']) {
         // No password set, use the session password
         if (empty($bind_pass)) {
             $bind_pass = $rcube->decrypt($_SESSION['password']);
         }
         // Get the pieces needed for variable replacement.
         if ($fu = $rcube->get_user_name()) {
             list($u, $d) = explode('@', $fu);
         } else {
             $d = $this->mail_domain;
         }
         $dc = 'dc=' . strtr($d, array('.' => ',dc='));
         // hierarchal domain string
         $replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u);
         if ($this->prop['search_base_dn'] && $this->prop['search_filter']) {
             if (!empty($this->prop['search_bind_dn']) && !empty($this->prop['search_bind_pw'])) {
                 $this->bind($this->prop['search_bind_dn'], $this->prop['search_bind_pw']);
             }
             // Search for the dn to use to authenticate
             $this->prop['search_base_dn'] = strtr($this->prop['search_base_dn'], $replaces);
             $this->prop['search_filter'] = strtr($this->prop['search_filter'], $replaces);
             $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}");
             $res = @ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid'));
             if ($res) {
                 if (($entry = ldap_first_entry($this->conn, $res)) && ($bind_dn = ldap_get_dn($this->conn, $entry))) {
                     $this->_debug("S: search returned dn: {$bind_dn}");
                     $dn = ldap_explode_dn($bind_dn, 1);
                     $replaces['%dn'] = $dn[0];
                 }
             } else {
                 $this->_debug("S: " . ldap_error($this->conn));
             }
             // DN not found
             if (empty($replaces['%dn'])) {
                 if (!empty($this->prop['search_dn_default'])) {
                     $replaces['%dn'] = $this->prop['search_dn_default'];
                 } else {
                     rcube::raise_error(array('code' => 100, 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "DN not found using LDAP search."), true);
                     return false;
                 }
             }
         }
         // Replace the bind_dn and base_dn variables.
         $bind_dn = strtr($bind_dn, $replaces);
         $this->base_dn = strtr($this->base_dn, $replaces);
         $this->groups_base_dn = strtr($this->groups_base_dn, $replaces);
         if (empty($bind_user)) {
             $bind_user = $u;
         }
     }
     if (empty($bind_pass)) {
         $this->ready = true;
     } else {
         if (!empty($bind_dn)) {
             $this->ready = $this->bind($bind_dn, $bind_pass);
         } else {
             if (!empty($this->prop['auth_cid'])) {
                 $this->ready = $this->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
             } else {
                 $this->ready = $this->sasl_bind($bind_user, $bind_pass);
             }
         }
     }
     return $this->ready;
 }
示例#16
0
 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;
     }
     // new password - default hash method
     if (strpos($sql, '%P') !== false) {
         $password = password::hash_password($passwd);
         if ($password === false) {
             return PASSWORD_CRYPT_ERROR;
         }
         $sql = str_replace('%P', $db->quote($password), $sql);
     }
     // old password - default hash method
     if (strpos($sql, '%O') !== false) {
         $password = password::hash_password($curpass);
         if ($password === false) {
             return PASSWORD_CRYPT_ERROR;
         }
         $sql = str_replace('%O', $db->quote($password), $sql);
     }
     // crypted password (deprecated, use %P)
     if (strpos($sql, '%c') !== false) {
         $password = password::hash_password($passwd, 'crypt', false);
         if ($password === false) {
             return PASSWORD_CRYPT_ERROR;
         }
         $sql = str_replace('%c', $db->quote($password), $sql);
     }
     // dovecotpw (deprecated, use %P)
     if (strpos($sql, '%D') !== false) {
         $password = password::hash_password($passwd, 'dovecot', false);
         if ($password === false) {
             return PASSWORD_CRYPT_ERROR;
         }
         $sql = str_replace('%D', $db->quote($password), $sql);
     }
     // hashed passwords (deprecated, use %P)
     if (strpos($sql, '%n') !== false) {
         $password = password::hash_password($passwd, 'hash', false);
         if ($password === false) {
             return PASSWORD_CRYPT_ERROR;
         }
         $sql = str_replace('%n', $db->quote($password, 'text'), $sql);
     }
     // hashed passwords (deprecated, use %P)
     if (strpos($sql, '%q') !== false) {
         $password = password::hash_password($curpass, 'hash', false);
         if ($password === false) {
             return PASSWORD_CRYPT_ERROR;
         }
         $sql = str_replace('%q', $db->quote($password, '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;
 }
 protected function _startup()
 {
     $rcmail = rcube::get_instance();
     if (!$this->sieve) {
         // Add include path for internal classes
         $include_path = $this->home . '/lib' . PATH_SEPARATOR;
         $include_path .= ini_get('include_path');
         set_include_path($include_path);
         // try to connect to managesieve server and to fetch the script
         $this->sieve = new rcube_sieve($_SESSION['username'], $rcmail->decrypt($_SESSION['password']), rcube_utils::idn_to_ascii(rcube_utils::parse_host($rcmail->config->get('sieverules_host'))), $rcmail->config->get('sieverules_port'), $rcmail->config->get('sieverules_auth_type', NULL), $rcmail->config->get('sieverules_usetls'), $this->current_ruleset, $this->home, $rcmail->config->get('sieverules_use_elsif', true), $rcmail->config->get('sieverules_auth_cid', NULL), $rcmail->config->get('sieverules_auth_pw', NULL), $rcmail->config->get('sieverules_conn_options', NULL));
         if ($rcmail->config->get('sieverules_debug', false)) {
             $this->sieve->set_debug(true);
         }
         $this->sieve_error = $this->sieve->error();
         if ($this->sieve_error == SIEVE_ERROR_NOT_EXISTS) {
             // load default rule set
             if ($this->_get_rule_file($rcmail->config->get('sieverules_default_file')) || sizeof($this->sieve->list) > 0) {
                 $rcmail->overwrite_action('plugin.sieverules.setup');
                 $this->action = 'plugin.sieverules.setup';
             }
             // that's not exactly an error
             $this->sieve_error = false;
         } elseif ($this->sieve_error) {
             switch ($this->sieve_error) {
                 case SIEVE_ERROR_CONNECTION:
                 case SIEVE_ERROR_LOGIN:
                     $this->api->output->command('display_message', $this->gettext('filterconnerror'), 'error');
                     break;
                 default:
                     $this->api->output->command('display_message', $this->gettext('filterunknownerror'), 'error');
                     break;
             }
             $this->api->output->set_env('sieveruleserror', true);
         }
         // finally set script objects
         if ($this->sieve_error) {
             $this->script = array();
         } else {
             $this->script = $this->sieve->script->as_array();
             // load example filters
             $this->examples = $this->_get_rule_file($rcmail->config->get('sieverules_example_file'), true);
         }
     } else {
         $this->sieve->set_ruleset($this->current_ruleset);
         $this->script = $this->sieve->script->as_array();
     }
 }
示例#18
0
function rcube_idn_to_ascii($str)
{
    _deprecation_warning(__FUNCTION__);
    return rcube_utils::idn_to_ascii($str);
}
示例#19
0
 /**
  * Establish a connection to the LDAP server
  */
 public function connect($host = null)
 {
     if (!function_exists('ldap_connect')) {
         rcube::raise_error(array('code' => 100, 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "No ldap support in this installation of PHP"), true);
         return false;
     }
     if (is_resource($this->conn) && $this->config['host'] == $host) {
         return true;
     }
     if (empty($this->config['ldap_version'])) {
         $this->config['ldap_version'] = 3;
     }
     // iterate over hosts if none specified
     if (!$host) {
         if (!is_array($this->config['hosts'])) {
             $this->config['hosts'] = array($this->config['hosts']);
         }
         foreach ($this->config['hosts'] as $host) {
             if ($this->connect($host)) {
                 return true;
             }
         }
         return false;
     }
     // open connection to the given $host
     $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
     $hostname = $host . ($this->config['port'] ? ':' . $this->config['port'] : '');
     $this->_debug("C: Connect to {$hostname} [{$this->config['name']}]");
     if ($lc = @ldap_connect($host, $this->config['port'])) {
         if ($this->config['use_tls'] === true) {
             if (!ldap_start_tls($lc)) {
                 return false;
             }
         }
         $this->_debug("S: OK");
         ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->config['ldap_version']);
         $this->config['host'] = $host;
         $this->conn = $lc;
         if (!empty($this->config['network_timeout'])) {
             ldap_set_option($lc, LDAP_OPT_NETWORK_TIMEOUT, $this->config['network_timeout']);
         }
         if (isset($this->config['referrals'])) {
             ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->config['referrals']);
         }
         if (isset($this->config['dereference'])) {
             ldap_set_option($lc, LDAP_OPT_DEREF, $this->config['dereference']);
         }
     } else {
         $this->_debug("S: NOT OK");
     }
     if (!is_resource($this->conn)) {
         rcube::raise_error(array('code' => 100, 'type' => 'ldap', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Could not connect to any LDAP server, last tried {$hostname}"), true);
         return false;
     }
     return true;
 }
示例#20
0
function rcube_idn_to_ascii($str)
{
    return rcube_utils::idn_to_ascii($str);
}
 private function _startup()
 {
     $rcmail = rcube::get_instance();
     if (!$this->sieve) {
         include 'lib/Net/Sieve.php';
         include 'include/rcube_sieve.php';
         include 'include/rcube_sieve_script.php';
         $rcmail = rcube::get_instance();
         // try to connect to managesieve server and to fetch the script
         $this->sieve = new rcube_sieve($_SESSION['username'], $rcmail->decrypt($_SESSION['password']), rcube_utils::idn_to_ascii(rcube_utils::parse_host($rcmail->config->get('sieverules_host'))), $rcmail->config->get('sieverules_port'), $rcmail->config->get('sieverules_auth_type', NULL), $rcmail->config->get('sieverules_usetls'), $this->current_ruleset, $this->home, $rcmail->config->get('sieverules_use_elsif', true), $rcmail->config->get('sieverules_auth_cid', NULL), $rcmail->config->get('sieverules_auth_pw', NULL));
         if ($rcmail->config->get('sieverules_debug', false)) {
             $this->sieve->set_debug(true);
         }
         $this->sieve_error = $this->sieve->error();
         if ($this->sieve_error == SIEVE_ERROR_NOT_EXISTS) {
             // load default rule set
             if ($rcmail->config->get('sieverules_default_file', false) && is_readable($rcmail->config->get('sieverules_default_file')) || sizeof($this->sieve->list) > 0) {
                 $rcmail->overwrite_action('plugin.sieverules.setup');
                 $this->action = 'plugin.sieverules.setup';
             } elseif ($rcmail->config->get('sieverules_default_file', false) && !is_readable($rcmail->config->get('sieverules_default_file'))) {
                 rcube::raise_error(array('code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "SieveRules plugin: Unable to open default rule file"), true, false);
             }
             // that's not exactly an error
             $this->sieve_error = false;
         } elseif ($this->sieve_error) {
             switch ($this->sieve_error) {
                 case SIEVE_ERROR_CONNECTION:
                 case SIEVE_ERROR_LOGIN:
                     $this->api->output->command('display_message', $this->gettext('filterconnerror'), 'error');
                     break;
                 default:
                     $this->api->output->command('display_message', $this->gettext('filterunknownerror'), 'error');
                     break;
             }
             $this->api->output->set_env('sieveruleserror', true);
         }
         // finally set script objects
         if ($this->sieve_error) {
             $this->script = array();
         } else {
             $this->script = $this->sieve->script->as_array();
             // load example filters
             if ($rcmail->config->get('sieverules_example_file', false) && is_readable($rcmail->config->get('sieverules_example_file'))) {
                 $this->examples = $this->sieve->script->parse_text(file_get_contents($rcmail->config->get('sieverules_example_file')));
             } elseif ($rcmail->config->get('sieverules_example_file', false) && !is_readable($rcmail->config->get('sieverules_example_file'))) {
                 rcube::raise_error(array('code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "SieveRules plugin: Unable to open example rule file"), true, false);
             }
         }
     } else {
         $this->sieve->set_ruleset($this->current_ruleset);
         $this->script = $this->sieve->script->as_array();
     }
 }
示例#22
0
 /**
  * Perfom login to the mail server and to the webmail service.
  * This will also create a new user entry if auto_create_user is configured.
  *
  * @param string Mail storage (IMAP) user name
  * @param string Mail storage (IMAP) password
  * @param string Mail storage (IMAP) host
  * @param bool   Enables cookie check
  *
  * @return boolean True on success, False on failure
  */
 function login($username, $pass, $host = null, $cookiecheck = false)
 {
     $this->login_error = null;
     if (empty($username)) {
         return false;
     }
     if ($cookiecheck && empty($_COOKIE)) {
         $this->login_error = self::ERROR_COOKIES_DISABLED;
         return false;
     }
     $default_host = $this->config->get('default_host');
     $default_port = $this->config->get('default_port');
     $username_domain = $this->config->get('username_domain');
     $login_lc = $this->config->get('login_lc', 2);
     // host is validated in rcmail::autoselect_host(), so here
     // we'll only handle unset host (if possible)
     if (!$host && !empty($default_host)) {
         if (is_array($default_host)) {
             list($key, $val) = each($default_host);
             $host = is_numeric($key) ? $val : $key;
         } else {
             $host = $default_host;
         }
         $host = rcube_utils::parse_host($host);
     }
     if (!$host) {
         $this->login_error = self::ERROR_INVALID_HOST;
         return false;
     }
     // parse $host URL
     $a_host = parse_url($host);
     if ($a_host['host']) {
         $host = $a_host['host'];
         $ssl = isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl', 'imaps', 'tls')) ? $a_host['scheme'] : null;
         if (!empty($a_host['port'])) {
             $port = $a_host['port'];
         } else {
             if ($ssl && $ssl != 'tls' && (!$default_port || $default_port == 143)) {
                 $port = 993;
             }
         }
     }
     if (!$port) {
         $port = $default_port;
     }
     // Check if we need to add/force domain to username
     if (!empty($username_domain)) {
         $domain = is_array($username_domain) ? $username_domain[$host] : $username_domain;
         if ($domain = rcube_utils::parse_host((string) $domain, $host)) {
             $pos = strpos($username, '@');
             // force configured domains
             if ($pos !== false && $this->config->get('username_domain_forced')) {
                 $username = substr($username, 0, $pos) . '@' . $domain;
             } else {
                 if ($pos === false) {
                     $username .= '@' . $domain;
                 }
             }
         }
     }
     // Convert username to lowercase. If storage backend
     // is case-insensitive we need to store always the same username (#1487113)
     if ($login_lc) {
         if ($login_lc == 2 || $login_lc === true) {
             $username = mb_strtolower($username);
         } else {
             if (strpos($username, '@')) {
                 // lowercase domain name
                 list($local, $domain) = explode('@', $username);
                 $username = $local . '@' . mb_strtolower($domain);
             }
         }
     }
     // try to resolve email address from virtuser table
     if (strpos($username, '@') && ($virtuser = rcube_user::email2user($username))) {
         $username = $virtuser;
     }
     // Here we need IDNA ASCII
     // Only rcube_contacts class is using domain names in Unicode
     $host = rcube_utils::idn_to_ascii($host);
     $username = rcube_utils::idn_to_ascii($username);
     // user already registered -> overwrite username
     if ($user = rcube_user::query($username, $host)) {
         $username = $user->data['username'];
     }
     $storage = $this->get_storage();
     // try to log in
     if (!$storage->connect($host, $username, $pass, $port, $ssl)) {
         return false;
     }
     // user already registered -> update user's record
     if (is_object($user)) {
         // update last login timestamp
         $user->touch();
     } else {
         if ($this->config->get('auto_create_user')) {
             if ($created = rcube_user::create($username, $host)) {
                 $user = $created;
             } else {
                 self::raise_error(array('code' => 620, 'file' => __FILE__, 'line' => __LINE__, 'message' => "Failed to create a user record. Maybe aborted by a plugin?"), true, false);
             }
         } else {
             self::raise_error(array('code' => 621, 'file' => __FILE__, 'line' => __LINE__, 'message' => "Access denied for new user {$username}. 'auto_create_user' is disabled"), true, false);
         }
     }
     // login succeeded
     if (is_object($user) && $user->ID) {
         // Configure environment
         $this->set_user($user);
         $this->set_storage_prop();
         // set session vars
         $_SESSION['user_id'] = $user->ID;
         $_SESSION['username'] = $user->data['username'];
         $_SESSION['storage_host'] = $host;
         $_SESSION['storage_port'] = $port;
         $_SESSION['storage_ssl'] = $ssl;
         $_SESSION['password'] = $this->encrypt($pass);
         $_SESSION['login_time'] = time();
         if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_') {
             $_SESSION['timezone'] = rcube_utils::get_input_value('_timezone', rcube_utils::INPUT_GPC);
         }
         // fix some old settings according to namespace prefix
         $this->fix_namespace_settings($user);
         // set/create special folders
         $this->set_special_folders();
         // clear all mailboxes related cache(s)
         $storage->clear_cache('mailboxes', true);
         return true;
     }
     return false;
 }
 public function create_identity($p)
 {
     $rcmail = rcmail::get_instance();
     // prefs are set in create_user()
     if ($this->prefs) {
         if ($this->prefs['full_name']) {
             $p['record']['name'] = $this->prefs['full_name'];
         }
         if (($this->identities_level == 0 || $this->identities_level == 2) && $this->prefs['email_address']) {
             $p['record']['email'] = $this->prefs['email_address'];
         }
         if ($this->prefs['___signature___']) {
             $p['record']['signature'] = $this->prefs['___signature___'];
         }
         if ($this->prefs['reply_to']) {
             $p['record']['reply-to'] = $this->prefs['reply_to'];
         }
         if (($this->identities_level == 0 || $this->identities_level == 1) && isset($this->prefs['identities']) && $this->prefs['identities'] > 1) {
             for ($i = 1; $i < $this->prefs['identities']; $i++) {
                 unset($ident_data);
                 $ident_data = array('name' => '', 'email' => '');
                 // required data
                 if ($this->prefs['full_name' . $i]) {
                     $ident_data['name'] = $this->prefs['full_name' . $i];
                 }
                 if ($this->identities_level == 0 && $this->prefs['email_address' . $i]) {
                     $ident_data['email'] = $this->prefs['email_address' . $i];
                 } else {
                     $ident_data['email'] = $p['record']['email'];
                 }
                 if ($this->prefs['reply_to' . $i]) {
                     $ident_data['reply-to'] = $this->prefs['reply_to' . $i];
                 }
                 if ($this->prefs['___sig' . $i . '___']) {
                     $ident_data['signature'] = $this->prefs['___sig' . $i . '___'];
                 }
                 // insert identity
                 $rcmail->user->insert_identity($ident_data);
             }
         }
         // copy address book
         $contacts = $rcmail->get_address_book(null, true);
         $addresses = array();
         $groups = array();
         if ($contacts && !empty($this->abook)) {
             foreach ($this->abook as $rec) {
                 // #1487096: handle multi-address and/or too long items
                 // #1487858: convert multi-address contacts into groups
                 $emails = preg_split('/[;,]/', $rec['email'], -1, PREG_SPLIT_NO_EMPTY);
                 $group_id = null;
                 // create group for addresses
                 if (count($emails) > 1) {
                     if (!($group_id = $groups[$rec['name']])) {
                         if ($group = $contacts->create_group($rec['name'])) {
                             $group_id = $group['id'];
                             $groups[$rec['name']] = $group_id;
                         }
                     }
                 }
                 // create contacts
                 foreach ($emails as $email) {
                     if (!($contact_id = $addresses[$email]) && rcube_utils::check_email(rcube_utils::idn_to_ascii($email))) {
                         $rec['email'] = rcube_utils::idn_to_utf8($email);
                         if ($contact_id = $contacts->insert($rec, true)) {
                             $addresses[$email] = $contact_id;
                         }
                     }
                     if ($group_id && $contact_id) {
                         $contacts->add_to_group($group_id, array($contact_id));
                     }
                 }
             }
         }
         // mark identity as complete for following hooks
         $p['complete'] = true;
     }
     return $p;
 }
示例#24
0
 /**
  * Check the given data before saving.
  * If input isn't valid, the message to display can be fetched using get_error()
  *
  * @param array Assoziative array with data to save
  * @param boolean Attempt to fix/complete record automatically
  * @return boolean True if input is valid, False if not.
  */
 public function validate(&$save_data, $autofix = false)
 {
     $rcube = rcube::get_instance();
     $valid = true;
     // check validity of email addresses
     foreach ($this->get_col_values('email', $save_data, true) as $email) {
         if (strlen($email)) {
             if (!rcube_utils::check_email(rcube_utils::idn_to_ascii($email))) {
                 $error = $rcube->gettext(array('name' => 'emailformaterror', 'vars' => array('email' => $email)));
                 $this->set_error(self::ERROR_VALIDATE, $error);
                 $valid = false;
                 break;
             }
         }
     }
     // allow plugins to do contact validation and auto-fixing
     $plugin = $rcube->plugins->exec_hook('contact_validate', array('record' => $save_data, 'autofix' => $autofix, 'valid' => $valid));
     if ($valid && !$plugin['valid']) {
         $this->set_error(self::ERROR_VALIDATE, $plugin['error']);
     }
     if (is_array($plugin['record'])) {
         $save_data = $plugin['record'];
     }
     return $plugin['valid'];
 }
示例#25
0
 /**
  * SMTP Connection and authentication
  *
  * @param string Server host
  * @param string Server port
  * @param string User name
  * @param string Password
  *
  * @return bool  Returns true on success, or false on error
  */
 public function connect($host = null, $port = null, $user = null, $pass = null)
 {
     $rcube = rcube::get_instance();
     // disconnect/destroy $this->conn
     $this->disconnect();
     // reset error/response var
     $this->error = $this->response = null;
     // let plugins alter smtp connection config
     $CONFIG = $rcube->plugins->exec_hook('smtp_connect', array('smtp_server' => $host ? $host : $rcube->config->get('smtp_server'), 'smtp_port' => $port ? $port : $rcube->config->get('smtp_port', 25), 'smtp_user' => $user ? $user : $rcube->config->get('smtp_user'), 'smtp_pass' => $pass ? $pass : $rcube->config->get('smtp_pass'), 'smtp_auth_cid' => $rcube->config->get('smtp_auth_cid'), 'smtp_auth_pw' => $rcube->config->get('smtp_auth_pw'), 'smtp_auth_type' => $rcube->config->get('smtp_auth_type'), 'smtp_helo_host' => $rcube->config->get('smtp_helo_host'), 'smtp_timeout' => $rcube->config->get('smtp_timeout'), 'smtp_auth_callbacks' => array()));
     $smtp_host = rcube_utils::parse_host($CONFIG['smtp_server']);
     // when called from Installer it's possible to have empty $smtp_host here
     if (!$smtp_host) {
         $smtp_host = 'localhost';
     }
     $smtp_port = is_numeric($CONFIG['smtp_port']) ? $CONFIG['smtp_port'] : 25;
     $smtp_host_url = parse_url($smtp_host);
     // overwrite port
     if (isset($smtp_host_url['host']) && isset($smtp_host_url['port'])) {
         $smtp_host = $smtp_host_url['host'];
         $smtp_port = $smtp_host_url['port'];
     }
     // re-write smtp host
     if (isset($smtp_host_url['host']) && isset($smtp_host_url['scheme'])) {
         $smtp_host = sprintf('%s://%s', $smtp_host_url['scheme'], $smtp_host_url['host']);
     }
     // remove TLS prefix and set flag for use in Net_SMTP::auth()
     if (preg_match('#^tls://#i', $smtp_host)) {
         $smtp_host = preg_replace('#^tls://#i', '', $smtp_host);
         $use_tls = true;
     }
     if (!empty($CONFIG['smtp_helo_host'])) {
         $helo_host = $CONFIG['smtp_helo_host'];
     } else {
         if (!empty($_SERVER['SERVER_NAME'])) {
             $helo_host = preg_replace('/:\\d+$/', '', $_SERVER['SERVER_NAME']);
         } else {
             $helo_host = 'localhost';
         }
     }
     // IDNA Support
     $smtp_host = rcube_utils::idn_to_ascii($smtp_host);
     $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
     if ($rcube->config->get('smtp_debug')) {
         $this->conn->setDebug(true, array($this, 'debug_handler'));
     }
     // register authentication methods
     if (!empty($CONFIG['smtp_auth_callbacks']) && method_exists($this->conn, 'setAuthMethod')) {
         foreach ($CONFIG['smtp_auth_callbacks'] as $callback) {
             $this->conn->setAuthMethod($callback['name'], $callback['function'], isset($callback['prepend']) ? $callback['prepend'] : true);
         }
     }
     // try to connect to server and exit on failure
     $result = $this->conn->connect($smtp_timeout);
     if (PEAR::isError($result)) {
         $this->response[] = "Connection failed: " . $result->getMessage();
         $this->error = array('label' => 'smtpconnerror', 'vars' => array('code' => $this->conn->_code));
         $this->conn = null;
         return false;
     }
     // workaround for timeout bug in Net_SMTP 1.5.[0-1] (#1487843)
     if (method_exists($this->conn, 'setTimeout') && ($timeout = ini_get('default_socket_timeout'))) {
         $this->conn->setTimeout($timeout);
     }
     $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']);
     $smtp_pass = str_replace('%p', $rcube->decrypt($_SESSION['password']), $CONFIG['smtp_pass']);
     $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
     if (!empty($CONFIG['smtp_auth_cid'])) {
         $smtp_authz = $smtp_user;
         $smtp_user = $CONFIG['smtp_auth_cid'];
         $smtp_pass = $CONFIG['smtp_auth_pw'];
     }
     // attempt to authenticate to the SMTP server
     if ($smtp_user && $smtp_pass) {
         // IDNA Support
         if (strpos($smtp_user, '@')) {
             $smtp_user = rcube_utils::idn_to_ascii($smtp_user);
         }
         $result = $this->conn->auth($smtp_user, $smtp_pass, $smtp_auth_type, $use_tls, $smtp_authz);
         if (PEAR::isError($result)) {
             $this->error = array('label' => 'smtpautherror', 'vars' => array('code' => $this->conn->_code));
             $this->response[] .= 'Authentication failure: ' . $result->getMessage() . ' (Code: ' . $result->getCode() . ')';
             $this->reset();
             $this->disconnect();
             return false;
         }
     }
     return true;
 }
示例#26
0
 /**
  * Check the given data before saving.
  * If input isn't valid, the message to display can be fetched using get_error()
  *
  * @param array Assoziative array with data to save
  * @param boolean Attempt to fix/complete record automatically
  * @return boolean True if input is valid, False if not.
  */
 public function validate(&$save_data, $autofix = false)
 {
     $rcmail = rcmail::get_instance();
     // check validity of email addresses
     foreach ($this->get_col_values('email', $save_data, true) as $email) {
         if (strlen($email)) {
             if (!rcube_utils::check_email(rcube_utils::idn_to_ascii($email))) {
                 $error = $rcmail->gettext(array('name' => 'emailformaterror', 'vars' => array('email' => $email)));
                 $this->set_error(self::ERROR_VALIDATE, $error);
                 return false;
             }
         }
     }
     return true;
 }
 /**
  * Helper function to build a Mail_mime object to send an iTip message
  *
  * @param array   Event object to send
  * @param string  iTip method (REQUEST|REPLY|CANCEL)
  * @param boolean Request RSVP
  * @return object Mail_mime object with message data
  */
 public function compose_itip_message($event, $method, $rsvp = true)
 {
     $from = rcube_utils::idn_to_ascii($this->sender['email']);
     $from_utf = rcube_utils::idn_to_utf8($from);
     $sender = format_email_recipient($from, $this->sender['name']);
     // truncate list attendees down to the recipient of the iTip Reply.
     // constraints for a METHOD:REPLY according to RFC 5546
     if ($method == 'REPLY') {
         $replying_attendee = null;
         $reply_attendees = array();
         foreach ($event['attendees'] as $attendee) {
             if ($attendee['role'] == 'ORGANIZER') {
                 $reply_attendees[] = $attendee;
             } else {
                 if (strcasecmp($attendee['email'], $from) == 0 || strcasecmp($attendee['email'], $from_utf) == 0) {
                     $replying_attendee = $attendee;
                     if ($attendee['status'] != 'DELEGATED') {
                         unset($replying_attendee['rsvp']);
                         // unset the RSVP attribute
                     }
                 } else {
                     if (!empty($attendee['delegated-to']) && (strcasecmp($attendee['delegated-to'], $from) == 0 || strcasecmp($attendee['delegated-to'], $from_utf) == 0) || !empty($attendee['delegated-from']) && (strcasecmp($attendee['delegated-from'], $from) == 0 || strcasecmp($attendee['delegated-from'], $from_utf) == 0)) {
                         $reply_attendees[] = $attendee;
                     }
                 }
             }
         }
         if ($replying_attendee) {
             array_unshift($reply_attendees, $replying_attendee);
             $event['attendees'] = $reply_attendees;
         }
         if ($event['recurrence']) {
             unset($event['recurrence']['EXCEPTIONS']);
         }
     } else {
         if ($method == 'REQUEST') {
             foreach ($event['attendees'] as $i => $attendee) {
                 if (($rsvp || !isset($attendee['rsvp'])) && ($attendee['status'] != 'DELEGATED' && $attendee['role'] != 'NON-PARTICIPANT')) {
                     $event['attendees'][$i]['rsvp'] = (bool) $rsvp;
                 }
             }
         } else {
             if ($method == 'CANCEL') {
                 if ($event['recurrence']) {
                     unset($event['recurrence']['EXCEPTIONS']);
                 }
             }
         }
     }
     // compose multipart message using PEAR:Mail_Mime
     $message = new Mail_mime("\r\n");
     $message->setParam('text_encoding', 'quoted-printable');
     $message->setParam('head_encoding', 'quoted-printable');
     $message->setParam('head_charset', RCUBE_CHARSET);
     $message->setParam('text_charset', RCUBE_CHARSET . ";\r\n format=flowed");
     $message->setContentType('multipart/alternative');
     // compose common headers array
     $headers = array('From' => $sender, 'Date' => $this->rc->user_date(), 'Message-ID' => $this->rc->gen_message_id(), 'X-Sender' => $from);
     if ($agent = $this->rc->config->get('useragent')) {
         $headers['User-Agent'] = $agent;
     }
     $message->headers($headers);
     // attach ics file for this event
     $ical = libcalendaring::get_ical();
     $ics = $ical->export(array($event), $method, false, $method == 'REQUEST' && $this->plugin->driver ? array($this->plugin->driver, 'get_attachment_body') : false);
     $filename = $event['_type'] == 'task' ? 'todo.ics' : 'event.ics';
     $message->addAttachment($ics, 'text/calendar', $filename, false, '8bit', '', RCUBE_CHARSET . "; method=" . $method);
     return $message;
 }
示例#28
0
 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')) {
         // #1486067: enable new_link option
         if (is_array($dsn) && empty($dsn['new_link'])) {
             $dsn['new_link'] = true;
         } else {
             if (!is_array($dsn) && !preg_match('/\\?new_link=true/', $dsn)) {
                 $dsn .= '?new_link=true';
             }
         }
         $db = rcube_db::factory($dsn, '', false);
         $db->set_debug((bool) $rcmail->config->get('sql_debug'));
         $db->db_connect('w');
     } 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;
 }
 /**
  * Connect to configured managesieve server
  *
  * @param string $username User login
  * @param string $password User password
  *
  * @return int Connection status: 0 on success, >0 on failure
  */
 public function connect($username, $password)
 {
     // Get connection parameters
     $host = $this->rc->config->get('managesieve_host', 'localhost');
     $port = $this->rc->config->get('managesieve_port');
     $tls = $this->rc->config->get('managesieve_usetls', false);
     $host = rcube_utils::parse_host($host);
     $host = rcube_utils::idn_to_ascii($host);
     // remove tls:// prefix, set TLS flag
     if (($host = preg_replace('|^tls://|i', '', $host, 1, $cnt)) && $cnt) {
         $tls = true;
     }
     if (empty($port)) {
         $port = getservbyname('sieve', 'tcp');
         if (empty($port)) {
             $port = self::PORT;
         }
     }
     $plugin = $this->rc->plugins->exec_hook('managesieve_connect', array('user' => $username, 'password' => $password, 'host' => $host, 'port' => $port, 'usetls' => $tls, 'auth_type' => $this->rc->config->get('managesieve_auth_type'), 'disabled' => $this->rc->config->get('managesieve_disabled_extensions'), 'debug' => $this->rc->config->get('managesieve_debug', false), 'auth_cid' => $this->rc->config->get('managesieve_auth_cid'), 'auth_pw' => $this->rc->config->get('managesieve_auth_pw'), 'socket_options' => $this->rc->config->get('managesieve_conn_options')));
     // try to connect to managesieve server and to fetch the script
     $this->sieve = new rcube_sieve($plugin['user'], $plugin['password'], $plugin['host'], $plugin['port'], $plugin['auth_type'], $plugin['usetls'], $plugin['disabled'], $plugin['debug'], $plugin['auth_cid'], $plugin['auth_pw'], $plugin['socket_options']);
     $error = $this->sieve->error();
     if ($error) {
         rcube::raise_error(array('code' => 403, 'file' => __FILE__, 'line' => __LINE__, 'message' => "Unable to connect to managesieve on {$host}:{$port}"), true, false);
     }
     return $error;
 }