print-gssapi-sasl-ssf-psql.patch
text/x-diff
Filename: print-gssapi-sasl-ssf-psql.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/bin/psql/command.c | 0 | 0 |
| src/interfaces/libpq/exports.txt | 0 | 0 |
| src/interfaces/libpq/fe-secure.c | 0 | 0 |
| src/interfaces/libpq/fe-secure-gssapi.c | 0 | 0 |
| src/interfaces/libpq/libpq-fe.h | 0 | 0 |
| src/interfaces/libpq/libpq-int.h | 0 | 0 |
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
new file mode 100644
index ab259c4..2599330
*** a/src/bin/psql/command.c
--- b/src/bin/psql/command.c
*************** static void print_with_linenumbers(FILE
*** 159,164 ****
--- 159,165 ----
static void minimal_error_message(PGresult *res);
static void printSSLInfo(void);
+ static void printGSSENCInfo(void);
static bool printPsetInfo(const char *param, struct printQueryOpt *popt);
static char *pset_value_string(const char *param, struct printQueryOpt *popt);
*************** exec_command_conninfo(PsqlScanState scan
*** 621,626 ****
--- 622,628 ----
db, PQuser(pset.db), host, PQport(pset.db));
}
printSSLInfo();
+ printGSSENCInfo();
}
}
*************** connection_warnings(bool in_startup)
*** 3184,3189 ****
--- 3186,3192 ----
checkWin32Codepage();
#endif
printSSLInfo();
+ printGSSENCInfo();
}
}
*************** printSSLInfo(void)
*** 3216,3221 ****
--- 3219,3244 ----
(compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
}
+ /*
+ * printGSSENCInfo
+ *
+ * Prints information about the current GSS-Encrypted connection, if GSS
+ * encryption is in use.
+ */
+ static void
+ printGSSENCInfo(void)
+ {
+ const char *bits;
+
+ if (!PQgssEncInUse(pset.db))
+ return; /* no GSS Encryption */
+
+ bits = PQgetgssSASLSSF(pset.db);
+
+ printf(_("GSS Encrypted connection (bits: %s)\n"),
+ bits ? bits : _("unknown"));
+ }
+
/*
* checkWin32Codepage
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
new file mode 100644
index cc9ee9c..3db936f
*** a/src/interfaces/libpq/exports.txt
--- b/src/interfaces/libpq/exports.txt
*************** PQresultVerboseErrorMessage 171
*** 174,176 ****
--- 174,179 ----
PQencryptPasswordConn 172
PQresultMemorySize 173
PQhostaddr 174
+ PQgssEncInUse 175
+ PQgetgssctx 176
+ PQgetgssSASLSSF 177
diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c
new file mode 100644
index 5d9c1f8..df63882
*** a/src/interfaces/libpq/fe-secure-gssapi.c
--- b/src/interfaces/libpq/fe-secure-gssapi.c
***************
*** 17,22 ****
--- 17,24 ----
#include "libpq-int.h"
#include "fe-gssapi-common.h"
+ #include "port/pg_bswap.h"
+
/*
* Require encryption support, as well as mutual authentication and
* tamperproofing measures.
***************
*** 24,29 ****
--- 26,36 ----
#define GSS_REQUIRED_FLAGS GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \
GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG
+ static ssize_t send_buffered_data(PGconn *conn, size_t len);
+ static ssize_t read_from_buffer(PGconn *conn, void *ptr, size_t len);
+ static ssize_t load_packet_length(PGconn *conn);
+ static ssize_t load_packet(PGconn *conn, size_t len);
+
/*
* Helper function to write any pending data. Returns len when it has all
* been written; otherwise, sets errno appropriately. Assumes there is data
*************** pqsecure_open_gss(PGconn *conn)
*** 392,394 ****
--- 399,465 ----
gss_release_buffer(&minor, &output);
return PGRES_POLLING_WRITING;
}
+
+ /*
+ * GSSAPI Information functions.
+ */
+
+ /*
+ * Return the GSSAPI Context itself
+ */
+ void *
+ PQgetgssctx(PGconn *conn)
+ {
+ if (!conn)
+ return NULL;
+
+ return conn->gctx;
+ }
+
+ /*
+ * Return a string which represents the SASL SSF code.
+ *
+ * This is essentially the number of bits in the encryption key, or zero for
+ * no encryption or integrity, or 1 for integrity but no encryption.
+ *
+ * On error, NULL is returned.
+ */
+ const char *
+ PQgetgssSASLSSF(PGconn *conn)
+ {
+ uint32 tmp4,
+ result;
+ OM_uint32 major,
+ minor;
+ gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET;
+ gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF;
+ static char ssf[5] = "\0\0\0\0\0";
+
+ if (!conn)
+ return NULL;
+
+ /* Query the SSF value and range-check the result. */
+ major = gss_inquire_sec_context_by_oid(&minor, conn->gctx, ssf_oid, &bufset);
+
+ if (major != GSS_S_COMPLETE)
+ {
+ pg_GSS_error(libpq_gettext("GSSAPI inquire security context error"), conn, major, minor);
+ return NULL;
+ }
+
+ if (bufset->elements[0].length != 4)
+ return NULL;
+
+ /*
+ * gss_inquire_sec_context_by_oid() for GSS_C_SEC_CONTEXT_SASL_SSF returns a 32bit integer in network byte-order,
+ * so we need to adjust for that and then print the integer into our text string.
+ */
+ memcpy(&tmp4, bufset->elements[0].value, 4);
+ result = pg_ntoh32(tmp4);
+
+ snprintf(ssf,5,"%d",result);
+
+ (void)gss_release_buffer_set(&minor, &bufset);
+
+ return ssf;
+ }
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
new file mode 100644
index f8e24ee..c26a237
*** a/src/interfaces/libpq/fe-secure.c
--- b/src/interfaces/libpq/fe-secure.c
*************** PQsslInUse(PGconn *conn)
*** 137,142 ****
--- 137,150 ----
return conn->ssl_in_use;
}
+ int
+ PQgssEncInUse(PGconn *conn)
+ {
+ if (!conn)
+ return 0;
+ return conn->gssenc;
+ }
+
/*
* Exported function to allow application to tell us it's already
* initialized OpenSSL.
*************** PQsslAttributeNames(PGconn *conn)
*** 434,439 ****
--- 442,464 ----
}
#endif /* USE_SSL */
+ /* Dummy versions of GSSAPI info functions, when built without GSS support */
+ #ifndef ENABLE_GSS
+
+ void *
+ PQgetgssctx(PGconn *conn)
+ {
+ return NULL;
+ }
+
+ const char *
+ PQgetgssSASLSSF(PGconn *conn)
+ {
+ return NULL;
+ }
+
+ #endif /* ENABLE_GSS */
+
#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
new file mode 100644
index a6f928a..4980835
*** a/src/interfaces/libpq/libpq-fe.h
--- b/src/interfaces/libpq/libpq-fe.h
*************** extern void PQinitSSL(int do_init);
*** 347,352 ****
--- 347,357 ----
/* More detailed way to tell libpq whether it needs to initialize OpenSSL */
extern void PQinitOpenSSL(int do_ssl, int do_crypto);
+ /* GSSAPI information functions */
+ extern int PQgssEncInUse(PGconn *conn);
+ extern void *PQgetgssctx(PGconn *conn);
+ extern const char *PQgetgssSASLSSF(PGconn *conn);
+
/* Set verbosity for PQerrorMessage and PQresultErrorMessage */
extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
new file mode 100644
index aa95a80..cc39f33
*** a/src/interfaces/libpq/libpq-int.h
--- b/src/interfaces/libpq/libpq-int.h
***************
*** 47,54 ****
--- 47,56 ----
#ifdef ENABLE_GSS
#if defined(HAVE_GSSAPI_H)
#include <gssapi.h>
+ #include <gssapi_ext.h>
#else
#include <gssapi/gssapi.h>
+ #include <gssapi/gssapi_ext.h>
#endif
#endif