WL#6441: Convert mysql_secure_installation script to C

Affects: Server-5.7   —   Status: Complete

mysql_secure_installation script currently
stores the user supplied password in a temporary
option file. This option file is later passed to
mysql client, which executes the required SQL
commands.

Since, storing password in an option file is
considered insecure, the script can be converted
to a C++ program so that the program can connect
to the server directly and execute the specified
commands using C API (libmysql).

User Documentation
==================

http://dev.mysql.com/doc/refman/5.7/en/mysql-secure-installation.html
http://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-2.html
mysql_secure_installation:

This script enables the user to secure the mysql installation in the following 
ways:

1) Set password to root accounts.
2) Remove root accounts access outside localhost.
3) Remove anonymous user accounts.
4) Remove test database and privileges associated with the databases with the 
name starting with 'test_'.

(Please refer: http://dev.mysql.com/doc/refman/5.6/en/mysql-secure-
installation.html for documentation)

Changes to user:
There will not be any syntax changes to the user. The name of the executable 
remains same i.e. 'mysql_secure_installation'.

Code Implementation:

The script existing for mysql_secure_installation triggers a series of steps 
which essentially needs to be carried forward to the C++ code file being 
introduced. The difference would be in the way the queries are executed. The 
script file creates a config file which is used by the client to connect to the 
server to execute the queries. This logic will be replaced with executing steps 
using mysql API for C++. However, an additional functionality to check the 
strength of the password will be introduced which is not present in the script.

The flow of the program will be:
* Ask for root password and check for its validity.
* Check if validate_password plugin is enabled on the server. If not,
  prompt the user if he wishes to install it. Take the input for the strength
  of password policy the user wishes to set.
* If the password is found to be blank, prompt the user that, for the database
  to be secure, the root password cannot be left blank. Prompt the user to enter
  the password. Once it is entered, check for any human error by asking him to
  retype the password. After checking it,

  If validate_password plugin is installed: display the strength of the password
  and ask the user if he wants to continue with it(y or n question). Repeat the
  steps if he wants to have a different one. Else apply the password on the
  server.

  If validate_password plugin is not present: Apply the password on the server.

* If password is not empty and validate_password plugin is installed,
  display the strength of existing password and prompt the user if he wishes to
  change it. If he wishes to, change the password just as mentioned in the
  previous point. Else, continue.
* On success of the previous step, prompt that anonymous users are removed by
  default for better security. Hit return key to continue or, any other key and
  return to retain anonymous users.
* Prompt that remote root login is to be removed by default for better security.
  Hit return key to continue or, any other key and return to retain remote login
  option.
* Same prompt as previous one for removing test database and access to it.
* Finally give an option to reload the privilege tables to implement all the
  changes with immediate effect.

The user can give the defaults conf file to be considered for connection
parameters using --defaults-file=

The following client options are supported for giving as command line arguments:
1) host
2) pipe
3) port
4) protocol
5) shared-memory-base-name
6) socket
7) user
8) SSL options
9) help

The prime difference between what is existing now, and what is proposed to be 
implemented would be that all the transactions mentioned above will be carried 
on using mysql API functions for C++ rather than using mysql client to connect. 
There will not be any need for a temporary config file where the password is 
stored and hence making the entire process secure.

List of Requirements:
1) The parameters used for connecting to a server like port and
   socket, should be taken in the following order of precedence:

   * Arguments given in command line.
   * Defaults file mentioned in command line.
   * The default my.cnf
   * Defaults mentioned in the program: port=3306 socket=/tmp/mysql.sock

2) By the end of the program, root account should have a
   non empty password.

3) After the root password is validated and the client connects to the server,
   user should get a prompt if he wants to set validate_password plugin. If it
   is already set, he shouldn't get any prompt. Strength of the password should
   be displayed in the subsequent steps only if the plugin is set.

4) If the user goes with the recommended options in each of
   the prompts, the server should have the following features.
   * No database with the name test.
   * No access to guest users.
   * No root accounts with hosts other than localhost, 127.0.0.1 and ::1