forked from LiveCarta/LiveCartaWP
Changed source root directory
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
require_once ("registered-domain-libs-master/PHP/effectiveTLDs.inc.php");
|
||||
require_once ("registered-domain-libs-master/PHP/regDomain.inc.php");
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jasonhendriks
|
||||
*
|
||||
*/
|
||||
class PostmanPortTest {
|
||||
private $errstr;
|
||||
private $logger;
|
||||
private $hostname;
|
||||
public $hostnameDomainOnly;
|
||||
private $port;
|
||||
private $connectionTimeout;
|
||||
private $readTimeout;
|
||||
public $reportedHostname;
|
||||
public $reportedHostnameDomainOnly;
|
||||
public $protocol;
|
||||
public $secure;
|
||||
public $mitm;
|
||||
public $http;
|
||||
public $https;
|
||||
public $smtp;
|
||||
public $smtps;
|
||||
public $startTls;
|
||||
public $checkStartTls;
|
||||
public $authLogin;
|
||||
public $authPlain;
|
||||
public $authCrammd5;
|
||||
public $authXoauth;
|
||||
public $authNone;
|
||||
public $trySmtps;
|
||||
|
||||
//
|
||||
const SMTPS_PROTOCOL = 'SMTPS';
|
||||
|
||||
/**
|
||||
*/
|
||||
public function __construct($hostname, $port) {
|
||||
$this->logger = new PostmanLogger ( get_class ( $this ) );
|
||||
$this->hostname = $hostname;
|
||||
$this->hostnameDomainOnly = $this->getRegisteredDomain ( $hostname );
|
||||
$this->port = $port;
|
||||
$this->connectionTimeout = 10;
|
||||
$this->readTimeout = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the regDomain/getRegisteredDomain function
|
||||
*
|
||||
* @param mixed $domain
|
||||
* @return mixed
|
||||
*/
|
||||
private function getRegisteredDomain($hostname) {
|
||||
$registeredDomain = getRegisteredDomain ( $hostname );
|
||||
if ($registeredDomain === NULL) {
|
||||
return $hostname;
|
||||
}
|
||||
return $registeredDomain;
|
||||
}
|
||||
public function setConnectionTimeout($timeout) {
|
||||
$this->connectionTimeout = $timeout;
|
||||
$this->logger->trace ( $this->connectionTimeout );
|
||||
}
|
||||
public function setReadTimeout($timeout) {
|
||||
$this->readTimeout = $timeout;
|
||||
$this->logger->trace ( $this->readTimeout );
|
||||
}
|
||||
private function createStream($connectionString) {
|
||||
$stream = @stream_socket_client ( $connectionString, $errno, $errstr, $this->connectionTimeout );
|
||||
if ($stream) {
|
||||
$this->trace ( sprintf ( 'connected to %s', $connectionString ) );
|
||||
} else {
|
||||
$this->trace ( sprintf ( 'Could not connect to %s because %s [%s]', $connectionString, $errstr, $errno ) );
|
||||
}
|
||||
return $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param number $timeout
|
||||
* @return boolean
|
||||
*/
|
||||
public function genericConnectionTest() {
|
||||
$this->logger->trace ( 'testCustomConnection()' );
|
||||
// test if the port is open
|
||||
$connectionString = sprintf ( '%s:%s', $this->hostname, $this->port );
|
||||
$stream = $this->createStream ( $connectionString, $this->connectionTimeout );
|
||||
return null != $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a hostname, test if it has open ports
|
||||
*
|
||||
* @param string $hostname
|
||||
*/
|
||||
public function testHttpPorts() {
|
||||
$this->trace ( 'testHttpPorts()' );
|
||||
$connectionString = sprintf ( "https://%s:%s", $this->hostname, $this->port );
|
||||
try {
|
||||
$response = PostmanUtils::remotePost ( $connectionString );
|
||||
$this->trace ( 'wp_remote_retrieve_headers:' );
|
||||
$this->logger->trace ( wp_remote_retrieve_headers ( $response ) );
|
||||
$this->trace ( wp_remote_retrieve_response_code ( $response ) );
|
||||
$this->protocol = 'HTTPS';
|
||||
$this->http = true;
|
||||
$this->https = true;
|
||||
$this->secure = true;
|
||||
$this->reportedHostname = $this->hostname;
|
||||
$this->reportedHostnameDomainOnly = $this->getRegisteredDomain ( $this->hostname );
|
||||
return true;
|
||||
} catch ( Exception $e ) {
|
||||
$this->debug ( 'return false' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a hostname, test if it has open ports
|
||||
*
|
||||
* @param string $hostname
|
||||
*/
|
||||
public function testSmtpPorts() {
|
||||
$this->logger->trace ( 'testSmtpPorts()' );
|
||||
if ($this->port == 8025) {
|
||||
$this->debug ( 'Executing test code for port 8025' );
|
||||
$this->protocol = 'SMTP';
|
||||
$this->smtp = true;
|
||||
$this->authNone = 'true';
|
||||
return true;
|
||||
}
|
||||
$connectionString = sprintf ( "%s:%s", $this->hostname, $this->port );
|
||||
$success = $this->talkToMailServer ( $connectionString, $this->connectionTimeout, $this->readTimeout );
|
||||
if ($success) {
|
||||
$this->protocol = 'SMTP';
|
||||
if (! ($this->authCrammd5 || $this->authLogin || $this->authPlain || $this->authXoauth)) {
|
||||
$this->authNone = true;
|
||||
}
|
||||
} else {
|
||||
$this->trySmtps = true;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a hostname, test if it has open ports
|
||||
*
|
||||
* @param string $hostname
|
||||
*/
|
||||
public function testSmtpsPorts() {
|
||||
$this->logger->trace ( 'testSmtpsPorts()' );
|
||||
$connectionString = sprintf ( "ssl://%s:%s", $this->hostname, $this->port );
|
||||
$success = $this->talkToMailServer ( $connectionString, $this->connectionTimeout, $this->readTimeout );
|
||||
if ($success) {
|
||||
if (! ($this->authCrammd5 || $this->authLogin || $this->authPlain || $this->authXoauth)) {
|
||||
$this->authNone = true;
|
||||
}
|
||||
$this->protocol = self::SMTPS_PROTOCOL;
|
||||
$this->smtps = true;
|
||||
$this->secure = true;
|
||||
}
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a hostname, test if it has open ports
|
||||
*
|
||||
* @param string $hostname
|
||||
*/
|
||||
private function talkToMailServer($connectionString) {
|
||||
$this->logger->trace ( 'talkToMailServer()' );
|
||||
$stream = $this->createStream ( $connectionString, $this->connectionTimeout );
|
||||
if ($stream) {
|
||||
$serverName = PostmanUtils::postmanGetServerName ();
|
||||
@stream_set_timeout ( $stream, $this->readTimeout );
|
||||
// see http://php.net/manual/en/transports.inet.php#113244
|
||||
// see http://php.net/stream_socket_enable_crypto
|
||||
$result = $this->readSmtpResponse ( $stream );
|
||||
if ($result) {
|
||||
$this->reportedHostname = $result;
|
||||
$this->reportedHostnameDomainOnly = $this->getRegisteredDomain ( $this->reportedHostname );
|
||||
$this->logger->trace ( sprintf ( 'comparing %s with %s', $this->reportedHostnameDomainOnly, $this->hostnameDomainOnly ) );
|
||||
$this->mitm = true;
|
||||
// MITM exceptions
|
||||
if ($this->reportedHostnameDomainOnly == 'google.com' && $this->hostnameDomainOnly == 'gmail.com') {
|
||||
$this->mitm = false;
|
||||
} elseif ($this->reportedHostnameDomainOnly == 'hotmail.com' && $this->hostnameDomainOnly == 'live.com') {
|
||||
$this->mitm = false;
|
||||
} elseif ($this->reportedHostnameDomainOnly == $this->hostnameDomainOnly) {
|
||||
$this->mitm = false;
|
||||
}
|
||||
$this->debug ( sprintf ( 'domain name: %s (%s)', $this->reportedHostname, $this->reportedHostnameDomainOnly ) );
|
||||
$this->sendSmtpCommand ( $stream, sprintf ( 'EHLO %s', $serverName ) );
|
||||
$this->readSmtpResponse ( $stream );
|
||||
if ($this->checkStartTls) {
|
||||
$this->sendSmtpCommand ( $stream, 'STARTTLS' );
|
||||
$this->readSmtpResponse ( $stream );
|
||||
$starttlsSuccess = @stream_socket_enable_crypto ( $stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT );
|
||||
if ($starttlsSuccess) {
|
||||
$this->startTls = true;
|
||||
$this->secure = true;
|
||||
$this->sendSmtpCommand ( $stream, sprintf ( 'EHLO %s', $serverName ) );
|
||||
$this->readSmtpResponse ( $stream );
|
||||
} else {
|
||||
$this->error ( 'starttls failed' );
|
||||
}
|
||||
}
|
||||
fclose ( $stream );
|
||||
$this->debug ( 'return true' );
|
||||
return true;
|
||||
} else {
|
||||
fclose ( $stream );
|
||||
$this->debug ( 'return false' );
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private function sendSmtpCommand($stream, $message) {
|
||||
$this->trace ( 'tx: ' . $message );
|
||||
fputs ( $stream, $message . "\r\n" );
|
||||
}
|
||||
private function readSmtpResponse($stream) {
|
||||
$result = '';
|
||||
while ( ($line = fgets ( $stream )) !== false ) {
|
||||
$this->trace ( 'rx: ' . $line );
|
||||
if (preg_match ( '/^250.AUTH/', $line )) {
|
||||
// $this->debug ( '250-AUTH' );
|
||||
if (preg_match ( '/\\sLOGIN\\s/', $line )) {
|
||||
$this->authLogin = true;
|
||||
$this->debug ( 'authLogin' );
|
||||
}
|
||||
if (preg_match ( '/\\sPLAIN\\s/', $line )) {
|
||||
$this->authPlain = true;
|
||||
$this->debug ( 'authPlain' );
|
||||
}
|
||||
if (preg_match ( '/\\sCRAM-MD5\\s/', $line )) {
|
||||
$this->authCrammd5 = true;
|
||||
$this->debug ( 'authCrammd5' );
|
||||
}
|
||||
if (preg_match ( '/\\sXOAUTH.\\s/', $line )) {
|
||||
$this->authXoauth = true;
|
||||
$this->debug ( 'authXoauth' );
|
||||
}
|
||||
if (preg_match ( '/\\sANONYMOUS\\s/', $line )) {
|
||||
// Postman treats ANONYMOUS login as no authentication.
|
||||
$this->authNone = true;
|
||||
$this->debug ( 'authAnonymous => authNone' );
|
||||
}
|
||||
// done
|
||||
$result = 'auth';
|
||||
} elseif (preg_match ( '/STARTTLS/', $line )) {
|
||||
$result = 'starttls';
|
||||
$this->checkStartTls = true;
|
||||
$this->debug ( 'starttls' );
|
||||
} elseif (preg_match ( '/^220.(.*?)\\s/', $line, $matches )) {
|
||||
if (empty ( $result ))
|
||||
$result = $matches [1];
|
||||
}
|
||||
if (preg_match ( '/^\d\d\d\\s/', $line )) {
|
||||
// always exist on last server response line
|
||||
// $this->debug ( 'exit' );
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function getErrorMessage() {
|
||||
return $this->errstr;
|
||||
}
|
||||
private function trace($message) {
|
||||
$this->logger->trace ( sprintf ( '%s:%s => %s', $this->hostname, $this->port, $message ) );
|
||||
}
|
||||
private function debug($message) {
|
||||
$this->logger->debug ( sprintf ( '%s:%s => %s', $this->hostname, $this->port, $message ) );
|
||||
}
|
||||
private function error($message) {
|
||||
$this->logger->error ( sprintf ( '%s:%s => %s', $this->hostname, $this->port, $message ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class PostmanConnectivityTestController {
|
||||
|
||||
const PORT_TEST_SLUG = 'postman/port_test';
|
||||
|
||||
// logging
|
||||
private $logger;
|
||||
|
||||
// Holds the values to be used in the fields callbacks
|
||||
private $rootPluginFilenameAndPath;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param mixed $rootPluginFilenameAndPath
|
||||
*/
|
||||
public function __construct( $rootPluginFilenameAndPath ) {
|
||||
assert( ! empty( $rootPluginFilenameAndPath ) );
|
||||
assert( PostmanUtils::isAdmin() );
|
||||
assert( is_admin() );
|
||||
|
||||
$this->logger = new PostmanLogger( get_class( $this ) );
|
||||
$this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
|
||||
|
||||
PostmanUtils::registerAdminMenu( $this, 'addPortTestSubmenu' );
|
||||
|
||||
// hook on the init event
|
||||
add_action( 'init', array(
|
||||
$this,
|
||||
'on_init',
|
||||
) );
|
||||
|
||||
// initialize the scripts, stylesheets and form fields
|
||||
add_action( 'admin_init', array(
|
||||
$this,
|
||||
'on_admin_init',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Functions to execute on the init event
|
||||
*
|
||||
* "Typically used by plugins to initialize. The current user is already authenticated by this time."
|
||||
* ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request
|
||||
*/
|
||||
public function on_init() {
|
||||
// register Ajax handlers
|
||||
new PostmanPortTestAjaxController();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires on the admin_init method
|
||||
*/
|
||||
public function on_admin_init() {
|
||||
$this->registerStylesAndScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and add settings
|
||||
*/
|
||||
private function registerStylesAndScripts() {
|
||||
if ( $this->logger->isTrace() ) {
|
||||
$this->logger->trace( 'registerStylesAndScripts()' );
|
||||
}
|
||||
// register the stylesheet and javascript external resources
|
||||
$pluginData = apply_filters( 'postman_get_plugin_metadata', null );
|
||||
wp_register_script( 'postman_port_test_script', plugins_url( 'Postman/Postman-Connectivity-Test/postman_port_test.js', $this->rootPluginFilenameAndPath ), array(
|
||||
PostmanViewController::JQUERY_SCRIPT,
|
||||
'jquery_validation',
|
||||
PostmanViewController::POSTMAN_SCRIPT,
|
||||
'sprintf',
|
||||
), $pluginData ['version'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Email Test screen
|
||||
*/
|
||||
public function addPortTestSubmenu() {
|
||||
$page = add_submenu_page( ' ', sprintf( __( '%s Setup', 'post-smtp' ), __( 'Postman SMTP', 'post-smtp' ) ), __( 'Postman SMTP', 'post-smtp' ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConnectivityTestController::PORT_TEST_SLUG, array(
|
||||
$this,
|
||||
'outputPortTestContent',
|
||||
) );
|
||||
// When the plugin options page is loaded, also load the stylesheet
|
||||
add_action( 'admin_print_styles-' . $page, array(
|
||||
$this,
|
||||
'enqueuePortTestResources',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
function enqueuePortTestResources() {
|
||||
wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
|
||||
wp_enqueue_script( 'postman_port_test_script' );
|
||||
$warning = __( 'Warning', 'post-smtp' );
|
||||
|
||||
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() {
|
||||
wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_port_test', array(
|
||||
'in_progress' => _x( 'Checking..', 'The "please wait" message', 'post-smtp' ),
|
||||
'open' => _x( 'Open', 'The port is open', 'post-smtp' ),
|
||||
'closed' => _x( 'Closed', 'The port is closed', 'post-smtp' ),
|
||||
'yes' => __( 'Yes', 'post-smtp' ),
|
||||
'no' => __( 'No', 'post-smtp' ),
|
||||
/* translators: where %d is a port number */
|
||||
'blocked' => __( 'No outbound route between this site and the Internet on Port %d.', 'post-smtp' ),
|
||||
/* translators: where %d is a port number and %s is a hostname */
|
||||
'try_dif_smtp' => __( 'Port %d is open, but not to %s.', 'post-smtp' ),
|
||||
/* translators: where %d is the port number and %s is the hostname */
|
||||
'success' => __( 'Port %d can be used for SMTP to %s.', 'post-smtp' ),
|
||||
'mitm' => sprintf( '%s: %s', __( 'Warning', 'post-smtp' ), __( 'connected to %1$s instead of %2$s.', 'post-smtp' ) ),
|
||||
/* translators: where %d is a port number and %s is the URL for the Postman Gmail Extension */
|
||||
'https_success' => __( 'Port %d can be used with the %s.', 'post-smtp' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the settings option array and print one of its values
|
||||
*/
|
||||
public function port_test_hostname_callback() {
|
||||
$hostname = PostmanTransportRegistry::getInstance()->getSelectedTransport()->getHostname();
|
||||
if ( empty( $hostname ) ) {
|
||||
$hostname = PostmanTransportRegistry::getInstance()->getActiveTransport()->getHostname();
|
||||
}
|
||||
printf( '<input type="text" id="input_hostname" name="postman_options[hostname]" value="%s" size="40" class="required"/>', $hostname );
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function outputPortTestContent() {
|
||||
print '<div class="wrap">';
|
||||
|
||||
wp_nonce_field('post-smtp', 'security');
|
||||
|
||||
PostmanViewController::outputChildPageHeader( __( 'Connectivity Test', 'post-smtp' ) );
|
||||
|
||||
print '<p>';
|
||||
print __( 'This test determines which well-known ports are available for Postman to use.', 'post-smtp' );
|
||||
print '<form id="port_test_form_id" method="post">';
|
||||
|
||||
wp_nonce_field('post-smtp', 'security' );
|
||||
|
||||
printf( '<label for="hostname">%s</label>', __( 'Outgoing Mail Server Hostname', 'post-smtp' ) );
|
||||
$this->port_test_hostname_callback();
|
||||
submit_button( _x( 'Begin Test', 'Button Label', 'post-smtp' ), 'primary', 'begin-port-test', true );
|
||||
print '</form>';
|
||||
print '<table id="connectivity_test_table">';
|
||||
print sprintf( '<tr><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th colspan="5">%s</th></tr>', __( 'Transport', 'post-smtp' ), _x( 'Socket', 'A socket is the network term for host and port together', 'post-smtp' ), __( 'Status', 'post-smtp' ) . '<sup>*</sup>', __( 'Service Available', 'post-smtp' ), __( 'Server ID', 'post-smtp' ), __( 'Authentication', 'post-smtp' ) );
|
||||
print sprintf( '<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>', 'None', 'Login', 'Plain', 'CRAM-MD5', 'OAuth 2.0' );
|
||||
$sockets = PostmanTransportRegistry::getInstance()->getSocketsForSetupWizardToProbe();
|
||||
foreach ( $sockets as $socket ) {
|
||||
if ( $socket ['smtp'] ) {
|
||||
print sprintf( '<tr id="%s"><th class="name">%s</th><td class="socket">%s:%s</td><td class="firewall resettable">-</td><td class="service resettable">-</td><td class="reported_id resettable">-</td><td class="auth_none resettable">-</td><td class="auth_login resettable">-</td><td class="auth_plain resettable">-</td><td class="auth_crammd5 resettable">-</td><td class="auth_xoauth2 resettable">-</td></tr>', $socket ['id'], $socket ['transport_name'], $socket ['host'], $socket ['port'] );
|
||||
} else {
|
||||
print sprintf( '<tr id="%s"><th class="name">%s</th><td class="socket">%s:%s</td><td class="firewall resettable">-</td><td class="service resettable">-</td><td class="reported_id resettable">-</td><td colspan="5">%s</td></tr>', $socket ['id'], $socket ['transport_name'], $socket ['host'], $socket ['port'], __( 'n/a', 'post-smtp' ) );
|
||||
}
|
||||
}
|
||||
print '</table>';
|
||||
/* Translators: Where %s is the name of the service providing Internet connectivity test */
|
||||
printf( '<p class="portquiz" style="display:none; font-size:0.8em">* %s</p>', sprintf( __( 'According to %s', 'post-smtp' ), '<a target="_blank" href="http://portquiz.net">portquiz.net</a>' ) );
|
||||
printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
|
||||
print '<section id="conclusion" style="display:none">';
|
||||
print sprintf( '<h3>%s:</h3>', __( 'Summary', 'post-smtp' ) );
|
||||
print '<ol class="conclusion">';
|
||||
print '</ol>';
|
||||
print '</section>';
|
||||
print '<section id="blocked-port-help" style="display:none">';
|
||||
print sprintf( '<p><b>%s</b></p>', __( 'A test with <span style="color:red">"No"</span> Service Available indicates one or more of these issues:', 'post-smtp' ) );
|
||||
print '<ol>';
|
||||
printf( '<li>%s</li>', __( 'Your web host has placed a firewall between this site and the Internet', 'post-smtp' ) );
|
||||
printf( '<li>%s</li>', __( 'The SMTP hostname is wrong or the mail server does not provide service on this port', 'post-smtp' ) );
|
||||
/* translators: where (1) is the URL and (2) is the system */
|
||||
$systemBlockMessage = __( 'Your <a href="%1$s">%2$s configuration</a> is preventing outbound connections', 'post-smtp' );
|
||||
printf( '<li>%s</li>', sprintf( $systemBlockMessage, 'http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen', 'PHP' ) );
|
||||
printf( '<li>%s</li>', sprintf( $systemBlockMessage, 'http://wp-mix.com/disable-external-url-requests/', 'WordPress' ) );
|
||||
print '</ol></p>';
|
||||
print sprintf( '<p><b>%s</b></p>', __( 'If the issues above can not be resolved, your last option is to configure Postman to use an email account managed by your web host with an SMTP server managed by your web host.', 'post-smtp' ) );
|
||||
print '</section>';
|
||||
print '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jasonhendriks
|
||||
*/
|
||||
class PostmanPortTestAjaxController {
|
||||
private $logger;
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param PostmanOptions $options
|
||||
*/
|
||||
function __construct() {
|
||||
$this->logger = new PostmanLogger( get_class( $this ) );
|
||||
PostmanUtils::registerAjaxHandler( 'postman_get_hosts_to_test', $this, 'getPortsToTestViaAjax' );
|
||||
PostmanUtils::registerAjaxHandler( 'postman_wizard_port_test', $this, 'runSmtpTest' );
|
||||
PostmanUtils::registerAjaxHandler( 'postman_wizard_port_test_smtps', $this, 'runSmtpsTest' );
|
||||
PostmanUtils::registerAjaxHandler( 'postman_port_quiz_test', $this, 'runPortQuizTest' );
|
||||
PostmanUtils::registerAjaxHandler( 'postman_test_port', $this, 'runSmtpTest' );
|
||||
PostmanUtils::registerAjaxHandler( 'postman_test_smtps', $this, 'runSmtpsTest' );
|
||||
}
|
||||
|
||||
/**
|
||||
* This Ajax function determines which hosts/ports to test in both the Wizard Connectivity Test and direct Connectivity Test
|
||||
*
|
||||
* Given a single outgoing smtp server hostname, return an array of host/port
|
||||
* combinations to run the connectivity test on
|
||||
*/
|
||||
function getPortsToTestViaAjax() {
|
||||
|
||||
check_admin_referer('post-smtp', 'security');
|
||||
|
||||
if( !current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_NAME ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'Message' => 'Unauthorized.'
|
||||
),
|
||||
401
|
||||
);
|
||||
}
|
||||
|
||||
$queryHostname = PostmanUtils::getRequestParameter( 'hostname' );
|
||||
// originalSmtpServer is what SmtpDiscovery thinks the SMTP server should be, given an email address
|
||||
$originalSmtpServer = PostmanUtils::getRequestParameter( 'original_smtp_server' );
|
||||
if ( $this->logger->isDebug() ) {
|
||||
$this->logger->debug( 'Probing available transports for sockets against hostname ' . $queryHostname );
|
||||
}
|
||||
$sockets = PostmanTransportRegistry::getInstance()->getSocketsForSetupWizardToProbe( $queryHostname, $originalSmtpServer );
|
||||
$response = array(
|
||||
'hosts' => $sockets,
|
||||
);
|
||||
wp_send_json_success( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* This Ajax function retrieves whether a TCP port is open or not
|
||||
*/
|
||||
function runPortQuizTest() {
|
||||
|
||||
check_admin_referer('post-smtp', 'security');
|
||||
|
||||
if( !current_user_can( Postman::MANAGE_POSTMAN_CAPABILITY_NAME ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'Message' => 'Unauthorized.'
|
||||
),
|
||||
401
|
||||
);
|
||||
}
|
||||
|
||||
$hostname = 'portquiz.net';
|
||||
$port = intval( PostmanUtils::getRequestParameter( 'port' ) );
|
||||
$this->logger->debug( 'testing TCP port: hostname ' . $hostname . ' port ' . $port );
|
||||
$portTest = new PostmanPortTest( $hostname, $port );
|
||||
$success = $portTest->genericConnectionTest();
|
||||
$this->buildResponse( $hostname, $port, $portTest, $success );
|
||||
}
|
||||
|
||||
/**
|
||||
* This Ajax function retrieves whether a TCP port is open or not.
|
||||
* This is called by both the Wizard and Port Test
|
||||
*/
|
||||
function runSmtpTest() {
|
||||
|
||||
check_admin_referer('post-smtp', 'security');
|
||||
|
||||
if( !current_user_can( 'delete_users' ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'Message' => 'Unauthorized.'
|
||||
),
|
||||
401
|
||||
);
|
||||
}
|
||||
|
||||
$hostname = trim( PostmanUtils::getRequestParameter( 'hostname' ) );
|
||||
$port = intval( PostmanUtils::getRequestParameter( 'port' ) );
|
||||
$transport = empty( PostmanUtils::getRequestParameter( 'transport' ) ) ? '' : trim( PostmanUtils::getRequestParameter( 'transport' ) );
|
||||
$timeout = PostmanUtils::getRequestParameter( 'timeout' );
|
||||
$logo_url = PostmanUtils::getRequestParameter( 'logo_url' );
|
||||
$data['logo_url'] = $logo_url;
|
||||
|
||||
$this->logger->trace( $timeout );
|
||||
$portTest = new PostmanPortTest( $hostname, $port );
|
||||
if ( isset( $timeout ) ) {
|
||||
$portTest->setConnectionTimeout( intval( $timeout ) );
|
||||
$portTest->setReadTimeout( intval( $timeout ) );
|
||||
}
|
||||
if ( $port != 443 ) {
|
||||
$this->logger->debug( sprintf( 'testing SMTP socket %s:%s (%s)', $hostname, $port, $transport ) );
|
||||
$success = $portTest->testSmtpPorts();
|
||||
} else {
|
||||
$this->logger->debug( sprintf( 'testing HTTPS socket %s:%s (%s)', $hostname, $port, $transport ) );
|
||||
$success = $portTest->testHttpPorts();
|
||||
}
|
||||
|
||||
$this->buildResponse( $hostname, $port, $portTest, $success, $transport, $data );
|
||||
}
|
||||
/**
|
||||
* This Ajax function retrieves whether a TCP port is open or not
|
||||
*/
|
||||
function runSmtpsTest() {
|
||||
|
||||
check_admin_referer('post-smtp', 'security');
|
||||
|
||||
if( !current_user_can( 'delete_users' ) ) {
|
||||
wp_send_json_error(
|
||||
array(
|
||||
'Message' => 'Unauthorized.'
|
||||
),
|
||||
401
|
||||
);
|
||||
}
|
||||
|
||||
$hostname = trim( PostmanUtils::getRequestParameter( 'hostname' ) );
|
||||
$port = intval( PostmanUtils::getRequestParameter( 'port' ) );
|
||||
$transport = empty( PostmanUtils::getRequestParameter( 'transport' ) ) ? '' : trim( PostmanUtils::getRequestParameter( 'transport' ) );
|
||||
$transportName = empty( PostmanUtils::getRequestParameter( 'transport_name' ) ) ? '' : trim( PostmanUtils::getRequestParameter( 'transport_name' ) );
|
||||
$logo_url = PostmanUtils::getRequestParameter( 'logo_url' );
|
||||
$data['logo_url'] = $logo_url;
|
||||
|
||||
$this->logger->debug( sprintf( 'testing SMTPS socket %s:%s (%s)', $hostname, $port, $transport ) );
|
||||
$portTest = new PostmanPortTest( $hostname, $port );
|
||||
$portTest->transportName = $transportName;
|
||||
$success = $portTest->testSmtpsPorts();
|
||||
$this->buildResponse( $hostname, $port, $portTest, $success, $transport, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param mixed $hostname
|
||||
* @param mixed $port
|
||||
* @param mixed $success
|
||||
* @since 2.1 @param mixed $data for extra fields
|
||||
*/
|
||||
private function buildResponse( $hostname, $port, PostmanPortTest $portTest, $success, $transport = '', $data = array() ) {
|
||||
$this->logger->debug( sprintf( 'testing port result for %s:%s success=%s', $hostname, $port, $success ) );
|
||||
$response = array(
|
||||
'hostname' => $hostname,
|
||||
'hostname_domain_only' => $portTest->hostnameDomainOnly,
|
||||
'port' => $port,
|
||||
'protocol' => $portTest->protocol,
|
||||
'secure' => ($portTest->secure),
|
||||
'mitm' => ($portTest->mitm),
|
||||
'reported_hostname' => $portTest->reportedHostname,
|
||||
'reported_hostname_domain_only' => $portTest->reportedHostnameDomainOnly,
|
||||
'message' => $portTest->getErrorMessage(),
|
||||
'start_tls' => $portTest->startTls,
|
||||
'auth_plain' => $portTest->authPlain,
|
||||
'auth_login' => $portTest->authLogin,
|
||||
'auth_crammd5' => $portTest->authCrammd5,
|
||||
'auth_xoauth' => $portTest->authXoauth,
|
||||
'auth_none' => $portTest->authNone,
|
||||
'try_smtps' => $portTest->trySmtps,
|
||||
'success' => $success,
|
||||
'transport' => $transport,
|
||||
'data' => $data
|
||||
);
|
||||
|
||||
$this->logger->trace( 'Ajax response:' );
|
||||
$this->logger->trace( $response );
|
||||
if ( $success ) {
|
||||
wp_send_json_success( $response );
|
||||
} else {
|
||||
wp_send_json_error( $response );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
postman_begin_test_button_id = 'input#begin-port-test';
|
||||
|
||||
jQuery(document).ready(function() {
|
||||
var elHostname = jQuery(postman_begin_test_button_id);
|
||||
jQuery(post_smtp_localize.postman_hostname_element_name).focus();
|
||||
elHostname.click(function() {
|
||||
valid = jQuery('#port_test_form_id').valid();
|
||||
if (!valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize the view for a new test
|
||||
elHostname.attr('disabled', 'disabled');
|
||||
hide('#conclusion');
|
||||
hide('#blocked-port-help');
|
||||
jQuery('ol.conclusion').html('');
|
||||
showLoaderIcon();
|
||||
|
||||
var $elTestingTable = jQuery('#connectivity_test_table');
|
||||
$elTestingTable.show();
|
||||
show('.portquiz');
|
||||
|
||||
var hostname = jQuery(post_smtp_localize.postman_hostname_element_name).val();
|
||||
var data = {
|
||||
'action' : 'postman_get_hosts_to_test',
|
||||
'hostname' : hostname,
|
||||
'security' : jQuery('#security').val(),
|
||||
};
|
||||
|
||||
totalPortsTested = 0;
|
||||
portsToBeTested = 0;
|
||||
|
||||
jQuery.post(ajaxurl, data, function(response) {
|
||||
if (postmanValidateAjaxResponseWithPopup(response)) {
|
||||
handleHostsToCheckResponse(response.data);
|
||||
}
|
||||
}).fail(function(response) {
|
||||
ajaxFailed(response);
|
||||
});
|
||||
|
||||
//
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles the response from the server of the list of sockets to check.
|
||||
*
|
||||
* @param hostname
|
||||
* @param response
|
||||
*/
|
||||
function handleHostsToCheckResponse(response) {
|
||||
for ( var x in response.hosts) {
|
||||
var id = response.hosts[x].id;
|
||||
var transportSlug = response.hosts[x].transport_id;
|
||||
var hostname = response.hosts[x].host;
|
||||
var port = response.hosts[x].port
|
||||
var cell = 'tr#' + id + " td.socket";
|
||||
var testEl = jQuery(cell);
|
||||
testEl.html('<span>' + hostname + ':' + port + '</span>');
|
||||
portQuizTest(response.hosts[x], hostname, port);
|
||||
}
|
||||
}
|
||||
|
||||
function portQuizTest(socket, hostname, port) {
|
||||
resetView(socket.id);
|
||||
portsToBeTested += 1;
|
||||
var cell = 'tr#' + socket.id + " td.firewall";
|
||||
var testEl = jQuery(cell);
|
||||
testEl.html('<span style="color:blue">' + postman_port_test.in_progress
|
||||
+ '</span>');
|
||||
var data = {
|
||||
'action' : 'postman_port_quiz_test',
|
||||
'hostname' : hostname,
|
||||
'port' : port,
|
||||
'security' : jQuery('#security').val(),
|
||||
};
|
||||
jQuery.post(
|
||||
ajaxurl,
|
||||
data,
|
||||
function(response) {
|
||||
if (postmanValidateAjaxResponseWithPopup(response)) {
|
||||
if (response.success) {
|
||||
testEl.html('<span style="color:green">'
|
||||
+ postman_port_test.open + '</span>');
|
||||
// start the next test
|
||||
} else {
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_port_test.closed + '</span>');
|
||||
}
|
||||
firstServiceTest(socket, hostname, port, response.success);
|
||||
}
|
||||
}).fail(
|
||||
function(response) {
|
||||
totalPortsTested += 1;
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_email_test.ajax_error + "</span>");
|
||||
enableButtonCheck();
|
||||
});
|
||||
}
|
||||
function firstServiceTest(socket, hostname, port, open) {
|
||||
var cell = 'tr#' + socket.id + " td.service";
|
||||
var testEl = jQuery(cell);
|
||||
testEl.html('<span style="color:blue">' + postman_port_test.in_progress
|
||||
+ '</span>');
|
||||
var data = {
|
||||
'action' : 'postman_test_port',
|
||||
'hostname' : hostname,
|
||||
'port' : port,
|
||||
'security' : jQuery('#security').val(),
|
||||
};
|
||||
jQuery
|
||||
.post(
|
||||
ajaxurl,
|
||||
data,
|
||||
function(response) {
|
||||
if (postmanValidateAjaxResponseWithPopup(response)) {
|
||||
if (response.success) {
|
||||
totalPortsTested += 1;
|
||||
if (port == 443) {
|
||||
// API test
|
||||
testEl
|
||||
.html('<span style="color:green">🔒 '
|
||||
+ response.data.protocol
|
||||
+ '</span>');
|
||||
var cell = 'tr#' + socket.id
|
||||
+ " td.reported_id";
|
||||
var p443El = jQuery(cell);
|
||||
if (response.data.reported_hostname_domain_only) {
|
||||
p443El
|
||||
.html('<span>'
|
||||
+ response.data.reported_hostname_domain_only
|
||||
+ '</span>');
|
||||
}
|
||||
addConclusion(sprintf(
|
||||
postman_port_test.https_success,
|
||||
response.data.port,
|
||||
socket.transport_name), true,
|
||||
response.data.secure);
|
||||
} else {
|
||||
// SMTP test
|
||||
testEl.html('<span style="color:green">'
|
||||
+ response.data.protocol
|
||||
+ '</span>');
|
||||
inspectResponse(socket.id, response.data,
|
||||
port);
|
||||
var message = sprintf(postman_port_test.success,
|
||||
port, hostname);
|
||||
if (response.data.mitm) {
|
||||
message += ' <span style="background-color:yellow">'
|
||||
+ sprintf(
|
||||
postman_port_test.mitm,
|
||||
response.data.reported_hostname_domain_only,
|
||||
response.data.hostname_domain_only)
|
||||
+ '</span>';
|
||||
}
|
||||
addConclusion(message, true,
|
||||
response.data.secure);
|
||||
}
|
||||
} else {
|
||||
if (port == 443) {
|
||||
// API test
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_port_test.no + '</span>');
|
||||
totalPortsTested += 1;
|
||||
var p443El = jQuery(cell);
|
||||
addConclusion(sprintf(postman_port_test.try_dif_smtp,
|
||||
port, hostname), false,
|
||||
response.data.secure);
|
||||
} else {
|
||||
if (response.data.try_smtps) {
|
||||
// start the SMTPS test
|
||||
portTest3(socket, hostname, port, open);
|
||||
} else {
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_port_test.no + '</span>');
|
||||
totalPortsTested += 1;
|
||||
addConclusion(sprintf(
|
||||
postman_port_test.blocked, port),
|
||||
false, response.data.secure);
|
||||
show('#blocked-port-help');
|
||||
}
|
||||
}
|
||||
}
|
||||
enableButtonCheck();
|
||||
}
|
||||
}).fail(
|
||||
function(response) {
|
||||
totalPortsTested += 1;
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_email_test.ajax_error + "</span>");
|
||||
enableButtonCheck();
|
||||
});
|
||||
}
|
||||
function portTest3(socket, hostname, port, open) {
|
||||
var cell = 'tr#' + socket.id + " td.service";
|
||||
var testEl = jQuery(cell);
|
||||
testEl.html('<span style="color:blue">' + postman_port_test.in_progress
|
||||
+ '</span>');
|
||||
var data = {
|
||||
'action' : 'postman_test_smtps',
|
||||
'hostname' : hostname,
|
||||
'port' : port,
|
||||
'security' : jQuery('#security').val(),
|
||||
};
|
||||
jQuery
|
||||
.post(
|
||||
ajaxurl,
|
||||
data,
|
||||
function(response) {
|
||||
if (postmanValidateAjaxResponseWithPopup(response)) {
|
||||
if (response.success) {
|
||||
if (response.data.protocol == 'SMTPS') {
|
||||
testEl
|
||||
.html('<span style="color:green">🔒 '
|
||||
+ response.data.protocol
|
||||
+ '</span>');
|
||||
} else {
|
||||
|
||||
testEl.html('<span style="color:green">'
|
||||
+ response.data.protocol
|
||||
+ '</span>');
|
||||
}
|
||||
inspectResponse(socket.id, response.data, port);
|
||||
var message = sprintf(postman_port_test.success,
|
||||
port, hostname);
|
||||
if (response.data.mitm) {
|
||||
message += ' <span style="background-color:yellow">'
|
||||
+ sprintf(
|
||||
postman_port_test.mitm,
|
||||
response.data.reported_hostname_domain_only,
|
||||
response.data.hostname_domain_only
|
||||
+ '</span>');
|
||||
}
|
||||
addConclusion(message, true,
|
||||
response.data.secure);
|
||||
} else {
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_port_test.no + '</span>');
|
||||
show('#blocked-port-help');
|
||||
if (open) {
|
||||
addConclusion(sprintf(postman_port_test.try_dif_smtp,
|
||||
port, hostname), false,
|
||||
response.data.secure);
|
||||
} else {
|
||||
addConclusion(sprintf(postman_port_test.blocked,
|
||||
port), false, response.data.secure);
|
||||
}
|
||||
}
|
||||
totalPortsTested += 1;
|
||||
enableButtonCheck();
|
||||
}
|
||||
}).fail(
|
||||
function(response) {
|
||||
totalPortsTested += 1;
|
||||
testEl.html('<span style="color:red">'
|
||||
+ postman_email_test.ajax_error + "</span>");
|
||||
enableButtonCheck();
|
||||
});
|
||||
}
|
||||
function enableButtonCheck() {
|
||||
if (totalPortsTested >= portsToBeTested) {
|
||||
enable(postman_begin_test_button_id);
|
||||
hideLoaderIcon();
|
||||
jQuery(post_smtp_localize.postman_hostname_element_name).focus();
|
||||
}
|
||||
}
|
||||
function inspectResponse(id, response, port) {
|
||||
var cell = 'tr#' + id + " td.reported_id";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.reported_hostname_domain_only) {
|
||||
testEl.html('<span>' + response.reported_hostname_domain_only
|
||||
+ '</span>');
|
||||
}
|
||||
var cell = 'tr#' + id + " td.service";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.protocol == 'SMTPS') {
|
||||
testEl.html('<span style="color:green">🔒 SMTPS</span>');
|
||||
} else if (response.start_tls) {
|
||||
testEl.html('<span style="color:green">🔒 SMTP-STARTTLS</span>');
|
||||
} else {
|
||||
testEl.html('<span style="color:green">SMTP</span>');
|
||||
}
|
||||
var cell = 'tr#' + id + " td.auth_none";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.auth_none) {
|
||||
testEl.html('<span style="color:green">' + postman_port_test.yes + '</span>');
|
||||
} else {
|
||||
testEl.html('<span>' + postman_port_test.no + '</span>');
|
||||
}
|
||||
var cell = 'tr#' + id + " td.auth_plain";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.auth_plain) {
|
||||
testEl.html('<span style="color:green">' + postman_port_test.yes + '</span>');
|
||||
} else {
|
||||
testEl.html('<span>' + postman_port_test.no + '</span>');
|
||||
}
|
||||
var cell = 'tr#' + id + " td.auth_login";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.auth_login) {
|
||||
testEl.html('<span style="color:green">' + postman_port_test.yes + '</span>');
|
||||
} else {
|
||||
testEl.html('<span>' + postman_port_test.no + '</span>');
|
||||
}
|
||||
var cell = 'tr#' + id + " td.auth_crammd5";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.auth_crammd5) {
|
||||
testEl.html('<span style="color:green">' + postman_port_test.yes + '</span>');
|
||||
} else {
|
||||
testEl.html('<span>' + postman_port_test.no + '</span>');
|
||||
}
|
||||
var cell = 'tr#' + id + " td.auth_xoauth2";
|
||||
var testEl = jQuery(cell);
|
||||
if (response.auth_xoauth) {
|
||||
testEl.html('<span style="color:green">' + postman_port_test.yes + '</span>');
|
||||
} else {
|
||||
testEl.html('<span>' + postman_port_test.no + '</span>');
|
||||
}
|
||||
}
|
||||
function resetView(id) {
|
||||
var testEl = jQuery('tr#' + id + ' td.resettable');
|
||||
testEl.html('-');
|
||||
}
|
||||
function addConclusion(message, success, isSecure) {
|
||||
show('#conclusion');
|
||||
var secureIcon = '';
|
||||
if (isSecure) {
|
||||
secureIcon = '🔒 ';
|
||||
}
|
||||
if (success) {
|
||||
message = '✅ ' + secureIcon + message;
|
||||
} else {
|
||||
message = '❌ ' + secureIcon + message;
|
||||
}
|
||||
jQuery('ol.conclusion').append('<li>' + message + '</li>');
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Calculate the effective registered domain of a fully qualified domain name.
|
||||
*
|
||||
* <@LICENSE>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to you under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* </@LICENSE>
|
||||
*
|
||||
* Florian Sager, 25.07.2008, sager@agitos.de, http://www.agitos.de
|
||||
*/
|
||||
|
||||
/*
|
||||
* Remove subdomains from a signing domain to get the registered domain.
|
||||
*
|
||||
* dkim-reputation.org blocks signing domains on the level of registered domains
|
||||
* to rate senders who use e.g. a.spamdomain.tld, b.spamdomain.tld, ... under
|
||||
* the most common identifier - the registered domain - finally.
|
||||
*
|
||||
* This function returns NULL if $signingDomain is TLD itself
|
||||
*
|
||||
* $signingDomain has to be provided lowercase (!)
|
||||
*/
|
||||
|
||||
class regDomain {
|
||||
/* tld tree */
|
||||
protected $tldTree = array();
|
||||
|
||||
/* main function */
|
||||
public function getRegisteredDomain($signingDomain, $fallback = TRUE) {
|
||||
$signingDomainParts = explode('.', $signingDomain);
|
||||
|
||||
$result = $this->findRegisteredDomain($signingDomainParts, $this->tldTree);
|
||||
|
||||
if ($result===NULL || $result=="") {
|
||||
// this is an invalid domain name
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// assure there is at least 1 TLD in the stripped signing domain
|
||||
if (!strpos($result, '.')) {
|
||||
if ($fallback===FALSE) {
|
||||
return NULL;
|
||||
}
|
||||
$cnt = count($signingDomainParts);
|
||||
if ($cnt==1 || $signingDomainParts[$cnt-2]=="") return NULL;
|
||||
if (!$this->validDomainPart($signingDomainParts[$cnt-2]) || !$this->validDomainPart($signingDomainParts[$cnt-1])) return NULL;
|
||||
return $signingDomainParts[$cnt-2].'.'.$signingDomainParts[$cnt-1];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* validate parts */
|
||||
public function validDomainPart($domPart) {
|
||||
// see http://www.register.com/domain-extension-rules.rcmx
|
||||
$len = strlen($domPart);
|
||||
|
||||
// not more than 63 characters
|
||||
if ($len>63) return FALSE;
|
||||
|
||||
// not less than 1 characters --> there are TLD-specific rules that could be considered additionally
|
||||
if ($len<1) return FALSE;
|
||||
|
||||
// Use only letters, numbers, or hyphen ("-")
|
||||
// not beginning or ending with a hypen (this is TLD specific, be aware!)
|
||||
if (!preg_match("/^([a-z0-9])(([a-z0-9-])*([a-z0-9]))*$/", $domPart)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* recursive helper method */
|
||||
public function findRegisteredDomain($remainingSigningDomainParts, &$treeNode) {
|
||||
$sub = array_pop($remainingSigningDomainParts);
|
||||
|
||||
$result = NULL;
|
||||
if (isset($treeNode['!'])) {
|
||||
return '#';
|
||||
}
|
||||
|
||||
if (!$this->validDomainPart($sub)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (is_array($treeNode) && array_key_exists($sub, $treeNode)) {
|
||||
$result = $this->findRegisteredDomain($remainingSigningDomainParts, $treeNode[$sub]);
|
||||
} else if (is_array($treeNode) && array_key_exists('*', $treeNode)) {
|
||||
$result = $this->findRegisteredDomain($remainingSigningDomainParts, $treeNode['*']);
|
||||
} else {
|
||||
return $sub;
|
||||
}
|
||||
|
||||
// this is a hack 'cause PHP interpretes '' as NULL
|
||||
if ($result == '#') {
|
||||
return $sub;
|
||||
} else if (strlen($result)>0) {
|
||||
return $result.'.'.$sub;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* load tld tree into object */
|
||||
function __construct() {
|
||||
/* include tld tree data */
|
||||
include(dirname(__FILE__) . '/effectiveTLDs.inc.php');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Calculate the effective registered domain of a fully qualified domain name.
|
||||
*
|
||||
* <@LICENSE>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to you under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* </@LICENSE>
|
||||
*
|
||||
* Florian Sager, 25.07.2008, sager@agitos.de, http://www.agitos.de
|
||||
*/
|
||||
|
||||
/*
|
||||
* Remove subdomains from a signing domain to get the registered domain.
|
||||
*
|
||||
* dkim-reputation.org blocks signing domains on the level of registered domains
|
||||
* to rate senders who use e.g. a.spamdomain.tld, b.spamdomain.tld, ... under
|
||||
* the most common identifier - the registered domain - finally.
|
||||
*
|
||||
* This function returns NULL if $signingDomain is TLD itself
|
||||
*
|
||||
* $signingDomain has to be provided lowercase (!)
|
||||
*/
|
||||
|
||||
/* pull in class */
|
||||
require_once (dirname ( __FILE__ ) . '/regDomain.class.php');
|
||||
|
||||
/* create global object */
|
||||
;
|
||||
function getRegisteredDomain($signingDomain, $fallback = TRUE) {
|
||||
/* pull in object */
|
||||
$regDomainObj = new regDomain ();
|
||||
/* return object method */
|
||||
return $regDomainObj->getRegisteredDomain ( $signingDomain, $fallback );
|
||||
}
|
||||
function validDomainPart($domPart) {
|
||||
/* pull in object */
|
||||
$regDomainObj = new regDomain ();
|
||||
/* return object method */
|
||||
return $regDomainObj->validDomainPart ( $domPart );
|
||||
}
|
||||
|
||||
// recursive helper method
|
||||
function findRegisteredDomain($remainingSigningDomainParts, &$treeNode) {
|
||||
/* pull in object */
|
||||
$regDomainObj = new regDomain ();
|
||||
/* return object method */
|
||||
return $regDomainObj->findRegisteredDomain ( $remainingSigningDomainParts, $treeNode );
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Calculate the effective registered domain of a fully qualified domain name.
|
||||
*
|
||||
* <@LICENSE>
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to you under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* </@LICENSE>
|
||||
*
|
||||
* Florian Sager, 25.07.2008, sager@agitos.de, http://www.agitos.de
|
||||
*/
|
||||
|
||||
require_once("effectiveTLDs.inc.php");
|
||||
require_once("regDomain.inc.php");
|
||||
|
||||
if ($_SERVER["argc"]<2) {
|
||||
print("test-regDomain.php <(fully-qualified-domain-name )+>\n");
|
||||
exit;
|
||||
}
|
||||
|
||||
// strip subdomains from every signing domain
|
||||
// char dom[] = "sub2.sub.registered.nom.ad";
|
||||
|
||||
$argc = $_SERVER["argc"];
|
||||
$argv = $_SERVER["argv"];
|
||||
|
||||
for ($i=1; $i<$argc; $i++) {
|
||||
|
||||
$registeredDomain = getRegisteredDomain($argv[$i], $tldTree);
|
||||
|
||||
if ( $registeredDomain === NULL ) {
|
||||
printf("error: %s\n", $argv[$i]);
|
||||
} else {
|
||||
printf("%s\n", $registeredDomain);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,56 @@
|
||||
===============================================
|
||||
Detection of registered domains by reg-dom libs
|
||||
===============================================
|
||||
|
||||
The reg-dom libs are available in C, Perl and PHP so far.
|
||||
|
||||
They include recent representations of the effective TLD list available at
|
||||
http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1
|
||||
and help to convert an arbitrary domain name to the registered domain name.
|
||||
|
||||
Sample use:
|
||||
dkim-reputation.org blocks signing domains on the level of registered domains
|
||||
to rate senders who use e.g. a.spamdomain.tld, b.spamdomain.tld, ... under
|
||||
the most common identifier - the registered domain - finally.
|
||||
Project page: http://www.dkim-reputation.org/regdom-libs/
|
||||
|
||||
Pseudo code:
|
||||
registeredDomain = getRegisteredDomain(ingoingDomain);
|
||||
|
||||
Return values:
|
||||
1) NULL if ingoingDomain is a TLD
|
||||
2) the registered domain name if TLD is known
|
||||
3) just <domain>.<tld> if <tld> is unknown
|
||||
This case was added to support new TLDs in outdated reg-dom libs
|
||||
by a certain likelihood. This fallback method is implemented in the
|
||||
last conversion step and can be simply commented out.
|
||||
|
||||
---
|
||||
|
||||
If you like to regenerate the effective TLD tree structure by yourself
|
||||
you can use the script generateEffectiveTLDs.php with the following parameters:
|
||||
|
||||
php generateEffectiveTLDs.php php > PHP/effectiveTLDs.inc.php
|
||||
php generateEffectiveTLDs.php perl > Perl/effectiveTLDs.pm
|
||||
php generateEffectiveTLDs.php c > C/tld-canon.h
|
||||
|
||||
|
||||
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to you under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at:
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
# </@LICENSE>
|
||||
|
||||
|
||||
Florian Sager, 2009-02-05, sager@agitos.de, http://www.agitos.de
|
||||
@@ -0,0 +1,213 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Florian Sager, 06.08.2008, sager@agitos.de, http://www.agitos.de
|
||||
*
|
||||
* Auto-Generate PHP array tree that contains all TLDs from the URL (see below);
|
||||
* The output has to be copied to reputation-libs/effectiveTLDs.inc.php
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
DEFINE('URL', 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1');
|
||||
|
||||
$format = "php";
|
||||
if ($_SERVER['argc']>1) {
|
||||
if ($_SERVER['argv'][1] == "perl") {
|
||||
$format = "perl";
|
||||
} else if ($_SERVER['argv'][1] == "c") {
|
||||
$format = "c";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Does $search start with $startstring?
|
||||
*/
|
||||
function startsWith($search, $startstring) {
|
||||
return (substr($search, 0, strlen($startstring))==$startstring);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does $search end with $endstring?
|
||||
*/
|
||||
function endsWith($search, $endstring) {
|
||||
return (substr($search, -strlen($endstring))==$endstring);
|
||||
}
|
||||
|
||||
|
||||
function buildSubdomain(&$node, $tldParts) {
|
||||
|
||||
$dom = trim(array_pop($tldParts));
|
||||
|
||||
$isNotDomain = FALSE;
|
||||
if (startsWith($dom, "!")) {
|
||||
$dom = substr($dom, 1);
|
||||
$isNotDomain = TRUE;
|
||||
}
|
||||
|
||||
if (!array_key_exists($dom, $node)) {
|
||||
if ($isNotDomain) {
|
||||
$node[$dom] = array("!" => "");
|
||||
} else {
|
||||
$node[$dom] = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isNotDomain && count($tldParts)>0) {
|
||||
buildSubdomain($node[$dom], $tldParts);
|
||||
}
|
||||
}
|
||||
|
||||
function printNode($key, $valueTree, $isAssignment = false) {
|
||||
|
||||
global $format;
|
||||
|
||||
if ($isAssignment) {
|
||||
if ($format == "perl") {
|
||||
echo "$key = {";
|
||||
} else {
|
||||
echo "$key = array(";
|
||||
}
|
||||
} else {
|
||||
if (strcmp($key, "!")==0) {
|
||||
if ($format == "perl") {
|
||||
echo "'!' => {}";
|
||||
} else {
|
||||
echo "'!' => ''";
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if ($format == "perl") {
|
||||
echo "'$key' => {";
|
||||
} else {
|
||||
echo "'$key' => array(";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$keys = array_keys($valueTree);
|
||||
|
||||
for ($i=0; $i<count($keys); $i++) {
|
||||
|
||||
$key = $keys[$i];
|
||||
|
||||
printNode($key, $valueTree[$key]);
|
||||
|
||||
if ($i+1 != count($valueTree)) {
|
||||
echo ",\n";
|
||||
} else {
|
||||
"\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($format == "perl") {
|
||||
echo '}';
|
||||
} else {
|
||||
echo ')';
|
||||
}
|
||||
}
|
||||
|
||||
// sample: root(3:ac(5:com,edu,gov,net,ad(3:nom,co!,*)),de,com)
|
||||
|
||||
function printNode_C($key, $valueTree) {
|
||||
|
||||
echo "$key";
|
||||
|
||||
$keys = array_keys($valueTree);
|
||||
|
||||
if (count($keys)>0) {
|
||||
|
||||
if (strcmp($keys['!'], "!")==0) {
|
||||
echo "!";
|
||||
} else {
|
||||
|
||||
echo "(".count($keys).":";
|
||||
|
||||
for ($i=0; $i<count($keys); $i++) {
|
||||
|
||||
$key = $keys[$i];
|
||||
|
||||
// if (count($valueTree[$key])>0) {
|
||||
printNode_C($key, $valueTree[$key]);
|
||||
// }
|
||||
|
||||
if ($i+1 != count($valueTree)) {
|
||||
echo ",";
|
||||
}
|
||||
}
|
||||
|
||||
echo ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- main ---
|
||||
|
||||
error_reporting(E_ERROR);
|
||||
|
||||
$tldTree = array();
|
||||
$list = file_get_contents(URL);
|
||||
// $list = "bg\na.bg\n0.bg\n!c.bg\n";
|
||||
$lines = explode("\n", $list);
|
||||
$licence = TRUE;
|
||||
|
||||
if ($format == "php") echo "<?php\n";
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$line = trim($line);
|
||||
if ($line == "") {
|
||||
if ($licence) {
|
||||
$licence = FALSE;
|
||||
echo "\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (startsWith($line, "//")) {
|
||||
if ($licence) {
|
||||
if ($format == "perl") {
|
||||
echo "# ".substr($line, 2)."\n";
|
||||
} else {
|
||||
echo $line."\n";
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// this must be a TLD
|
||||
$tldParts = preg_split('\.', $line);
|
||||
buildSubdomain($tldTree, $tldParts);
|
||||
}
|
||||
|
||||
// print_r($tldTree);
|
||||
|
||||
/*
|
||||
$tldTree = array(
|
||||
'de' => array(), // test.agitos.de --> agitos.de
|
||||
'uk' => array(
|
||||
'co' => array(), // test.agitos.co.uk --> agitos.co.uk
|
||||
'xy' => array('!'), // test.agitos.xy.uk --> xy.uk
|
||||
'*' => array() // test.agitos.ab.uk --> agitos.ab.uk
|
||||
)
|
||||
);
|
||||
*/
|
||||
|
||||
if ($format == "c") {
|
||||
|
||||
echo "static const char tldString[] = \"";
|
||||
printNode_C("root", $tldTree);
|
||||
echo "\";\n\n";
|
||||
|
||||
} else {
|
||||
|
||||
if ($format == "perl") {
|
||||
print "package effectiveTLDs;\n\n";
|
||||
}
|
||||
printNode("\$tldTree", $tldTree, TRUE);
|
||||
echo ";\n";
|
||||
if ($format == "php") echo '?>' . "\n";
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user