Skip to content

Commit 4e59bba

Browse files
committed
Initial Commit
0 parents  commit 4e59bba

File tree

4 files changed

+338
-0
lines changed

4 files changed

+338
-0
lines changed

includes/admin-page.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#dashboard_right_now .securedbconnection-ssl span:before {
2+
content: "\f160";
3+
}
4+
5+
#dashboard_right_now .securedbconnection-nossl span:before {
6+
content: "\f528";
7+
color: #d54e21;
8+
}
9+
10+
#dashboard_right_now .securedbconnection-nossl {
11+
color: #d54e21;
12+
}

includes/db.php

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<?php
2+
/*
3+
Plugin name: Secure DB Connection
4+
Plugin URI: http://wordpress.org/plugins/secure-db-connection/
5+
Description: Sets SSL keys and certs for encrypted database connections
6+
Author: Xiao Yu
7+
Author URI: http://xyu.io/
8+
Version: 1.0
9+
*/
10+
11+
class wpdb_ssl extends wpdb {
12+
13+
/**
14+
* Connect to and select database.
15+
*
16+
* If $allow_bail is false, the lack of database connection will need
17+
* to be handled manually.
18+
*
19+
* @since 3.0.0
20+
* @since 3.9.0 $allow_bail parameter added.
21+
*
22+
* @param bool $allow_bail Optional. Allows the function to bail. Default true.
23+
* @return bool True with a successful connection, false on failure.
24+
*/
25+
public function db_connect( $allow_bail = true ) {
26+
$this->is_mysql = true;
27+
28+
/*
29+
* Deprecated in 3.9+ when using MySQLi. No equivalent
30+
* $new_link parameter exists for mysqli_* functions.
31+
*/
32+
$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
33+
$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
34+
35+
if ( $this->use_mysqli ) {
36+
$this->dbh = mysqli_init();
37+
38+
// mysqli_real_connect doesn't support the host param including a port or socket
39+
// like mysql_connect does. This duplicates how mysql_connect detects a port and/or socket file.
40+
$port = null;
41+
$socket = null;
42+
$host = $this->dbhost;
43+
$port_or_socket = strstr( $host, ':' );
44+
if ( ! empty( $port_or_socket ) ) {
45+
$host = substr( $host, 0, strpos( $host, ':' ) );
46+
$port_or_socket = substr( $port_or_socket, 1 );
47+
if ( 0 !== strpos( $port_or_socket, '/' ) ) {
48+
$port = intval( $port_or_socket );
49+
$maybe_socket = strstr( $port_or_socket, ':' );
50+
if ( ! empty( $maybe_socket ) ) {
51+
$socket = substr( $maybe_socket, 1 );
52+
}
53+
} else {
54+
$socket = $port_or_socket;
55+
}
56+
}
57+
58+
// Set SSL certs if we want to use secure DB connections
59+
$ssl_opts = array(
60+
'KEY' => ( defined( 'MYSQL_SSL_KEY' ) && is_file( MYSQL_SSL_KEY ) ) ? MYSQL_SSL_KEY : null,
61+
'CERT' => ( defined( 'MYSQL_SSL_CERT' ) && is_file( MYSQL_SSL_CERT ) ) ? MYSQL_SSL_CERT : null,
62+
'CA' => ( defined( 'MYSQL_SSL_CA' ) && is_file( MYSQL_SSL_CA ) ) ? MYSQL_SSL_CA : null,
63+
'CA_PATH' => ( defined( 'MYSQL_SSL_CA_PATH' ) && is_dir ( MYSQL_SSL_CA_PATH ) ) ? MYSQL_SSL_CA_PATH : null,
64+
'CIPHER' => ( defined( 'MYSQL_SSL_CIPHER' ) && !empty ( MYSQL_SSL_CIPHER ) ) ? MYSQL_SSL_CIPHER : null,
65+
);
66+
$ssl_opts_set = false;
67+
foreach ( $ssl_opts as $ssl_opt_val ) {
68+
if ( !is_null( $ssl_opt_val ) ) {
69+
$ssl_opts_set = true;
70+
break;
71+
}
72+
}
73+
if ( $ssl_opts_set ) {
74+
mysqli_ssl_set(
75+
$this->dbh,
76+
$ssl_opts[ 'KEY' ],
77+
$ssl_opts[ 'CERT' ],
78+
$ssl_opts[ 'CA' ],
79+
$ssl_opts[ 'CA_PATH' ],
80+
$ssl_opts[ 'CIPHER' ]
81+
);
82+
}
83+
84+
if ( WP_DEBUG ) {
85+
mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
86+
} else {
87+
@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
88+
}
89+
90+
if ( $this->dbh->connect_errno ) {
91+
$this->dbh = null;
92+
93+
/* It's possible ext/mysqli is misconfigured. Fall back to ext/mysql if:
94+
* - We haven't previously connected, and
95+
* - WP_USE_EXT_MYSQL isn't set to false, and
96+
* - ext/mysql is loaded.
97+
*/
98+
$attempt_fallback = true;
99+
100+
if ( $this->has_connected ) {
101+
$attempt_fallback = false;
102+
} elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
103+
$attempt_fallback = false;
104+
} elseif ( ! function_exists( 'mysql_connect' ) ) {
105+
$attempt_fallback = false;
106+
}
107+
108+
if ( $attempt_fallback ) {
109+
$this->use_mysqli = false;
110+
return $this->db_connect( $allow_bail );
111+
}
112+
}
113+
} else {
114+
if ( WP_DEBUG ) {
115+
$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
116+
} else {
117+
$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
118+
}
119+
}
120+
121+
if ( ! $this->dbh && $allow_bail ) {
122+
wp_load_translations_early();
123+
124+
// Load custom DB error template, if present.
125+
if ( file_exists( WP_CONTENT_DIR . '/db-error.php' ) ) {
126+
require_once( WP_CONTENT_DIR . '/db-error.php' );
127+
die();
128+
}
129+
130+
$message = '<h1>' . __( 'Error establishing a database connection' ) . "</h1>\n";
131+
132+
$message .= '<p>' . sprintf(
133+
/* translators: 1: wp-config.php. 2: database host */
134+
__( '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.' ),
135+
'<code>wp-config.php</code>',
136+
'<code>' . htmlspecialchars( $this->dbhost, ENT_QUOTES ) . '</code>'
137+
) . "</p>\n";
138+
139+
$message .= "<ul>\n";
140+
$message .= '<li>' . __( 'Are you sure you have the correct username and password?' ) . "</li>\n";
141+
$message .= '<li>' . __( 'Are you sure that you have typed the correct hostname?' ) . "</li>\n";
142+
$message .= '<li>' . __( 'Are you sure that the database server is running?' ) . "</li>\n";
143+
$message .= "</ul>\n";
144+
145+
$message .= '<p>' . sprintf(
146+
/* translators: %s: support forums URL */
147+
__( '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>.' ),
148+
__( 'https://wordpress.org/support/' )
149+
) . "</p>\n";
150+
151+
$this->bail( $message, 'db_connect_fail' );
152+
153+
return false;
154+
} elseif ( $this->dbh ) {
155+
if ( ! $this->has_connected ) {
156+
$this->init_charset();
157+
}
158+
159+
$this->has_connected = true;
160+
161+
$this->set_charset( $this->dbh );
162+
163+
$this->ready = true;
164+
$this->set_sql_mode();
165+
$this->select( $this->dbname, $this->dbh );
166+
167+
return true;
168+
}
169+
170+
return false;
171+
}
172+
173+
}
174+
175+
$wpdb = new wpdb_ssl( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );

readme.txt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
=== Secure DB Connection ===
2+
Contributors: HypertextRanch
3+
Tags: db, mysql, secure, encrypted, ssl
4+
Requires at least: 3.9
5+
Tested up to: 4.6
6+
Stable tag: 1.0
7+
License: GPLv3
8+
License URI: http://www.gnu.org/licenses/gpl-3.0.html
9+
10+
Sets SSL keys and certs for encrypted database connections.
11+
12+
== Description ==
13+
14+
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.
15+
16+
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.
17+
18+
Also find me on [GitHub](https://github.com/xyu/secure-db-connection).
19+
20+
= Configuration Parameters =
21+
22+
To adjust the configuration, define any of the following applicable constants in your `wp-config.php` file.
23+
24+
* `MYSQL_SSL_KEY` [default: not set]
25+
26+
The path name to the key file. (RSA Key)
27+
28+
* `MYSQL_SSL_CERT` [default: not set]
29+
30+
The path name to the certificate file.
31+
32+
* `MYSQL_SSL_CA` [default: not set]
33+
34+
The path name to the certificate authority file.
35+
36+
* `MYSQL_SSL_CA_PATH` [default: not set]
37+
38+
The pathname to a directory that contains trusted SSL CA certificates in PEM format.
39+
40+
* `MYSQL_SSL_CIPHER` [default: not set]
41+
42+
A list of allowable ciphers to use for SSL encryption
43+
44+
= Turning on SSL =
45+
46+
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.
47+
48+
```
49+
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL );
50+
```
51+
52+
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:
53+
54+
```
55+
define( 'MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT );
56+
```
57+
58+
== Installation ==
59+
60+
For detailed installation instructions, please read the [standard installation procedure for WordPress plugins](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins).
61+
62+
1. Install and activate plugin.
63+
1. Symlink or copy the `db.php` file from the `/plugins/secure-db-connection/includes/` directory to the `/wp-content/` directory.
64+
1. Set the relevant defines in your `wp-config.php` file.
65+
66+
== Changelog ==
67+
68+
= 1.0 =
69+
70+
* Initial release

secure-db-connection.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/*
3+
Plugin name: Secure DB Connection
4+
Plugin URI: http://wordpress.org/plugins/secure-db-connection/
5+
Description: Sets SSL keys and certs for encrypted database connections
6+
Author: Xiao Yu
7+
Author URI: http://xyu.io/
8+
Version: 1.0
9+
*/
10+
11+
if ( ! defined( 'ABSPATH' ) ) {
12+
exit;
13+
}
14+
15+
class WP_SecureDBConnection {
16+
17+
public function __construct() {
18+
$this->init();
19+
}
20+
21+
public function init() {
22+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
23+
add_filter( 'dashboard_glance_items', array( $this, 'dashboard_glance_items' ) );
24+
}
25+
26+
public function admin_enqueue_scripts( $hook_suffix ) {
27+
if ( "index.php" === $hook_suffix ) {
28+
$plugin = get_plugin_data( __FILE__ );
29+
wp_enqueue_style(
30+
'secure-db-connection',
31+
plugin_dir_url( __FILE__ ) . 'includes/admin-page.css',
32+
null,
33+
$plugin[ 'Version' ]
34+
);
35+
}
36+
}
37+
38+
/**
39+
* Add to Dashboard At a Glance echo instead of return to hack in
40+
* custom styles.
41+
*/
42+
public function dashboard_glance_items( $elements ) {
43+
if ( current_user_can( 'administrator' ) ) {
44+
$status = $this->_getConnStatus();
45+
46+
if ( empty( $status['ssl_cipher'] ) ) {
47+
printf(
48+
'<li class="securedbconnection-nossl"><span>%s</span></li>',
49+
"Connection to MySQL is in plain text",
50+
'MySQL Unencrypted'
51+
);
52+
} else {
53+
printf(
54+
'<li class="securedbconnection-ssl"><span title="%s">%s</span></li>',
55+
"Connection to MySQL is SSL ({$status['ssl_version']}) encrypted via {$status['ssl_cipher']}",
56+
"MySQL Secured"
57+
);
58+
}
59+
}
60+
61+
return $elements;
62+
}
63+
64+
private function _getConnStatus() {
65+
global $wpdb;
66+
67+
$results = $wpdb->get_results(
68+
"SHOW SESSION STATUS WHERE variable_name IN ( 'Ssl_cipher', 'Ssl_version' )"
69+
);
70+
71+
$return = array();
72+
foreach ( $results as $row ) {
73+
$key = strtolower( $row->Variable_name );
74+
$return[ $key ] = $row->Value;
75+
}
76+
return $return;
77+
}
78+
79+
}
80+
81+
new WP_SecureDBConnection();

0 commit comments

Comments
 (0)