/** * Display installer setup form. * * @since 2.8.0 * * @param string|null $error */ function display_setup_form($error = null) { global $hqdb; $sql = $hqdb->prepare("SHOW TABLES LIKE %s", $hqdb->esc_like($hqdb->users)); $user_table = $hqdb->get_var($sql) != null; // Ensure that Blogs appear in search engines by default. $blog_public = 1; if (isset($_POST['weblog_title'])) { $blog_public = isset($_POST['blog_public']); } $weblog_title = isset($_POST['weblog_title']) ? trim(hq_unslash($_POST['weblog_title'])) : ''; $user_name = isset($_POST['user_name']) ? trim(hq_unslash($_POST['user_name'])) : ''; $admin_email = isset($_POST['admin_email']) ? trim(hq_unslash($_POST['admin_email'])) : ''; if (!is_null($error)) { ?> <p class="message"><?php echo $error; ?> </p> <?php } ?> <form id="setup" method="post" action="install.php?step=2" novalidate="novalidate"> <table class="form-table"> <tr> <th scope="row"><label for="weblog_title"><?php _e('Site Title'); ?> </label></th> <td><input name="weblog_title" type="text" id="weblog_title" size="25" value="<?php echo esc_attr($weblog_title); ?> " /></td> </tr> <tr> <th scope="row"><label for="user_login"><?php _e('Username'); ?> </label></th> <td> <?php if ($user_table) { _e('User(s) already exists.'); echo '<input name="user_name" type="hidden" value="admin" />'; } else { ?> <input name="user_name" type="text" id="user_login" size="25" value="<?php echo esc_attr(sanitize_user($user_name, true)); ?> " /> <p><?php _e('Usernames can have only alphanumeric characters, spaces, underscores, hyphens, periods, and the @ symbol.'); ?> </p> <?php } ?> </td> </tr> <?php if (!$user_table) { ?> <tr class="form-field form-required user-pass1-wrap"> <th scope="row"> <label for="pass1"> <?php _e('Password'); ?> </label> </th> <td> <div class=""> <?php $initial_password = isset($_POST['admin_password']) ? stripslashes($_POST['admin_password']) : hq_generate_password(18); ?> <input type="password" name="admin_password" id="pass1" class="regular-text" autocomplete="off" data-reveal="1" data-pw="<?php echo esc_attr($initial_password); ?> " aria-describedby="pass-strength-result" /> <button type="button" class="button button-secondary hq-hide-pw hide-if-no-js" data-start-masked="<?php echo (int) isset($_POST['admin_password']); ?> " data-toggle="0" aria-label="<?php esc_attr_e('Hide password'); ?> "> <span class="dashicons dashicons-hidden"></span> <span class="text"><?php _e('Hide'); ?> </span> </button> <div id="pass-strength-result" aria-live="polite"></div> </div> <p><span class="description important hide-if-no-js"> <strong><?php _e('Important:'); ?> </strong> <?php /* translators: The non-breaking space prevents 1Password from thinking the text "log in" should trigger a password save prompt. */ ?> <?php _e('You will need this password to log in. Please store it in a secure location.'); ?> </span></p> </td> </tr> <tr class="form-field form-required user-pass2-wrap hide-if-js"> <th scope="row"> <label for="pass2"><?php _e('Repeat Password'); ?> <span class="description"><?php _e('(required)'); ?> </span> </label> </th> <td> <input name="admin_password2" type="password" id="pass2" autocomplete="off" /> </td> </tr> <tr class="pw-weak"> <th scope="row"><?php _e('Confirm Password'); ?> </th> <td> <label> <input type="checkbox" name="pw_weak" class="pw-checkbox" /> <?php _e('Confirm use of weak password'); ?> </label> </td> </tr> <?php } ?> <tr> <th scope="row"><label for="admin_email"><?php _e('Your E-mail'); ?> </label></th> <td><input name="admin_email" type="email" id="admin_email" size="25" value="<?php echo esc_attr($admin_email); ?> " /> <p><?php _e('Double-check your email address before continuing.'); ?> </p></td> </tr> <tr> <th scope="row"><?php _e('Privacy'); ?> </th> <td colspan="2"><label><input type="checkbox" name="blog_public" id="blog_public" value="1" <?php checked($blog_public); ?> /> <?php _e('Allow search engines to index this site'); ?> </label></td> </tr> </table> <p class="step"><?php submit_button(__('Install HiveQueen'), 'large', 'Submit', false, array('id' => 'submit')); ?> </p> <input type="hidden" name="language" value="<?php echo isset($_REQUEST['language']) ? esc_attr($_REQUEST['language']) : ''; ?> " /> </form> <?php }
/** * Get salt to add to hashes. * * Salts are created using secret keys. Secret keys are located in two places: * in the database and in the hq-config.php file. The secret key in the database * is randomly generated and will be appended to the secret keys in hq-config.php. * * The secret keys in hq-config.php should be updated to strong, random keys to maximize * security. Below is an example of how the secret key constants are defined. * Do not paste this example directly into hq-config.php. Instead, have a * {@link https://api.wordpress.org/secret-key/1.1/salt/ secret key created} just * for you. * * define('AUTH_KEY', ' Xakm<o xQy rw4EMsLKM-?!T+,PFF})H4lzcW57AF0U@N@< >M%G4Yt>f`z]MON'); * define('SECURE_AUTH_KEY', 'LzJ}op]mr|6+![P}Ak:uNdJCJZd>(Hx.-Mh#Tz)pCIU#uGEnfFz|f ;;eU%/U^O~'); * define('LOGGED_IN_KEY', '|i|Ux`9<p-h$aFf(qnT:sDO:D1P^wZ$$/Ra@miTJi9G;ddp_<q}6H1)o|a +&JCM'); * define('NONCE_KEY', '%:R{[P|,s.KuMltH5}cI;/k<Gx~j!f0I)m_sIyu+&NJZ)-iO>z7X>QYR0Z_XnZ@|'); * define('AUTH_SALT', 'eZyT)-Naw]F8CwA*VaW#q*|.)g@o}||wf~@C-YSt}(dh_r6EbI#A,y|nU2{B#JBW'); * define('SECURE_AUTH_SALT', '!=oLUTXh,QW=H `}`L|9/^4-3 STz},T(w}W<I`.JjPi)<Bmf1v,HpGe}T1:Xt7n'); * define('LOGGED_IN_SALT', '+XSqHc;@Q*K_b|Z?NC[3H!!EONbh.n<+=uKR:>*c(u`g~EJBf#8u#R{mUEZrozmm'); * define('NONCE_SALT', 'h`GXHhD>SLWVfg1(1(N{;.V!MoE(SfbA_ksP@&`+AycHcAV$+?@3q+rxV{%^VyKT'); * * Salting passwords helps against tools which has stored hashed values of * common dictionary strings. The added values makes it harder to crack. * * @since 0.0.1 * * @link https://api.wordpress.org/secret-key/1.1/salt/ Create secrets for hq-config.php * * @staticvar array $cached_salts * @staticvar array $duplicated_keys * * @param string $scheme Authentication scheme (auth, secure_auth, logged_in, nonce) * @return string Salt value */ function hq_salt($scheme = 'auth') { static $cached_salts = array(); if (isset($cached_salts[$scheme])) { /** * Filter the HiveQueen salt. * * @since 0.0.1 * * @param string $cached_salt Cached salt for the given scheme. * @param string $scheme Authentication scheme. Values include 'auth', * 'secure_auth', 'logged_in', and 'nonce'. */ return apply_filters('salt', $cached_salts[$scheme], $scheme); } static $duplicated_keys; if (null === $duplicated_keys) { $duplicated_keys = array('put your unique phrase here' => true); foreach (array('AUTH', 'SECURE_AUTH', 'LOGGED_IN', 'NONCE', 'SECRET') as $first) { foreach (array('KEY', 'SALT') as $second) { if (!defined("{$first}_{$second}")) { continue; } $value = constant("{$first}_{$second}"); $duplicated_keys[$value] = isset($duplicated_keys[$value]); } } } $values = array('key' => '', 'salt' => ''); if (defined('SECRET_KEY') && SECRET_KEY && empty($duplicated_keys[SECRET_KEY])) { $values['key'] = SECRET_KEY; } if ('auth' == $scheme && defined('SECRET_SALT') && SECRET_SALT && empty($duplicated_keys[SECRET_SALT])) { $values['salt'] = SECRET_SALT; } if (in_array($scheme, array('auth', 'secure_auth', 'logged_in', 'nonce'))) { foreach (array('key', 'salt') as $type) { $const = strtoupper("{$scheme}_{$type}"); if (defined($const) && constant($const) && empty($duplicated_keys[constant($const)])) { $values[$type] = constant($const); } elseif (!$values[$type]) { $values[$type] = get_site_option("{$scheme}_{$type}"); if (!$values[$type]) { $values[$type] = hq_generate_password(64, true, true); update_site_option("{$scheme}_{$type}", $values[$type]); } } } } else { if (!$values['key']) { $values['key'] = get_site_option('secret_key'); if (!$values['key']) { $values['key'] = hq_generate_password(64, true, true); update_site_option('secret_key', $values['key']); } } $values['salt'] = hash_hmac('md5', $scheme, $values['key']); } $cached_salts[$scheme] = $values['key'] . $values['salt']; /** This filter is documented in hq-includes/pluggable.php */ return apply_filters('salt', $cached_salts[$scheme], $scheme); }
/** * Generate a session token and attach session information to it. * * A session token is a long, random string. It is used in a cookie * link that cookie to an expiration time and to ensure the cookie * becomes invalidated upon logout. * * This function generates a token and stores it with the associated * expiration time (and potentially other session information via the * `attach_session_information` filter). * * @since 0.0.1 * @access public * * @param int $expiration Session expiration timestamp. * @return string Session token. */ public final function create($expiration) { /** * Filter the information attached to the newly created session. * * Could be used in the future to attach information such as * IP address or user agent to a session. * * @since 0.0.1 * * @param array $session Array of extra data. * @param int $user_id User ID. */ $session = apply_filters('attach_session_information', array(), $this->user_id); $session['expiration'] = $expiration; // IP address. if (!empty($_SERVER['REMOTE_ADDR'])) { $session['ip'] = $_SERVER['REMOTE_ADDR']; } // User-agent. if (!empty($_SERVER['HTTP_USER_AGENT'])) { $session['ua'] = hq_unslash($_SERVER['HTTP_USER_AGENT']); } // Timestamp $session['login'] = time(); $token = hq_generate_password(43, false, false); $this->update($token, $session); return $token; }
/** Installs the site. * * Runs the required functions to set up and populate the database, * including primary admin user and initial options. * * @since 0.0.1 * * @param string $blog_title Blog title. * @param string $user_name User's username. * @param string $user_email User's email. * @param bool $public Whether blog is public. * @param string $deprecated Optional. Not used. * @param string $user_password Optional. User's chosen password. Default empty (random password). * @param string $language Optional. Language chosen. Default empty. * @return array Array keys 'url', 'user_id', 'password', and 'password_message'. */ function hq_install($blog_title, $user_name, $user_email, $public, $deprecated = '', $user_password = '', $language = '') { if (!empty($deprecated)) { _deprecated_argument(__FUNCTION__, '2.6'); } hq_check_mysql_version(); //TODO: no cache //hq_cache_flush(); //TODO: Debug //make_db_current_silent(); make_db_current(); populate_options(); populate_roles(); update_option('blogname', $blog_title); update_option('admin_email', $user_email); update_option('blog_public', $public); if ($language) { update_option('HQLANG', $language); } $guessurl = hq_guess_url(); update_option('siteurl', $guessurl); // If not a public blog, don't ping. if (!$public) { update_option('default_pingback_flag', 0); } /* * Create default user. If the user already exists, the user tables are * being shared among blogs. Just set the role in that case. */ $user_id = username_exists($user_name); $user_password = trim($user_password); $email_password = false; if (!$user_id && empty($user_password)) { $user_password = hq_generate_password(12, false); $message = __('<strong><em>Note that password</em></strong> carefully! It is a <em>random</em> password that was generated just for you.'); $user_id = hq_create_user($user_name, $user_password, $user_email); update_user_option($user_id, 'default_password_nag', true, true); $email_password = true; } elseif (!$user_id) { // Password has been provided $message = '<em>' . __('Your chosen password.') . '</em>'; $user_id = hq_create_user($user_name, $user_password, $user_email); } else { $message = __('User already exists. Password inherited.'); } $user = new HQ_User($user_id); $user->set_role('administrator'); hq_install_defaults($user_id); hq_install_maybe_enable_pretty_permalinks(); flush_rewrite_rules(); hq_new_blog_notification($blog_title, $guessurl, $user_id, $email_password ? $user_password : __('The password you chose during the install.')); hq_cache_flush(); /** * Fires after a site is fully installed. * * @since 0.0.1 * * @param HQ_User $user The site owner. */ do_action('hq_install', $user); return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message); }
/** * Handles sending password retrieval email to user. * * @global hqdb $hqdb HiveQueen database abstraction object. * @global PasswordHash $hq_hasher Portable PHP password hashing framework. * * @return bool|HQ_Error True: when finish. HQ_Error on error */ function retrieve_password() { global $hqdb, $hq_hasher; $errors = new HQ_Error(); if (empty($_POST['user_login'])) { $errors->add('empty_username', __('<strong>ERROR</strong>: Enter a username or e-mail address.')); } elseif (strpos($_POST['user_login'], '@')) { $user_data = get_user_by('email', trim($_POST['user_login'])); if (empty($user_data)) { $errors->add('invalid_email', __('<strong>ERROR</strong>: There is no user registered with that email address.')); } } else { $login = trim($_POST['user_login']); $user_data = get_user_by('login', $login); } /** * Fires before errors are returned from a password reset request. * * @since 0.0.1 */ do_action('lostpassword_post'); if ($errors->get_error_code()) { return $errors; } if (!$user_data) { $errors->add('invalidcombo', __('<strong>ERROR</strong>: Invalid username or e-mail.')); return $errors; } // Redefining user_login ensures we return the right case in the email. $user_login = $user_data->user_login; $user_email = $user_data->user_email; /** * Fires before a new password is retrieved. * * @since 0.0.1 * * @param string $user_login The user login name. */ do_action('retreive_password', $user_login); /** * Fires before a new password is retrieved. * * @since 0.0.1 * * @param string $user_login The user login name. */ do_action('retrieve_password', $user_login); /** * Filter whether to allow a password to be reset. * * @since 0.0.1 * * @param bool true Whether to allow the password to be reset. Default true. * @param int $user_data->ID The ID of the user attempting to reset a password. */ $allow = apply_filters('allow_password_reset', true, $user_data->ID); if (!$allow) { return new HQ_Error('no_password_reset', __('Password reset is not allowed for this user')); } elseif (is_hq_error($allow)) { return $allow; } // Generate something random for a password reset key. $key = hq_generate_password(20, false); /** * Fires when a password reset key is generated. * * @since 0.0.1 * * @param string $user_login The username for the user. * @param string $key The generated password reset key. */ do_action('retrieve_password_key', $user_login, $key); // Now insert the key, hashed, into the DB. if (empty($hq_hasher)) { require_once ABSPATH . HQINC . '/class-phpass.php'; $hq_hasher = new PasswordHash(8, true); } $hashed = time() . ':' . $hq_hasher->HashPassword($key); $hqdb->update($hqdb->users, array('user_activation_key' => $hashed), array('user_login' => $user_login)); $message = __('Someone requested that the password be reset for the following account:') . "\r\n\r\n"; $message .= network_home_url('/') . "\r\n\r\n"; $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; $message .= __('If this was a mistake, just ignore this email and nothing will happen.') . "\r\n\r\n"; $message .= __('To reset your password, visit the following address:') . "\r\n\r\n"; $message .= '<' . network_site_url("hq-login.php?action=rp&key={$key}&login="******">\r\n"; //TODO: Goyo no multisite //if ( is_multisite() ) if (false) { $blogname = $GLOBALS['current_site']->site_name; } else { /* * The blogname option is escaped with esc_html on the way into the database * in sanitize_option we want to reverse this for the plain text arena of emails. */ $blogname = hq_specialchars_decode(get_option('blogname'), ENT_QUOTES); } $title = sprintf(__('[%s] Password Reset'), $blogname); /** * Filter the subject of the password reset email. * * @since 0.0.1 * * @param string $title Default email title. */ $title = apply_filters('retrieve_password_title', $title); /** * Filter the message body of the password reset mail. * * @since 0.0.1 * * @param string $message Default mail message. * @param string $key The activation key. * @param string $user_login The username for the user. * @param HQ_User $user_data HQ_User object. */ $message = apply_filters('retrieve_password_message', $message, $key, $user_login, $user_data); if ($message && !hq_mail($user_email, hq_specialchars_decode($title), $message)) { hq_die(__('The e-mail could not be sent.') . "<br />\n" . __('Possible reason: your host may have disabled the mail() function.')); } return true; }