PMS Password fix moved to new structure

parent 8408876e
<?php
/**
* Copyright: 2022 (c)Franco (nextime) Lanza <franco@nexlab.it>
* License: GNU/GPL version 3.0
*
* This file is part of SexHackMe Wordpress Plugin.
*
* SexHackMe Wordpress Plugin is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* SexHackMe Wordpress Plugin is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SexHackMe Wordpress Plugin. If not, see <https://www.gnu.org/licenses/>.
*/
namespace wp_SexHackMe;
if(!class_exists('SexhackPmsPasswordDataLeak')) {
class SexhackPmsPasswordDataLeak
{
public function __construct()
{
sexhack_log('SexhackPmsPasswordDataLeak() Instanced');
add_filter( 'pms_recover_password_message', array($this, "change_recover_form_message") );
add_action( 'init', array($this, 'reset_password_form'), 9);
add_action( 'login_form_rp', array( $this, 'redirect_password_reset' ) );
add_action( 'login_form_resetpass', array( $this, 'redirect_password_reset' ) );
}
public function change_recover_form_message($string)
{
return str_replace("<br/>", "<br/>If valid, ", $string);
}
public function redirect_password_reset()
{
wp_redirect( home_url( 'password-reset' ) );
}
public function reset_password_form()
{
/*
* Username or Email
*/
$error=false;
if( isset( $_POST['pms_username_email'] ) ) {
//Check recover password form nonce;
if( !isset( $_POST['pmstkn'] ) || ( !wp_verify_nonce( sanitize_text_field( $_POST['pmstkn'] ), 'pms_recover_password_form_nonce') ) )
return;
if( is_email( $_POST['pms_username_email'] ) )
$username_email = sanitize_email( $_POST['pms_username_email'] );
else
$username_email = sanitize_text_field( $_POST['pms_username_email'] );
if( empty( $username_email ) )
pms_errors()->add( 'pms_username_email', __( 'Please enter a username or email address.', 'paid-member-subscriptions' ) );
else {
$user = '';
// verify if it's a username and a valid one
if ( !is_email($username_email) ) {
if ( username_exists($username_email) ) {
$user = get_user_by('login',$username_email);
}
else $error=true; //pms_errors()->add('pms_username_email',__( 'The entered username doesn\'t exist. Please try again.', 'paid-member-subscriptions'));
}
//verify if it's a valid email
if ( is_email( $username_email ) ){
if ( email_exists($username_email) ) {
$user = get_user_by('email', $username_email);
}
else $error=true; //pms_errors()->add('pms_username_email',__( 'The entered email wasn\'t found in our database. Please try again.', 'paid-member-subscriptions'));
}
}
// Extra validation
do_action( 'pms_recover_password_form_validation' );
//If entered username or email is valid (no errors), email the password reset confirmation link
if ( count( pms_errors()->get_error_codes() ) == 0 && !$error) {
$mailpage = get_option('sexhack_registration_mail_endpoint', false);
if($mailpage) {
$page = get_page($mailpage);
$mailpage = $page->post_name;
}
send_changepwd_mail($user, $mailpage);
/*
if (is_object($user)) { //user data is set
$requestedUserID = $user->ID;
$requestedUserLogin = $user->user_login;
$requestedUserEmail = $user->user_email;
//search if there is already an activation key present, if not create one
$key = pms_retrieve_activation_key( $requestedUserLogin );
//Confirmation link email content
$recoveruserMailMessage1 = sprintf(__('Someone has just requested a password reset for the following account: <b>%1$s</b><br/><br/>If this was a mistake, just ignore this email and nothing will happen.<br/>To reset your password, visit the following link: %2$s', 'paid-member-subscriptions'), $username_email, '<a href="' . esc_url(add_query_arg(array('loginName' => urlencode( $requestedUserLogin ), 'key' => $key), pms_get_current_page_url())) . '">' . esc_url(add_query_arg(array('loginName' => urlencode( $requestedUserLogin ), 'key' => $key), pms_get_current_page_url())) . '</a>');
$recoveruserMailMessage1 = apply_filters('pms_recover_password_message_content_sent_to_user1', $recoveruserMailMessage1, $requestedUserID, $requestedUserLogin, $requestedUserEmail);
//Confirmation link email title
$recoveruserMailMessageTitle1 = sprintf(__('Password Reset from "%s"', 'paid-member-subscriptions'), $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES));
$recoveruserMailMessageTitle1 = apply_filters('pms_recover_password_message_title_sent_to_user1', $recoveruserMailMessageTitle1, $requestedUserLogin);
//we add this filter to enable html encoding
add_filter('wp_mail_content_type', function () { return 'text/html'; } );
// Temporary change the from name and from email
add_filter( 'wp_mail_from_name', array( 'PMS_Emails', 'pms_email_website_name' ), 20, 1 );
add_filter( 'wp_mail_from', array( 'PMS_Emails', 'pms_email_website_email' ), 20, 1 );
//send mail to the user notifying him of the reset request
if (trim($recoveruserMailMessageTitle1) != '') {
$sent = wp_mail($requestedUserEmail, $recoveruserMailMessageTitle1, $recoveruserMailMessage1);
if ($sent === false)
pms_errors()->add('pms_username_email',__( 'There was an error while trying to send the activation link.', 'paid-member-subscriptions'));
}
// Reset the from name and email
remove_filter( 'wp_mail_from_name', array( 'PMS_Emails', 'pms_email_website_name' ), 20 );
remove_filter( 'wp_mail_from', array( 'PMS_Emails', 'pms_email_website_email' ), 20 );
// add option to store all user $id => $key and timestamp values that reset their passwords every 24 hours
if ( false === ( $activation_keys = get_option( 'pms_recover_password_activation_keys' ) ) ) {
$activation_keys = array();
}
$activation_keys[$user->ID]['key'] = $key;
$activation_keys[$user->ID]['time'] = time();
update_option( 'pms_recover_password_activation_keys', $activation_keys );
if( $sent === true )
do_action( 'pms_password_reset_email_sent', $user, $key );
} */
}
} // isset($_POST[pms_username_email])
unset($_POST['pms_username_email']);
}
}
}
$SEXHACK_SECTION = array('class' => 'SexhackPmsPasswordDataLeak',
'description' => 'Fix Pay Member Subscription password-reset data leak',
'name' => 'sexhackme_pms_resetfix',
'require-page' => array(
array('post_type' => 'page', 'title' => 'Reset password page', 'option' => 'sexhack_reset_pwd_fix')
)
);
?>
......@@ -24,98 +24,199 @@ namespace wp_SexHackMe;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
class SexHackPMSHelper
{
public function __construct()
{
$this->plans = false;
}
private function set_pms_plans()
{
$plans = array(
'member' => array(),
'premium'=> array(),
'byid' => array()
);
if(!class_exists('SH_PMS_Support')) {
class SH_PMS_Support
{
public function __construct()
{
$this->plans = false;
}
private function set_pms_plans()
{
$plans = array(
'member' => array(),
'premium'=> array(),
'byid' => array()
);
$splans=pms_get_subscription_plans(true);
foreach($splans as $splan)
{
if(intval($splan->price)==0) $plans['member'][] = $splan->id;
else $plans['premium'][] = $splan->id;
$splans=pms_get_subscription_plans(true);
foreach($splans as $splan)
{
if(intval($splan->price)==0) $plans['member'][] = $splan->id;
else $plans['premium'][] = $splan->id;
$plans['byid'][$splan->id] = $splan;
}
$this->plans = $plans;
return $plans;
}
$plans['byid'][$splan->id] = $splan;
public function refresh_plans()
{
$this->plans = set_pms_plans();
return $this->plans;
}
$this->plans = $plans;
return $plans;
}
public function refresh_plans()
{
$this->plans = set_pms_plans();
return $this->plans;
}
// XXX Here we just return the first "member" (free) plan
// if any in our array.
//
// I should probably make it configurable with an option?
// And should not be limited to the free ones?
public function get_default_plan()
{
if(!$this->plans) $this->set_pms_plans();
if(count($this->plans['member']) > 0)
{
return $this->plans['byid'][$this->plans['member'][0]];
}
return false;
}
public function get_member_plans()
{
if(!$this->plans) $this->set_pms_plans();
return $this->plans['member'];
}
// XXX Here we just return the first "member" (free) plan
// if any in our array.
//
// I should probably make it configurable with an option?
// And should not be limited to the free ones?
public function get_default_plan()
{
if(!$this->plans) $this->set_pms_plans();
if(count($this->plans['member']) > 0)
public function get_premium_plans()
{
return $this->plans['byid'][$this->plans['member'][0]];
if(!$this->plans) $this->set_pms_plans();
return $this->plans['premium'];
}
return false;
}
public function get_member_plans()
{
if(!$this->plans) $this->set_pms_plans();
return $this->plans['member'];
public function get_plans($pid=false)
{
if(!$this->plans) $this->set_pms_plans();
if($pid)
{
if(array_key_exists($pid, $this->plans['byid'])) return $this->plans['byid'][$pid];
return false;
}
return $this->plans['byid'];
}
public function is_member($uid='')
{
return pms_is_member( $uid, $this->get_member_plans() );
}
public function is_premium($uid='')
{
return pms_is_member( $uid, $this->get_premium_plans() );
}
}
public function get_premium_plans()
{
if(!$this->plans) $this->set_pms_plans();
return $this->plans['premium'];
function instance_SH_PMS_Support() {
// add $sh_pms global object
$GLOBALS['sh_pms'] = new SH_PMS_Support();
// backward compatibility
$GLOBALS['sexhack_pms'] = $GLOBALS['sh_pms'];
// Do action after instancing the global var to notify is reay
do_action('sh_pms_ready');
}
public function get_plans($pid=false)
// Create the sh_pms object
add_action('wp', 'wp_SexHackMe\instance_SH_PMS_Support');
}
if(!class_exists('SexhackPmsPasswordDataLeak')) {
class SexhackPmsPasswordDataLeak
{
if(!$this->plans) $this->set_pms_plans();
if($pid)
{
if(array_key_exists($pid, $this->plans['byid'])) return $this->plans['byid'][$pid];
return false;
public function __construct()
{
sexhack_log('SexhackPmsPasswordDataLeak() Instanced');
add_filter( 'pms_recover_password_message', array($this, "change_recover_form_message") );
add_action( 'init', array($this, 'reset_password_form'), 9);
add_action( 'login_form_rp', array( $this, 'redirect_password_reset' ) );
add_action( 'login_form_resetpass', array( $this, 'redirect_password_reset' ) );
}
return $this->plans['byid'];
}
public function change_recover_form_message($string)
{
// XXX This should be in a template file as a full substitute
return str_replace("<br/>", "<br/>If valid, ", $string);
}
public function is_member($uid='')
{
return pms_is_member( $uid, $this->get_member_plans() );
}
public function is_premium($uid='')
{
return pms_is_member( $uid, $this->get_premium_plans() );
}
}
public function redirect_password_reset()
{
// XXX This should be configurable.
wp_redirect( home_url( 'password-reset' ) );
}
public function reset_password_form()
{
function instancePMSHelper() {
$GLOBALS['sexhack_pms'] = new SexHackPMSHelper();
}
/*
* Username or Email
*/
$error=false;
if( isset( $_POST['pms_username_email'] ) ) {
//Check recover password form nonce;
if( !isset( $_POST['pmstkn'] ) || ( !wp_verify_nonce( sanitize_text_field( $_POST['pmstkn'] ), 'pms_recover_password_form_nonce') ) )
return;
if( is_email( $_POST['pms_username_email'] ) )
$username_email = sanitize_email( $_POST['pms_username_email'] );
else
$username_email = sanitize_text_field( $_POST['pms_username_email'] );
if( empty( $username_email ) )
pms_errors()->add( 'pms_username_email', __( 'Please enter a username or email address.', 'paid-member-subscriptions' ) );
else {
$user = '';
// verify if it's a username and a valid one
if ( !is_email($username_email) ) {
if ( username_exists($username_email) ) {
$user = get_user_by('login',$username_email);
}
else $error=true;
}
//verify if it's a valid email
if ( is_email( $username_email ) ){
if ( email_exists($username_email) ) {
$user = get_user_by('email', $username_email);
}
else $error=true;
}
}
// Extra validation
do_action( 'pms_recover_password_form_validation' );
//If entered username or email is valid (no errors), email the password reset confirmation link
if ( count( pms_errors()->get_error_codes() ) == 0 && !$error) {
// XXX this option?
$mailpage = get_option('sexhack_registration_mail_endpoint', false);
if($mailpage) {
$page = get_page($mailpage);
$mailpage = $page->post_name;
}
send_changepwd_mail($user, $mailpage);
}
} // isset($_POST[pms_username_email])
unset($_POST['pms_username_email']);
}
}
add_action('wp', 'wp_SexHackMe\instancePMSHelper');
// Let's create the Fixes
new SexhackPmsPasswordDataLeak;
}
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment