Skip to content

Commit bee57c8

Browse files
[[ PostgreSQL SSL ]] Updated revOpenDatabase to handle the SSL connection options as key value pairs.
It was decided that key=value parameters were easier to use than one specific parameter per SSL option. Now any number of additional paramters can be passed to revOpenDatabase (for PostgreSQL connections) each specifying an SSL option in the form option_name=option_value. The docs note and dictionary entry have been updated accordingly.
1 parent 7d3da3e commit bee57c8

3 files changed

Lines changed: 75 additions & 61 deletions

File tree

docs/dictionary/function/revOpenDatabase.lcdoc

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Syntax: revOpenDatabase("odbc", <host> [: <port>], <databaseName>, [<userName>],
88

99
Syntax: revOpenDatabase("sqlite",filepath,[<sqliteOptions>])
1010

11-
Syntax: revOpenDatabase("postgresql", <host> [: <port>], <databaseName>, [<userName>], [<password>], [<sslmode>], [<sslcompression>], [<sslcert>], [<sslkey>], [<sslrootcert>], [<sslcrl>])
11+
Syntax: revOpenDatabase("postgresql", <host> [: <port>], <databaseName>, [<userName>], [<password>], [<sslOption>],...)
1212

1313
Syntax: revOpenDatabase("oracle", <host> [: <port>], <databaseName>, [<userName>],[<password>])
1414

@@ -40,7 +40,7 @@ Example:
4040
get revOpenDatabase("mysql", "localhost", "dbName", myUsr, myPass, false, "/var/mysql.sock", 1, true)
4141

4242
Example:
43-
get revOpenDatabase("postgresql", "192.168.1.100", "dbName", myUsr, myPass, "require")
43+
get revOpenDatabase("postgresql", "192.168.1.100", "dbName", myUsr, myPass, "sslmode=require", "sslcompression=0")
4444

4545
Parameters:
4646
host (string): A string specifying the IP address or domain name of the system hosting the database. For SQLite databases, the host should be the full path to the database file.
@@ -67,19 +67,21 @@ databaseType (enum): A string specifying the database type to use. One of the fo
6767
- "valentina"
6868
- "sqlite"
6969
filename: (SQLite Only) A string specifying the path to the SQLite database.
70-
sslmode: (PostgreSQL Only) A string specifying the SSL connection mode to use. There are 6 options:
71-
- "disable": Only try a non-SSL connection.
72-
- "allow": First try a non-SSL connection; if that fails, try an SSL connection.
73-
- "prefer": First try an SSL connection; if that fails, try a non-SSL connection.
74-
- "require": Only try an SSL connection. If a root CA file is present, verify the certificate in the same way as if verify-ca was specified.
75-
- "verify-ca": Only try an SSL connection, and verify that the server certificate is issued by a trusted certificate authority (CA).
76-
- "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.
77-
If no SSL mode is specified, the default will be "prefer" is the security library can be loaded, "disable" otherwise.
78-
sslcompression: (PostgreSQL Only) A string specifying the any SSL compression to use. If set to "1" (default), data sent over SSL connections will be compressed. If set to "0", compression will be disabled. This parameter is ignored if a connection without SSL is made. Compression uses CPU time, but can improve throughput if the network is the bottleneck. Disabling compression can improve response time and throughput if CPU performance is the limiting factor.
79-
sslcert: (PostgreSQL Only) A string specifying the file name of the client SSL certificate, replacing the default ~/.postgresql/postgresql.crt. This parameter is ignored if an SSL connection is not made.
80-
sslkey: (PostgreSQL Only) A string specifying the location for the secret key used for the client certificate. This parameter is ignored if an SSL connection is not made.
81-
sslrootcert: (PostgreSQL Only) A string specifying 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. The default is ~/.postgresql/root.crt.
82-
sslcrl: (PostgreSQL Only) A string specifying 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. The default is ~/.postgresql/root.crl.
70+
sslOption (string): (PostgreSQL Only) A string of the form "key=value" specifying the SSL options to use when connecting. The key is the name of the option you want to set, the value is the value you want the option to take. Any number of key value pairs can be specified, each in a new parameter. The set of recognized SSL option and their expected values are as follows:
71+
- **"sslmode"**: A string specifying the SSL connection mode to use. There are 6 options:
72+
- "disable": Only try a non-SSL connection.
73+
- "allow": First try a non-SSL connection; if that fails, try an SSL connection.
74+
- "prefer": First try an SSL connection; if that fails, try a non-SSL connection.
75+
- "require": Only try an SSL connection. If a root CA file is present, verify the certificate in the same way as if verify-ca was specified.
76+
- "verify-ca": Only try an SSL connection, and verify that the server certificate is issued by a trusted certificate authority (CA).
77+
- "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.
78+
79+
If no SSL mode is specified, the default will be "prefer" if the security library can be loaded, "disable" if not. If you use SSL connections in a standalone application, remember to select 'SSL Encryption' from among the available 'script libraries' in the standalone application settings panel.
80+
- **"sslcompression"**: A string specifying the any SSL compression to use. If set to "1" (default), data sent over SSL connections will be compressed. If set to "0", compression will be disabled. This parameter is ignored if a connection without SSL is made. Compression uses CPU time, but can improve throughput if the network is the bottleneck. Disabling compression can improve response time and throughput if CPU performance is the limiting factor.
81+
- **"sslcert"**: A string specifying the file name of the client SSL certificate, replacing the default ~/.postgresql/postgresql.crt. This parameter is ignored if an SSL connection is not made.
82+
- **"sslkey"**: A string specifying the location for the secret key used for the client certificate. This parameter is ignored if an SSL connection is not made.
83+
- **sslrootcert"**: A string specifying 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. The default is ~/.postgresql/root.crt.
84+
- **"sslcrl"**: A string specifying 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. The default is ~/.postgresql/root.crl.
8385

8486
Returns:
8587
The <revOpenDatabase> function returns a database ID which can be used to refer to the database in other Database library commands and functions. The database ID is always an integer.
@@ -92,7 +94,7 @@ Use the <revOpenDatabase> function to start working with a database.
9294

9395
>*Important:* The revOpenDatabase function is part of the Database library. To ensure that the function works in a standalone application, you must include this custom library when you create your standalone. In the Inclusions section of the General screen of the Standalone Application Settings window, make sure the Database Support checkbox is checked and the database drivers you are using are selected in the list of database drivers.
9496

95-
>*Important:* If you are using any of the MySQL or PostgreSQL SSL connection options, make sure to select 'SSL Encryption' from among the available 'script libraries' in the standalone application settings panel.
97+
>*Important:* If you are using any of the MySQL or PostgreSQL SSL connection options in a standalone application, make sure to select 'SSL Encryption' from among the available 'script libraries' in the standalone application settings panel.
9698

9799
The version of SQLite has been updated to 3.8.2.
98100

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# SSL Support for PostgreSQL Connections
22

3-
The PostgreSQL database driver has been updated to support secure connections. The desired SSL connection mode can be specified in the sixth parameter of revOpenDatabase.
3+
The PostgreSQL database driver has been updated to support secure connections. The desired SSL connection options can be specified as key value pairs in the additional parameters of revOpenDatabase.
44

55
The syntax for connecting to PostgreSQL databases is now as follows:
66

7-
***revOpenDatabase(*** "postgresql", *<host>[<:port>]*, *<databasename>*, *[<username>]*, *[<password>]*, *[<sslmode>]*, *[<sslcompression>]*, *[<sslcert>]*, *[<sslkey>]*, *[<sslrootcert>]*, *[<sslcrl>]* ***)***
7+
**revOpenDatabase(** "postgresql", *<host>[<:port>]*, *<databasename>*, *[<username>]*, *[<password>]*, *[<ssloption>*=*<ssloptionvalue>]*,...**)**
88

9-
For full information on the new parameters see the dictionary entry for ***revOpenDatabase***.
9+
For full information on the new parameters see the dictionary entry for **revOpenDatabase**.

revdb/src/postgresql_connection.cpp

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -64,58 +64,72 @@ Bool DBConnection_POSTGRESQL::connect(char **args, int numargs)
6464
*t_delimiter = '\0';
6565
}
6666

