/** * 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; } $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) { $host = null; } } else { if (!empty($config['default_host']) && $host != rcube_parse_host($config['default_host'])) { $host = null; } } 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' && (!$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_parse_host($config['username_domain'][$host], $host); } else { if (is_string($config['username_domain'])) { $username .= '@' . rcube_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']) { if ($config['login_lc'] == 2 || $config['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_idn_to_ascii($host); $username = rcube_idn_to_ascii($username); // user already registered -> overwrite username if ($user = rcube_user::query($username, $host)) { $username = $user->data['username']; } if (!$this->storage) { $this->storage_init(); } // try to log in if (!($login = $this->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 = $this->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 { 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 { 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']))) { $this->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 $this->storage->clear_cache('mailboxes', true); return true; } return false; }