This patch fixes a NULL pointer reference bug which existed in the PGSQL output plugin, as well as enables SSL connections to be made to PostgreSQL server by the ulog daemon. Parameters introduced are: 'sslmode' - one of: disable - only try a non-SSL connection allow - first try a non-SSL connection; if that fails, try SSL connection prefer - (default) first try an SSL connection; if that fails, try a non-SSL connection require - only try an SSL connection requiressl - equivalent to 'require', but for older PostgreSQL server versions verify-ca - only try an SSL connection, and verify that the server certificate is issued by a trusted CA verify-full - only try an SSL connection, verify that the server certificate is issued by a trusted CA and that the server host name matches that in the certificate In addition to the above parameter, 4 other connection options can be specified: 'sslcert' - This parameter specifies the file name of the client SSL certificate. This parameter is ignored if an SSL connection is not made. 'sslkey' - This parameter specifies the location for the secret key used for the client certificate. It can either specify a file name that will be used or it can specify a key obtained from an external “engine” (engines are OpenSSL loadable modules). An external engine specification should consist of a colon-separated engine name and an engine-specific key identifier. This parameter is ignored if SSL connection is not made. If this key is protected with a password, this will be asked when the connection is made. It is asked every time an attempt for a connection is made. 'sslroot' - This parameter specifies the name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities. 'sslcrl' - This parameter specifies the file name of the SSL certificate revocation list (CRL). Certificates listed in this file, if it exists, will be rejected while attempting to authenticate the server's certificate. Example of use: ulogd.conf ~~~~~~~~~~ [pgsql3] db="ulogdb" host="10.1.1.17" port=5432 user="ulogd" pass="changeme" table="nfacct" procedure="INSERT_NFACCT" sslmode="verify-full" sslcert="/etc/pki/tls/private/postgresql.crt" sslkey="/etc/pki/tls/private/postgresql.key" sslroot="/etc/pki/tls/private/root.crt" sslcrl="/etc/pki/tls/private/root.crl" Signed-off-by: Mr Dash Four <mr.dash.four@xxxxxxxxxxxxxx> --- output/pgsql/ulogd_output_PGSQL.c | 99 ++++++++++++++++++++++++++++++++----- ulogd.conf.in | 26 ++++++++++ 2 files changed, 113 insertions(+), 12 deletions(-) diff --git a/output/pgsql/ulogd_output_PGSQL.c b/output/pgsql/ulogd_output_PGSQL.c index cd793ca..c99a0d7 100644 --- a/output/pgsql/ulogd_output_PGSQL.c +++ b/output/pgsql/ulogd_output_PGSQL.c @@ -38,7 +38,7 @@ struct pgsql_instance { /* our configuration directives */ static struct config_keyset pgsql_kset = { - .num_ces = DB_CE_NUM + 6, + .num_ces = DB_CE_NUM + 11, .ces = { DB_CES, { @@ -70,8 +70,32 @@ static struct config_keyset pgsql_kset = { .key = "schema", .type = CONFIG_TYPE_STRING, .options = CONFIG_OPT_NONE, - .u.string = "public", }, + { // sslmode=disable|allow|prefer|require|requiressl|verify-ca|verify-full + .key = "sslmode", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, + { + .key = "sslcert", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, + { + .key = "sslkey", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, + { + .key = "sslroot", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, + { + .key = "sslcrl", + .type = CONFIG_TYPE_STRING, + .options = CONFIG_OPT_NONE, + }, }, }; #define db_ce(x) (x->ces[DB_CE_NUM+0]) @@ -80,6 +104,11 @@ static struct config_keyset pgsql_kset = { #define pass_ce(x) (x->ces[DB_CE_NUM+3]) #define port_ce(x) (x->ces[DB_CE_NUM+4]) #define schema_ce(x) (x->ces[DB_CE_NUM+5]) +#define sslmode_ce(x) (x->ces[DB_CE_NUM+6]) +#define sslcert_ce(x) (x->ces[DB_CE_NUM+7]) +#define sslkey_ce(x) (x->ces[DB_CE_NUM+8]) +#define sslroot_ce(x) (x->ces[DB_CE_NUM+9]) +#define sslcrl_ce(x) (x->ces[DB_CE_NUM+10]) #define PGSQL_HAVE_NAMESPACE_TEMPLATE \ "SELECT nspname FROM pg_namespace n WHERE n.nspname='%s'" @@ -127,9 +156,12 @@ static int pgsql_namespace(struct ulogd_pluginstance *upi) static int get_columns_pgsql(struct ulogd_pluginstance *upi) { struct pgsql_instance *pi = (struct pgsql_instance *) upi->private; + char *table = table_ce(upi->config_kset).u.string; + char *schema = schema_ce(upi->config_kset).u.string; + int schema_len = strlen(schema); char pgbuf[strlen(PGSQL_GETCOLUMN_TEMPLATE_SCHEMA) - + strlen(table_ce(upi->config_kset).u.string) - + strlen(pi->db_inst.schema) + 2]; + + strlen(table) + + schema_len + 2]; int i; if (!pi->dbh) { @@ -137,14 +169,14 @@ static int get_columns_pgsql(struct ulogd_pluginstance *upi) return 1; } - if (pi->db_inst.schema) { + if (schema_len > 0) { snprintf(pgbuf, sizeof(pgbuf)-1, PGSQL_GETCOLUMN_TEMPLATE_SCHEMA, - table_ce(upi->config_kset).u.string, - pi->db_inst.schema); + schema, + table); } else { snprintf(pgbuf, sizeof(pgbuf)-1, PGSQL_GETCOLUMN_TEMPLATE, - table_ce(upi->config_kset).u.string); + table); } ulogd_log(ULOGD_DEBUG, "%s\n", pgbuf); @@ -217,23 +249,39 @@ static int open_db_pgsql(struct ulogd_pluginstance *upi) { struct pgsql_instance *pi = (struct pgsql_instance *) upi->private; int len; + int status; char *connstr; char *server = host_ce(upi->config_kset).u.string; unsigned int port = port_ce(upi->config_kset).u.value; char *user = user_ce(upi->config_kset).u.string; char *pass = pass_ce(upi->config_kset).u.string; char *db = db_ce(upi->config_kset).u.string; + char *sslmode = sslmode_ce(upi->config_kset).u.string; + char *sslcert = sslcert_ce(upi->config_kset).u.string; + char *sslkey = sslkey_ce(upi->config_kset).u.string; + char *sslroot = sslroot_ce(upi->config_kset).u.string; + char *sslcrl = sslcrl_ce(upi->config_kset).u.string; /* 80 is more than what we need for the fixed parts below */ len = 80 + strlen(user) + strlen(db); - /* hostname and and password are the only optionals */ + /* hostname and password are not the only optional parameters */ if (server) len += strlen(server); if (pass) len += strlen(pass); if (port) len += 20; + if (sslmode) + len += strlen(sslmode); + if (sslcert) + len += strlen(sslcert); + if (sslkey) + len += strlen(sslkey); + if (sslroot) + len += strlen(sslroot); + if (sslcrl) + len += strlen(sslcrl); connstr = (char *) malloc(len); if (!connstr) @@ -261,10 +309,37 @@ static int open_db_pgsql(struct ulogd_pluginstance *upi) strcat(connstr, pass); } + if (sslmode && strlen(sslmode) > 0) { + if (strncmp(sslmode, "requiressl", 10) == 0) { + strcat(connstr, " requiressl=1"); + } else { + strcat(connstr, " sslmode="); + strcat(connstr, sslmode); + } + + if (sslcert && strlen(sslcert) > 0) { + strcat(connstr, " sslcert="); + strcat(connstr, sslcert); + } + if (sslkey && strlen(sslkey)) { + strcat(connstr, " sslkey="); + strcat(connstr, sslkey); + } + if (sslroot && strlen(sslroot)) { + strcat(connstr, " sslrootcert="); + strcat(connstr, sslroot); + } + if (sslcrl && strlen(sslcrl)) { + strcat(connstr, " sslcrl="); + strcat(connstr, sslcrl); + } + } + pi->dbh = PQconnectdb(connstr); - if (PQstatus(pi->dbh) != CONNECTION_OK) { - ulogd_log(ULOGD_ERROR, "unable to connect to db (%s): %s\n", - connstr, PQerrorMessage(pi->dbh)); + status = PQstatus(pi->dbh); + if (status != CONNECTION_OK) { + ulogd_log(ULOGD_ERROR, "unable to connect to db (%s): %s; status=%u\n", + connstr, PQerrorMessage(pi->dbh),status); close_db_pgsql(upi); return -1; } diff --git a/ulogd.conf.in b/ulogd.conf.in index 3bd464b..81dabdc 100644 --- a/ulogd.conf.in +++ b/ulogd.conf.in @@ -240,6 +240,32 @@ table="nfacct" pass="changeme" procedure="INSERT_NFACCT" +[pgsql5] +db="nulog" +host="localhost" +user="nupik" +table="ulog2_ct" +pass="changeme" +procedure="INSERT_OR_REPLACE_CT" +sslmode="prefer" +sslcert="/etc/pki/tls/private/ct.crt" +sslkey="/etc/pki/tls/private/ct.key" +sslroot="/etc/pki/tls/private/root.crt" +sslcrl="/etc/pki/tls/private/root.crl" + +[pgsql6] +db="nulog" +host="localhost" +user="nupik" +table="nfacct" +pass="changeme" +procedure="INSERT_NFACCT" +sslmode="verify-full" +sslcert="/etc/pki/tls/private/nfacct.crt" +sslkey="/etc/pki/tls/private/nfacct.key" +sslroot="/etc/pki/tls/private/root.crt" +sslcrl="/etc/pki/tls/private/root.crl" + [dbi1] db="ulog2" dbtype="pgsql" -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html