summaryrefslogtreecommitdiff
path: root/src/backend/utils/misc/guc.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2020-01-18 12:32:55 +0900
committerMichael Paquier <michael@paquier.xyz>2020-01-18 12:32:55 +0900
commitac2dcca5dfe62177fd871a8f4f71430a1c92382c (patch)
treed4af39a9daf97418bde671e2d1179ce696703349 /src/backend/utils/misc/guc.c
parent2e2646060e18461de24e3585344095664dc7727b (diff)
Add GUC checks for ssl_min_protocol_version and ssl_max_protocol_version
Mixing incorrect bounds set in the SSL context leads to confusing error messages generated by OpenSSL which are hard to act on. New checks are added within the GUC machinery to improve the user experience as they apply to any SSL implementation, not only OpenSSL, and doing the checks beforehand avoids the creation of a SSL during a reload (or startup) which we know will never be used anyway. Backpatch down to 12, as those parameters have been introduced by e73e67c. Author: Michael Paquier Reviewed-by: Daniel Gustafsson Discussion: https://postgr.es/m/20200114035420.GE1515@paquier.xyz Backpatch-through: 12
Diffstat (limited to 'src/backend/utils/misc/guc.c')
-rw-r--r--src/backend/utils/misc/guc.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index dc8f910ea46..c94fe584177 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -201,6 +201,10 @@ static bool check_cluster_name(char **newval, void **extra, GucSource source);
static const char *show_unix_socket_permissions(void);
static const char *show_log_file_mode(void);
static const char *show_data_directory_mode(void);
+static bool check_ssl_min_protocol_version(int *newval, void **extra,
+ GucSource source);
+static bool check_ssl_max_protocol_version(int *newval, void **extra,
+ GucSource source);
static bool check_recovery_target_timeline(char **newval, void **extra, GucSource source);
static void assign_recovery_target_timeline(const char *newval, void *extra);
static bool check_recovery_target(char **newval, void **extra, GucSource source);
@@ -4522,7 +4526,7 @@ static struct config_enum ConfigureNamesEnum[] =
&ssl_min_protocol_version,
PG_TLS1_VERSION,
ssl_protocol_versions_info + 1, /* don't allow PG_TLS_ANY */
- NULL, NULL, NULL
+ check_ssl_min_protocol_version, NULL, NULL
},
{
@@ -4534,7 +4538,7 @@ static struct config_enum ConfigureNamesEnum[] =
&ssl_max_protocol_version,
PG_TLS_ANY,
ssl_protocol_versions_info,
- NULL, NULL, NULL
+ check_ssl_max_protocol_version, NULL, NULL
},
/* End-of-list marker */
@@ -11463,6 +11467,49 @@ show_data_directory_mode(void)
}
static bool
+check_ssl_min_protocol_version(int *newval, void **extra, GucSource source)
+{
+ int new_ssl_min_protocol_version = *newval;
+
+ /* PG_TLS_ANY is not supported for the minimum bound */
+ Assert(new_ssl_min_protocol_version > PG_TLS_ANY);
+
+ if (ssl_max_protocol_version &&
+ new_ssl_min_protocol_version > ssl_max_protocol_version)
+ {
+ GUC_check_errhint("\"%s\" cannot be higher than \"%s\".",
+ "ssl_min_protocol_version",
+ "ssl_max_protocol_version");
+ GUC_check_errcode(ERRCODE_INVALID_PARAMETER_VALUE);
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+check_ssl_max_protocol_version(int *newval, void **extra, GucSource source)
+{
+ int new_ssl_max_protocol_version = *newval;
+
+ /* if PG_TLS_ANY, there is no need to check the bounds */
+ if (new_ssl_max_protocol_version == PG_TLS_ANY)
+ return true;
+
+ if (ssl_min_protocol_version &&
+ ssl_min_protocol_version > new_ssl_max_protocol_version)
+ {
+ GUC_check_errhint("\"%s\" cannot be lower than \"%s\".",
+ "ssl_max_protocol_version",
+ "ssl_min_protocol_version");
+ GUC_check_errcode(ERRCODE_INVALID_PARAMETER_VALUE);
+ return false;
+ }
+
+ return true;
+}
+
+static bool
check_recovery_target_timeline(char **newval, void **extra, GucSource source)
{
RecoveryTargetTimeLineGoal rttg;