Yesterday I sent a PR (already merged) for cacti adding some extra SSL options that are available in the PDO API.
I wanted to do a similar work on spine to add the following c connector options:
- MYSQL_OPT_SSL_CAPATH
- MYSQL_OPT_SSL_MODE (mysql)
- MYSQL_OPT_SSL_ENFORCE (mariadb)
- mariadb's c conn doc say that mysql_options() is deprecated in favor of mysql_optionsv() which doesn't exist in mysql's c conn [1]
- mysql c conn uses MYSQL_OPT_SSL_MODE to specify if you want to make SSL mandatory and verify (or not) the server's certificate
- mariadb c conn uses MYSQL_OPT_SSL_ENFORCE and MYSQL_OPT_SSL_VERIFY_SERVER_CERT for the same result
There are some potential solutions to solve this issue.
One solution is to expand the configure checks to be able to detect which C/Connector lib is available as well as the version of the API, then add the usual #ifdefs in the code, with the risk of making the code more complex or harder to maintain.
Another other solution is to use the C/Connector's MYSQL_READ_DEFAULT_FILE and MYSQL_READ_DEFAULT_GROUP option that allows you to read configurations options from a specific group in an mysql configuration file (.cnf). Both connector libraries support this. IMO, this seems the cleaner solution.
With the second solution you would then just have to declare the .cnf file's location in spine.conf, and use that .cnf file to choose among the current available SSL options for mariadb or mysql. You could have two different .cnf files for the DB and RDB settings or combine them into a single file using groups within that file.
The only place in spine where the database options are used is in sql.c, just before opening a connection. By using a .cnf file, spine can delegate both the parsing and the set up of the options declared there to the C/Connector API MYSQL_READ_DEFAULT_FILE option. Spine wouldn't need to do that anymore: less code to maintain and more flexibility in supporting those features, in spite of the API differences.
Here's a mock-up of spine.conf and the db.cnf files, assuming you are using only one db file and two groups
The spine.conf file would be reduced to:
[[
Cacti_Log /var/www/html/cacti/log/cacti.log
Database_Configuration /etc/spine/db.cnf
...
]]
A spine.cnf (a la mysql) file could look like this:
[[
[spine-db]
host = localhost
port = 3306
database = cacti
user = cactiuser
password = cactiuser
#ssl-key =
#ssl-cert =
#ssl-ca =
ssl-capath = /etc/ssl/certs
# available only on mdb c/conn 3.1.1
#ssl-enforce = on
[spine-rdb]
#host = localhost
#port = 3306
#database = cacti
#user = cactiuser
#password = cactiuser
#ssl-key =
#ssl-cert =
#ssl-ca =
#ssl-capath = /etc/ssl/certs
]]
In sql.c:db_connect() , the parsing and initialization code could be simplified to:
[[
...
if (type == REMOTE) {
MYSQL_SET_OPTION(MYSQL_READ_DEFAULT_GROUP, "spine-rdb");
} else {
MYSQL_SET_OPTION(MYSQL_READ_DEFAULT_GROUP, "spine-db");
}
mysql_options(con, MYSQL_READ_DEFAULT_FILE, "db_config_file");
/* no need to give host, password, etc.. all of that info was already parsed with READ_DEFAULT_FILE) */
connect_error = mysql_real_connect(mysql, NULL, NULL, NULL, NULL, 0, NULL, 0);
...
]]
And you could remove all the config variables and parsing / initialization of those variables from util.c and spine.h.
You may need to adust your logs if they were using those variables. If needed, you can always query the database connection thru the C/Connector to get its characteristics.
And... after doing this big change, then we could use the new SSL features that are proposed by the C/Connectors without needing to parse and do individual MYSQL_SET_OPTION calls for them.
The only place where you won't be able to avoid adding C/Connector API version detection will be for the mysql_options() following its recent deprecationin mariadb's C/Connector, as mentioned above. You will need to use configure for that. There are already some m4 macros you can use for this purpose to save you time [3].
To summarize my message, if you add the above changes there won't be any need for me to add any specific calls to the new SSL options; the C/Connector will take care of those automatically by reading the .cnf file and doing the options setup by itself. Your code will be more flexible with regards to the evolution of these options and it will be better factorized.
Some planning is needed to know if you want to have a single .cnf file combining both DB and RDB sections or separate files, what log changes you want and making some .cnf.dist files for mariadb and mysql to guide users through that.
[1] https://mariadb.com/kb/en/mysql_options/
[2] https://mariadb.com/kb/en/mysql_optionsv/#options
[3] https://github.com/hholzgra/mysql-m4/bl ... /README.md