From patchwork Sat Sep 1 12:51:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mr Dash Four X-Patchwork-Id: 181134 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 6DC6E2C0081 for ; Sat, 1 Sep 2012 22:52:38 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753118Ab2IAMwU (ORCPT ); Sat, 1 Sep 2012 08:52:20 -0400 Received: from mail-wg0-f44.google.com ([74.125.82.44]:50503 "EHLO mail-wg0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751958Ab2IAMwT (ORCPT ); Sat, 1 Sep 2012 08:52:19 -0400 Received: by wgbdr13 with SMTP id dr13so3272956wgb.1 for ; Sat, 01 Sep 2012 05:52:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:mime-version :content-type:content-transfer-encoding; bh=ZNfJWBEtzJzxFKRj/MICeBxJti8j7iZDiCP3+INJRk0=; b=f2sef+wH9bCBFiX4Y1vwqFJ5T7MEessHgyOguU5A2pDNMTMwK6l1cWTJFNWxS8xgm9 VzDEwS02R97b+A0rdiiiW1gsgcXS3UNUM6SdQvN2fE/0iGPUor/zI4G+ri+8g3bkqGik nb2OBquW63GGftdtcs2TKzoasTYeuPUBdNeQCFTBmcQfGTWNkYjY19a1F02GEobWJxwb lJZUfsthP592GEqKgs4SN+bA8pSLpftLi7vadGZMq09svK+uVh5nde2cwG8+hwu1JE18 59p8JhHqFgKR76xFJJ6Y5fDxMR8ukgudfmSHbXnr5SA/hXcbuwbQ01cxRQicVaTcu1B7 4HKg== Received: by 10.180.96.3 with SMTP id do3mr11146850wib.5.1346503937777; Sat, 01 Sep 2012 05:52:17 -0700 (PDT) Received: from test7.my.net (cpc2-gill1-0-0-cust218.basl.cable.virginmedia.com. [82.34.56.219]) by mx.google.com with ESMTPS id cl8sm6831875wib.10.2012.09.01.05.52.16 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 01 Sep 2012 05:52:17 -0700 (PDT) From: Mr Dash Four To: Netfilter Core Team Cc: Mr Dash Four , Eric Leblond , Pablo Neira Ayuso Subject: [PATCH] pgsql: add SSL connection implementation to PGSQL plugin Date: Sat, 1 Sep 2012 13:51:51 +0100 Message-Id: <1346503911-3781-1-git-send-email-mr.dash.four@googlemail.com> X-Mailer: git-send-email 1.7.10.4 MIME-Version: 1.0 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org 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 --- 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"