Skip to content

Commit

Permalink
2.0.4
Browse files Browse the repository at this point in the history
Updated: More security.
  • Loading branch information
smusman98 committed Jul 18, 2022
1 parent b5cde9b commit f164971
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ function enqueuePortTestResources() {
wp_enqueue_script( 'postman_port_test_script' );
$warning = __( 'Warning', 'post-smtp' );
wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_email_test', array(
'recipient' => '#' . PostmanSendTestEmailController::RECIPIENT_EMAIL_FIELD_NAME,
'not_started' => _x( 'In Outbox', 'Email Test Status', 'post-smtp' ),
'sending' => _x( 'Sending...', 'Email Test Status', 'post-smtp' ),
'success' => _x( 'Success', 'Email Test Status', 'post-smtp' ),
'failed' => _x( 'Failed', 'Email Test Status', 'post-smtp' ),
'ajax_error' => __( 'Ajax Error', 'post-smtp' ),
) );
PostmanConnectivityTestController::addLocalizeScriptForPortTest();
}
static function addLocalizeScriptForPortTest() {
Expand Down Expand Up @@ -135,6 +143,8 @@ public function port_test_hostname_callback() {
public function outputPortTestContent() {
print '<div class="wrap">';

wp_nonce_field('post-smtp', 'security');

PostmanViewController::outputChildPageHeader( __( 'Connectivity Test', 'post-smtp' ) );

print '<p>';
Expand Down
4 changes: 2 additions & 2 deletions Postman/Postman-Connectivity-Test/postman_port_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function portQuizTest(socket, hostname, port) {
'action' : 'postman_port_quiz_test',
'hostname' : hostname,
'port' : port,
'_wpnonce' : jQuery('#_wpnonce').val(),
'security' : jQuery('#security').val(),
};
jQuery.post(
ajaxurl,
Expand Down Expand Up @@ -201,7 +201,7 @@ function portTest3(socket, hostname, port, open) {
'action' : 'postman_test_smtps',
'hostname' : hostname,
'port' : port,
'_wpnonce' : jQuery('#_wpnonce').val(),
'security' : jQuery('#security').val(),
};
jQuery
.post(
Expand Down
8 changes: 4 additions & 4 deletions Postman/Postman-Email-Log/PostmanEmailLogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exit; // Exit if accessed directly
}

require_once dirname(__DIR__) . '/PostmanEmailLogs.php';
require_once dirname(__DIR__) . '/PostmanLogFields.php';
require_once 'PostmanEmailLogService.php';
require_once 'PostmanEmailLogView.php';

Expand Down Expand Up @@ -82,7 +82,7 @@ public function resendMail() {
// get the email address of the recipient from the HTTP Request
$postid = $this->getRequestParameter( 'email' );
if ( ! empty( $postid ) ) {
$meta_values = PostmanEmailLogs::get_data( $postid );
$meta_values = PostmanLogFields::get_instance()->get( $postid );

if ( isset( $_POST['mail_to'] ) && ! empty( $_POST['mail_to'] ) ) {
$emails = explode( ',', $_POST['mail_to'] );
Expand Down Expand Up @@ -211,7 +211,7 @@ function view_log_item() {
return;
}

$meta_values = PostmanEmailLogs::get_data( $postid );
$meta_values = PostmanLogFields::get_instance()->get( $postid );
// https://css-tricks.com/examples/hrs/
print '<html><head><style>body {font-family: monospace;} hr {
border: 0;
Expand Down Expand Up @@ -269,7 +269,7 @@ function view_transcript_log_item() {
$this->logger->trace( 'handling view transcript item' );
$postid = $_REQUEST ['email'];
$post = get_post( $postid );
$meta_values = PostmanEmailLogs::get_data( $postid );
$meta_values = PostmanLogFields::get_instance()->get( $postid );
// https://css-tricks.com/examples/hrs/
print '<html><head><style>body {font-family: monospace;} hr {
border: 0;
Expand Down
26 changes: 14 additions & 12 deletions Postman/Postman-Email-Log/PostmanEmailLogService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
exit; // Exit if accessed directly
}

require_once dirname(__DIR__ ) . '/PostmanLogFields.php';

if ( ! class_exists( 'PostmanEmailLog' ) ) {
class PostmanEmailLog {
public $sender;
Expand Down Expand Up @@ -153,32 +155,32 @@ private function writeToEmailLog( PostmanEmailLog $log, PostmanMessage $message
$this->logger->trace( $log );

// Write the meta data related to the email
update_post_meta( $post_id, 'success', $log->success );
update_post_meta( $post_id, 'from_header', $log->sender );
PostmanLogFields::get_instance()->update( $post_id, 'success', $log->success );
PostmanLogFields::get_instance()->update( $post_id, 'from_header', $log->sender );
if ( ! empty( $log->toRecipients ) ) {
update_post_meta( $post_id, 'to_header', $log->toRecipients );
PostmanLogFields::get_instance()->update( $post_id, 'to_header', $log->toRecipients );
}
if ( ! empty( $log->ccRecipients ) ) {
update_post_meta( $post_id, 'cc_header', $log->ccRecipients );
PostmanLogFields::get_instance()->update( $post_id, 'cc_header', $log->ccRecipients );
}
if ( ! empty( $log->bccRecipients ) ) {
update_post_meta( $post_id, 'bcc_header', $log->bccRecipients );
PostmanLogFields::get_instance()->update( $post_id, 'bcc_header', $log->bccRecipients );
}
if ( ! empty( $log->replyTo ) ) {
update_post_meta( $post_id, 'reply_to_header', $log->replyTo );
PostmanLogFields::get_instance()->update( $post_id, 'reply_to_header', $log->replyTo );
}
update_post_meta( $post_id, 'transport_uri', $log->transportUri );
PostmanLogFields::get_instance()->update( $post_id, 'transport_uri', $log->transportUri );

if ( ! $log->success || true ) {
// alwas add the meta data so we can re-send it
update_post_meta( $post_id, 'original_to', $log->originalTo );
update_post_meta( $post_id, 'original_subject', $log->originalSubject );
update_post_meta( $post_id, 'original_message', $log->originalMessage );
update_post_meta( $post_id, 'original_headers', $log->originalHeaders );
PostmanLogFields::get_instance()->update( $post_id, 'original_to', $log->originalTo );
PostmanLogFields::get_instance()->update( $post_id, 'original_subject', $log->originalSubject );
PostmanLogFields::get_instance()->update( $post_id, 'original_message', $log->originalMessage );
PostmanLogFields::get_instance()->update( $post_id, 'original_headers', $log->originalHeaders );
}

// we do not sanitize the session transcript - let the reader decide how to handle the data
update_post_meta( $post_id, 'session_transcript', $log->sessionTranscript );
PostmanLogFields::get_instance()->update( $post_id, 'session_transcript', $log->sessionTranscript );

// truncate the log (remove older entries)
$purger = new PostmanEmailLogPurger();
Expand Down
6 changes: 3 additions & 3 deletions Postman/Postman-Email-Log/PostmanEmailLogView.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
require_once dirname(__DIR__) . '/PostmanEmailLogs.php';
require_once dirname(__DIR__) . '/PostmanLogFields.php';

/**
* See http://wpengineer.com/2426/wp_list_table-a-step-by-step-guide/
Expand Down Expand Up @@ -96,7 +96,7 @@ function column_title( $item ) {
$transcriptUrl = admin_url( sprintf( $iframeUri, 'transcript', $item ['ID'] ) );
$resendUrl = admin_url( sprintf( $iframeUri, 'resend', $item ['ID'] ) );

$meta_values = PostmanEmailLogs::get_data( $item ['ID'] );
$meta_values = PostmanLogFields::get_instance()->get( $item ['ID'] );

$actions = array(
'delete' => sprintf( '<a href="%s">%s</a>', $deleteUrl, _x( 'Delete', 'Delete an item from the email log', 'post-smtp' ) ),
Expand Down Expand Up @@ -373,7 +373,7 @@ function prepare_items() {
/* Translators: where %s indicates the relative time from now */
$date = sprintf( _x( '%s ago', 'A relative time as in "five days ago"', 'post-smtp' ), $humanTime );
}
$meta_values = PostmanEmailLogs::get_data( $post->ID );
$meta_values = PostmanLogFields::get_instance()->get( $post->ID );
$sent_to = array_map( 'sanitize_email', explode( ',' , $meta_values ['to_header'] [0] ) );
$flattenedPost = array(
// the post title must be escaped as they are displayed in the HTML output
Expand Down
2 changes: 2 additions & 0 deletions Postman/Postman-Mail/PostmanSmtpModuleTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@ public function printWizardMailServerHostnameStep() {
printf( '<legend>%s</legend>', _x( 'Which host will relay the mail?', 'Wizard Step Title', 'post-smtp' ) );
printf( '<p>%s</p>', __( 'This is the Outgoing (SMTP) Mail Server, or Mail Submission Agent (MSA), which Postman delegates mail delivery to. This server is specific to your email account, and if you don\'t know what to use, ask your email service provider.', 'post-smtp' ) );
printf( '<p>%s</p>', __( 'Note that many WordPress hosts, such as GoDaddy, Bluehost and Dreamhost, require that you use their mail accounts with their mail servers, and prevent you from using others.', 'post-smtp' ) );

printf( '<div><strong><u>%s</u></strong></div><br>', __( 'If you plan to use An API and not SMTP just type any value.', 'post-smtp' ) );
printf( '<label for="hostname">%s</label>', __( 'Outgoing Mail Server Hostname', 'post-smtp' ) );
print $this->hostname_callback();
printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
Expand Down
15 changes: 13 additions & 2 deletions Postman/Postman-Mail/Zend-1.12.10/Mail.php
Original file line number Diff line number Diff line change
Expand Up @@ -706,10 +706,21 @@ public function setReplyTo($email, $name = null)
throw new Postman_Zend_Mail_Exception('Reply-To Header set twice');
}

$email = $this->_filterEmail($email);
$name = $this->_filterName($name);
$this->_replyTo = $email;
$this->_storeHeader('Reply-To', $this->_formatAddress($email, $name), true);

if ( strpos( $email, ',' ) !== false ) {
$emails = explode(',', $email );
foreach ( $emails as $email ) {
$email = $this->_filterEmail($email);
$replyToList[] = $this->_formatAddress($email, $name);
}
} else {
$email = $this->_filterEmail($email);
$replyToList[] = $this->_formatAddress($email, $name);
}

$this->_storeHeader('Reply-To', implode(',', $replyToList ), true);

return $this;
}
Expand Down
7 changes: 5 additions & 2 deletions Postman/PostmanInputSanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ public function sanitize( $input ) {
$this->sanitizeString( 'Fallback username', PostmanOptions::FALLBACK_SMTP_USERNAME, $input, $new_input );
$this->sanitizePassword( 'Fallback password', PostmanOptions::FALLBACK_SMTP_PASSWORD, $input, $new_input, $this->options->getFallbackPassword() );

$new_input = apply_filters( 'post_smtp_sanitize', $new_input, $input, $this );

if ( $new_input [ PostmanOptions::CLIENT_ID ] != $this->options->getClientId() || $new_input [ PostmanOptions::CLIENT_SECRET ] != $this->options->getClientSecret() || $new_input [ PostmanOptions::HOSTNAME ] != $this->options->getHostname() ) {
$this->logger->debug( 'Recognized new Client ID' );
// the user entered a new client id and we should destroy the stored auth token
Expand All @@ -115,7 +117,8 @@ public function sanitize( $input ) {

return $new_input;
}
private function sanitizeString( $desc, $key, $input, &$new_input ) {

public function sanitizeString( $desc, $key, $input, &$new_input ) {
if ( isset( $input [ $key ] ) ) {
$this->logSanitize( $desc, $input [ $key ] );
$new_input [ $key ] = trim( $input [ $key ] );
Expand All @@ -130,7 +133,7 @@ private function sanitizeString( $desc, $key, $input, &$new_input ) {
* @param mixed $input
* @param mixed $new_input
*/
private function sanitizePassword( $desc, $key, $input, &$new_input, $existingPassword ) {
public function sanitizePassword( $desc, $key, $input, &$new_input, $existingPassword ) {
// WordPress calling Sanitize twice is a known issue
// https://core.trac.wordpress.org/ticket/21989
$action = PostmanSession::getInstance()->getAction();
Expand Down
86 changes: 86 additions & 0 deletions Postman/PostmanLogFields.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php
class PostmanLogFields {

private $fields = array(
'success' => 'sanitize_text_field',
'from_header' => 'sanitize_text_field',
'to_header' => 'sanitize_text_field',
'cc_header' => 'sanitize_text_field',
'bcc_header' => 'sanitize_text_field',
'reply_to_header' => 'sanitize_text_field',
'transport_uri' => 'sanitize_text_field',
'original_to' => 'sanitize_text_field',
'original_subject' => 'sanitize_text_field',
'original_message' => null,
'original_headers' => 'sanitize_text_field',
'session_transcript' => 'sanitize_textarea_field',
);

private static $instance = null;

public static function get_instance() {
if ( ! self::$instance ) {
self::$instance = new static();
}

return self::$instance;
}

private function __construct()
{
$this->fields['original_message'] = array( $this, 'sanitize_message' );
}

public function get( $post_id ) {
$data = [];
foreach ( $this->fields as $key => $sanitize_callback ) {
$meta = get_post_meta( $post_id, $key, true );
$data[$key][] = $this->maybe_json( $meta );
}

return $data;
}

public function update( $post_id, $key, $value ) {
$sanitized = $this->sanitize( $key, $value );
$encode = $this->encode( $sanitized );

update_post_meta( $post_id, $key, $encode );
}

private function maybe_json( $json ) {
if ( $this->isJson( $json ) ) {
return implode( ',', json_decode( $json, true ) );
}

// Fallback
return maybe_unserialize( $json );
}

private function isJson($string) {
$result = json_decode($string, true);
$error = json_last_error();
return ( $error == JSON_ERROR_NONE && ! is_null($result) && $result != $string );
}

private function sanitize( $key, $value ) {
$callback = is_array( $value ) ? 'array_map' : 'call_user_func';

return $callback( $this->fields[$key], $value );
}

private function sanitize_message( $message ) {
$allowed_tags = wp_kses_allowed_html( 'post' );
$allowed_tags['style'] = array();

return wp_kses( $message, $allowed_tags );
}

private function encode( $value ) {
if ( is_array( $value ) ) {
return wp_json_encode( $value );
}

return $value;
}
}
9 changes: 9 additions & 0 deletions Postman/PostmanUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,15 @@ static function validateEmail( $email ) {
if ( ! isset( PostmanUtils::$emailValidator ) ) {
PostmanUtils::$emailValidator = new Postman_Zend_Validate_EmailAddress();
}
if ( strpos( $email, ',' ) !== false ) {
$emails = explode(',', $email);
$result = [];
foreach ( $emails as $email ) {
$result[] = PostmanUtils::$emailValidator->isValid( $email );
}

return ! in_array(false, $result );
}
return PostmanUtils::$emailValidator->isValid( $email );
}

Expand Down
2 changes: 1 addition & 1 deletion Postman/PostmanViewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function generateDefaultContent() {
}
function enqueueHomeScreenStylesheet() {
wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
wp_enqueue_script( 'postman_script' );
wp_enqueue_script( PostmanViewController::POSTMAN_SCRIPT );
}

/**
Expand Down
4 changes: 2 additions & 2 deletions postman-smtp.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Plugin Name: Post SMTP
* Plugin URI: https://wordpress.org/plugins/post-smtp/
* Description: Email not reliable? Post SMTP is the first and only WordPress SMTP plugin to implement OAuth 2.0 for Gmail, Hotmail and Yahoo Mail. Setup is a breeze with the Configuration Wizard and integrated Port Tester. Enjoy worry-free delivery even if your password changes!
* Version: 2.0.3
* Version: 2.0.4
* Author: Yehuda Hassine
* Text Domain: post-smtp
* Author URI: https://postmansmtp.com
Expand Down Expand Up @@ -44,7 +44,7 @@
define( 'POST_BASE', __FILE__ );
define( 'POST_PATH', __DIR__ );
define( 'POST_URL', plugins_url('', POST_BASE ) );
define( 'POST_SMTP_VER', '2.0.3' );
define( 'POST_SMTP_VER', '2.0.4' );

$postman_smtp_exist = in_array( 'postman-smtp/postman-smtp.php', (array) get_option( 'active_plugins', array() ) );
$required_php_version = version_compare( PHP_VERSION, '5.6.0', '<' );
Expand Down
9 changes: 6 additions & 3 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=yehuda@m
Tags: postman smtp, postman, smtp, email, mail, mailer, email log, oauth2, gmail, google apps, hotmail, yahoo, mandrill api, sendgrid api, elastic email, office365, mailgun
Requires at least: 3.9
Tested up to: 5.2.2
Stable tag: 2.0.3
Stable tag: 2.0.4
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Send, log and troubleshoot your Outgoing Email easily. Supports everything: SMTP, Gmail, Mailgun, Mandril, SendGrid, Elastic Email and OAuth 2.0!

== Description ==

= Version 2.0.3 released - Security Fix =
I fixed a few security issues - I still need to fix one more thing (minor), so another version bump will coming soon.
= Version 2.0.4 released - The plugin is more secure =
Final fixes to make it the best and secure mailer plugin for WordPress

= The Only SMTP plugin with chrome Notifications =
Get notified if your emails are failing inside your Chrome browser. [Download here](https://chrome.google.com/webstore/detail/post-smtp-notifications/npklmbkpbknkmbohdbpikeidiaekjoch?hl=en-US)
Expand Down Expand Up @@ -289,6 +289,9 @@ To avoid being flagged as spam, you need to prove your email isn't forged. On a

== Changelog ==

= 2.0.4 - 2019-08-27
* Updated: More security.

= 2.0.3 - 2019-08-21
* Fixed: A few security issues.

Expand Down

0 comments on commit f164971

Please sign in to comment.