Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
xyu committed Aug 16, 2016
0 parents commit 4e59bba
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 0 deletions.
12 changes: 12 additions & 0 deletions includes/admin-page.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#dashboard_right_now .securedbconnection-ssl span:before {
content: "\f160";
}

#dashboard_right_now .securedbconnection-nossl span:before {
content: "\f528";
color: #d54e21;
}

#dashboard_right_now .securedbconnection-nossl {
color: #d54e21;
}
175 changes: 175 additions & 0 deletions includes/db.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php
/*
Plugin name: Secure DB Connection
Plugin URI: http://wordpress.org/plugins/secure-db-connection/
Description: Sets SSL keys and certs for encrypted database connections
Author: Xiao Yu
Author URI: http://xyu.io/
Version: 1.0
*/

class wpdb_ssl extends wpdb {

/**
* Connect to and select database.
*
* If $allow_bail is false, the lack of database connection will need
* to be handled manually.
*
* @since 3.0.0
* @since 3.9.0 $allow_bail parameter added.
*
* @param bool $allow_bail Optional. Allows the function to bail. Default true.
* @return bool True with a successful connection, false on failure.
*/
public function db_connect( $allow_bail = true ) {
$this->is_mysql = true;

/*
* Deprecated in 3.9+ when using MySQLi. No equivalent
* $new_link parameter exists for mysqli_* functions.
*/
$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;

if ( $this->use_mysqli ) {
$this->dbh = mysqli_init();

// mysqli_real_connect doesn't support the host param including a port or socket
// like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
$port = null;
$socket = null;
$host = $this->dbhost;
$port_or_socket = strstr( $host, ':' );
if ( ! empty( $port_or_socket ) ) {
$host = substr( $host, 0, strpos( $host, ':' ) );
$port_or_socket = substr( $port_or_socket, 1 );
if ( 0 !== strpos( $port_or_socket, '/' ) ) {
$port = intval( $port_or_socket );
$maybe_socket = strstr( $port_or_socket, ':' );
if ( ! empty( $maybe_socket ) ) {
$socket = substr( $maybe_socket, 1 );
}
} else {
$socket = $port_or_socket;
}
}

// Set SSL certs if we want to use secure DB connections
$ssl_opts = array(
'KEY' => ( defined( 'MYSQL_SSL_KEY' ) && is_file( MYSQL_SSL_KEY ) ) ? MYSQL_SSL_KEY : null,
'CERT' => ( defined( 'MYSQL_SSL_CERT' ) && is_file( MYSQL_SSL_CERT ) ) ? MYSQL_SSL_CERT : null,
'CA' => ( defined( 'MYSQL_SSL_CA' ) && is_file( MYSQL_SSL_CA ) ) ? MYSQL_SSL_CA : null,
'CA_PATH' => ( defined( 'MYSQL_SSL_CA_PATH' ) && is_dir ( MYSQL_SSL_CA_PATH ) ) ? MYSQL_SSL_CA_PATH : null,
'CIPHER' => ( defined( 'MYSQL_SSL_CIPHER' ) && !empty ( MYSQL_SSL_CIPHER ) ) ? MYSQL_SSL_CIPHER : null,
);
$ssl_opts_set = false;
foreach ( $ssl_opts as $ssl_opt_val ) {
if ( !is_null( $ssl_opt_val ) ) {
$ssl_opts_set = true;
break;
}
}
if ( $ssl_opts_set ) {
mysqli_ssl_set(
$this->dbh,
$ssl_opts[ 'KEY' ],
$ssl_opts[ 'CERT' ],
$ssl_opts[ 'CA' ],
$ssl_opts[ 'CA_PATH' ],
$ssl_opts[ 'CIPHER' ]
);
}

if ( WP_DEBUG ) {
mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
} else {
@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
}

if ( $this->dbh->connect_errno ) {
$this->dbh = null;

/* It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
* - We haven't previously connected, and
* - WP_USE_EXT_MYSQL isn't set to false, and
* - ext/mysql is loaded.
*/
$attempt_fallback = true;

if ( $this->has_connected ) {
$attempt_fallback = false;
} elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
$attempt_fallback = false;
} elseif ( ! function_exists( 'mysql_connect' ) ) {
$attempt_fallback = false;
}

if ( $attempt_fallback ) {
$this->use_mysqli = false;
return $this->db_connect( $allow_bail );
}
}
} else {
if ( WP_DEBUG ) {
$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
} else {
$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
}
}

if ( ! $this->dbh && $allow_bail ) {
wp_load_translations_early();

// Load custom DB error template, if present.
if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
require_once( WP_CONTENT_DIR . '/db-error.php' );
die();
}

$message = '<h1>' . __( 'Error establishing a database connection' ) . "</h1>\n";

$message .= '<p>' . sprintf(
/* translators: 1: wp-config.php. 2: database host */
__( 'This either means that the username and password information in your %1$s file is incorrect or we can&#8217;t contact the database server at %2$s. This could mean your host&#8217;s database server is down.' ),
'<code>wp-config.php</code>',
'<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'
) . "</p>\n";

$message .= "<ul>\n";
$message .= '<li>' . __( 'Are you sure you have the correct username and password?' ) . "</li>\n";
$message .= '<li>' . __( 'Are you sure that you have typed the correct hostname?' ) . "</li>\n";
$message .= '<li>' . __( 'Are you sure that the database server is running?' ) . "</li>\n";
$message .= "</ul>\n";

$message .= '<p>' . sprintf(
/* translators: %s: support forums URL */
__( 'If you&#8217;re unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href="%s">WordPress Support Forums</a>.' ),
__( 'https://wordpress.org/support/' )
) . "</p>\n";

$this->bail( $message, 'db_connect_fail' );

return false;
} elseif ( $this->dbh ) {
if ( ! $this->has_connected ) {
$this->init_charset();
}

$this->has_connected = true;

$this->set_charset( $this->dbh );

$this->ready = true;
$this->set_sql_mode();
$this->select( $this->dbname, $this->dbh );

return true;
}