67+
const char *t_sslmode;
68+
t_sslmode = NULL;
69+
const char *t_sslcompression;
70+
t_sslcompression = NULL;
71+
const char *t_sslcert;
72+
t_sslcert = NULL;
73+
const char *t_sslkey;
74+
t_sslkey = NULL;
75+
const char *t_sslrootcert;
76+
t_sslrootcert = NULL;
77+
const char *t_sslcrl;
78+
t_sslcrl = NULL;
79+
80+
// extract any ssl options spcified as key value pairs in the final args to revOpenDatabase
81+
// e.g. sslmode=require
82+
const char *t_ssl_opt_key;
83+
t_ssl_opt_key = NULL;
84+
const char *t_ssl_opt_val;
85+
t_ssl_opt_val = NULL;
86+
for (int i = 4; i < numargs; i++)
87+
{
88+
t_delimiter = strchr(args[i], '=');
89+
if (t_delimiter != NULL)
90+
{
91+
*t_delimiter = '\0';
92+
t_ssl_opt_key = args[i];
93+
t_ssl_opt_val = (t_delimiter + (1 * sizeof(char)));
94+
95+
if (*t_ssl_opt_val != '\0')
96+
{
97+
if (strcmp(t_ssl_opt_key, "sslmode") == 0)
98+
t_sslmode = t_ssl_opt_val;
99+
else if (strcmp(t_ssl_opt_key, "sslcompression") == 0)
100+
t_sslcompression = t_ssl_opt_val;
101+
else if (strcmp(t_ssl_opt_key, "sslcert") == 0)
102+
t_sslcert = t_ssl_opt_val;
103+
else if (strcmp(t_ssl_opt_key, "sslkey") == 0)
104+
t_sslkey = t_ssl_opt_val;
105+
else if (strcmp(t_ssl_opt_key, "sslrootcert") == 0)
106+
t_sslrootcert = t_ssl_opt_val;
107+
else if (strcmp(t_ssl_opt_key, "sslcrl") == 0)
108+
t_sslcrl = t_ssl_opt_val;
109+
}
110+
}
111+
}
112+
67113
bool t_have_ssl;
68114
t_have_ssl = load_ssl_library();
69115