return false;
}

}

$wpdb = new wpdb_ssl( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
70 changes: 70 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
=== Secure DB Connection ===
Contributors: HypertextRanch
Tags: db, mysql, secure, encrypted, ssl
Requires at least: 3.9
Tested up to: 4.6
Stable tag: 1.0
License: GPLv3
License URI: http://www.gnu.org/licenses/gpl-3.0.html

Sets SSL keys and certs for encrypted database connections.

== Description ==

Depending on the MySQL server setup the SSL certs used may not be in the trusted store, if that's the case `mysqli_ssl_set()` needs to be called to set custom keys and certs before connect. This Plugin adds a custom DB class that allows these settings to be configured via custom constants.

This plugin will also add a custom item on the "At a Glance" section of the Dashboard to show if the `$wpdb` connection is secure or not.

Also find me on [GitHub](https://github.com/xyu/secure-db-connection).

= Configuration Parameters =

To adjust the configuration, define any of the following applicable constants in your `wp-config.php` file.

* `MYSQL_SSL_KEY` [default: not set]

The path name to the key file. (RSA Key)

* `MYSQL_SSL_CERT` [default: not set]

The path name to the certificate file.

* `MYSQL_SSL_CA` [default: not set]

The path name to the certificate authority file.

* `MYSQL_SSL_CA_PATH` [default: not set]

The pathname to a directory that contains trusted SSL CA certificates in PEM format.

* `MYSQL_SSL_CIPHER` [default: not set]

A list of allowable ciphers to use for SSL encryption

= Turning on SSL =

Once SSL keys and certs have been configured you via the defines above define an WP core constant to pass a use SSL flag to the mysqli client also in your `wp-config.php` file.

```
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL );
```

If you are using the MySQL Native Driver and MySQL 5.6 or later `mysqli_real_connect()` will verify the server SSL certificate before connecting. If the SSL cert installed on the MySQL server your are connecting to is not valid PHP will refuse to connect. A flag was added to disable server certificate validation. If your server has an invalid certificate turn on SSL and turn off validation like so:

```
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT );
```

== Installation ==

For detailed installation instructions, please read the [standard installation procedure for WordPress plugins](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins).

1. Install and activate plugin.
1. Symlink or copy the `db.php` file from the `/plugins/secure-db-connection/includes/` directory to the `/wp-content/` directory.
1. Set the relevant defines in your `wp-config.php` file.

== Changelog ==

= 1.0 =

* Initial release
81 changes: 81 additions & 0 deletions secure-db-connection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/*
Plugin name: Secure DB Connection
Plugin URI: http://wordpress.org/plugins/secure-db-connection/
Description: Sets SSL keys and certs for encrypted database connections
Author: Xiao Yu
Author URI: http://xyu.io/
Version: 1.0
*/

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

class WP_SecureDBConnection {

public function __construct() {
$this->init();
}

public function init() {
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_filter( 'dashboard_glance_items', array( $this, 'dashboard_glance_items' ) );
}

public function admin_enqueue_scripts( $hook_suffix ) {
if ( "index.php" === $hook_suffix ) {
$plugin = get_plugin_data( __FILE__ );
wp_enqueue_style(
'secure-db-connection',
plugin_dir_url( __FILE__ ) . 'includes/admin-page.css',
null,
$plugin[ 'Version' ]
);
}
}

/**
* Add to Dashboard At a Glance echo instead of return to hack in
* custom styles.
*/
public function dashboard_glance_items( $elements ) {
if ( current_user_can( 'administrator' ) ) {
$status = $this->_getConnStatus();

if ( empty( $status['ssl_cipher'] ) ) {
printf(
'<li class="securedbconnection-nossl"><span>%s</span></li>',
"Connection to MySQL is in plain text",
'MySQL Unencrypted'
);
} else {
printf(
'<li class="securedbconnection-ssl"><span title="%s">%s</span></li>',
"Connection to MySQL is SSL ({$status['ssl_version']}) encrypted via {$status['ssl_cipher']}",
"MySQL Secured"
);
}
}

return $elements;
}

private function _getConnStatus() {
global $wpdb;

$results = $wpdb->get_results(
"SHOW SESSION STATUS WHERE variable_name IN ( 'Ssl_cipher', 'Ssl_version' )"
);

$return = array();
foreach ( $results as $row ) {
$key = strtolower( $row->Variable_name );
$return[ $key ] = $row->Value;
}
return $return;
}

}

new WP_SecureDBConnection();

0 comments on commit 4e59bba

Please sign in to comment.