70116
// if an ssl mode (other than disable) has been passed, make sure we can load libopenssl
71-
// if no ssl mode has been passed, use prefer if we have libopenssl (try an ssl connection,
72-
// if that fails try non-ssl), if we don't have libopenssl, don't attempt an ssl connection (disable sslmode)
73-
char *t_sslmode;
74-
t_sslmode = NULL;
75-
if (numargs > 4)
117+
// if no ssl mode has been passed, use prefer if we have libopenssl (try an ssl connection, if that fails try non-ssl)
118+
// if we don't have libopenssl, use disable (don't attempt an ssl connection)
119+
const char *t_sslmode_prefer = "prefer";
120+
const char *t_sslmode_disable = "disable";
121+
if (t_sslmode != NULL)
76122
{
77-
if (strcmp(args[4], "disable") != 0 && !t_have_ssl)
123+
if (strcmp(t_sslmode, "disable") != 0 && !t_have_ssl)
78124
{
79125
errorMessageSet("revdb,unable to load SSL library");
80126
return false;
81127
}
82-
t_sslmode = strdup(args[4]);
83128
}
84129
else if (t_have_ssl)
85-
t_sslmode = strdup("prefer");
130+
t_sslmode = t_sslmode_prefer;
86131
else
87-
t_sslmode = strdup("disable");
88-
89-
if (t_sslmode == NULL)
90-
{
91-
errorMessageSet("revdb,unable to extract SSL mode");
92-
return false;
93-
}
94-
95-
char *t_sslcompression;
96-
t_sslcompression = NULL;
97-
if (numargs > 5)
98-
t_sslcompression = args[5];
99-
100-
char *t_sslcert;
101-
t_sslcert = NULL;
102-
if (numargs > 6)
103-
t_sslcert = args[6];
104-
105-
char *t_sslkey;
106-
t_sslkey = NULL;
107-
if (numargs > 7)
108-
t_sslkey = args[7];
109-
110-
char *t_sslrootcert;
111-
t_sslrootcert = NULL;
112-
if (numargs > 8)
113-
t_sslrootcert = args[8];
114-
115-
char *t_sslcrl;
116-
t_sslcrl = NULL;
117-
if (numargs > 9)
118-
t_sslcrl = args[9];
132+
t_sslmode = t_sslmode_disable;
119133

120134
const char *t_connect_keys[] =
121135
{
@@ -155,8 +169,6 @@ Bool DBConnection_POSTGRESQL::connect(char **args, int numargs)
155169
dbconn = NULL;
156170
dbconn = PQconnectdbParams(t_connect_keys, t_connect_values, 0);
157171

158-
free(t_sslmode);
159-
160172
// OK-2008-05-16 : Bug where failed connections to postgres databases would
161173
// not return any error information. According to the postgres docs, dbconn
162174
// will only be null if there was not enough memory to allocate it.

0 commit comments

Comments
 (0)