xmlrpc-c/gssapi-delegate.patch
Enrico Scholz cd25c35791 updated to 1.25.13
rediffed some patches; removed 'struct-serialize' patch which was
applied upstream in 1.25.12
2012-01-04 13:06:01 +01:00

276 lines
10 KiB
Diff

From 867cf74ae3a95da7483e94052fd9b3743beb86ec Mon Sep 17 00:00:00 2001
From: giraffedata <giraffedata@adbb7d4b-a73a-0410-a071-c5f57c452bd4>
Date: Sun, 7 Aug 2011 02:50:57 +0000
Subject: [PATCH 9/9] backported GSSAPI_DELEGATION patch
---
include/xmlrpc-c/client.h | 1 +
include/xmlrpc-c/client_transport.hpp | 1 +
lib/curl_transport/curltransaction.c | 108 +++++++++++++++++++++++++++-
lib/curl_transport/curltransaction.h | 3 +
lib/curl_transport/curlversion.h | 6 ++
lib/curl_transport/xmlrpc_curl_transport.c | 5 ++
src/cpp/curl.cpp | 8 ++-
7 files changed, 129 insertions(+), 3 deletions(-)
diff --git a/include/xmlrpc-c/client.h b/include/xmlrpc-c/client.h
index 99eefd7..8dd3842 100644
--- a/include/xmlrpc-c/client.h
+++ b/include/xmlrpc-c/client.h
@@ -108,6 +108,7 @@ struct xmlrpc_curl_xportparms {
enum xmlrpc_httpproxyauth values
*/
const char * proxy_userpwd;
+ xmlrpc_bool gssapi_delegation;
};
diff --git a/include/xmlrpc-c/client_transport.hpp b/include/xmlrpc-c/client_transport.hpp
index ada5b5d..58a8c52 100644
--- a/include/xmlrpc-c/client_transport.hpp
+++ b/include/xmlrpc-c/client_transport.hpp
@@ -292,6 +292,7 @@ public:
constrOpt & proxy_auth (unsigned int const& arg);
constrOpt & proxy_userpwd (std::string const& arg);
constrOpt & proxy_type (xmlrpc_httpproxytype const& arg);
+ constrOpt & gssapi_delegation (bool const& arg);
private:
struct constrOpt_impl * implP;
diff --git a/lib/curl_transport/curltransaction.c b/lib/curl_transport/curltransaction.c
index 1ae6765..9cd6204 100644
--- a/lib/curl_transport/curltransaction.c
+++ b/lib/curl_transport/curltransaction.c
@@ -448,6 +448,99 @@ assertConstantsMatch(void) {
+/* About Curl and GSSAPI credential delegation:
+
+ Up through Curl 7.21.6, libcurl always delegates GSSAPI credentials, which
+ means it gives the client's secrets to the server so the server can operate
+ on the client's behalf. In mid-2011, this was noticed to be a major
+ security exposure, because the server is not necessarily trustworthy.
+ One is supposed to delegate one's credentials only to a server one trusts.
+ So in 7.21.7, Curl never delegates GSSAPI credentials.
+
+ But that causes problems for clients that _do_ trust their server, which
+ had always relied upon Curl's delegation.
+
+ So starting in 7.21.8, Curl gives the user the choice. The default is no
+ delegation, but the Curl user can set the CURLOPT_GSSAPI_DELEGATION flag to
+ order delegation.
+
+ Complicating matters is that some people made local variations of Curl
+ during the transition phase, so the version number alone isn't
+ determinative, so we rely on it only where we have to.
+
+ So Xmlrpc-c gives the same choice to its own user, via its
+ 'gssapi_delegation' Curl transport option.
+
+ Current Xmlrpc-c can be linked with, and compiled with, any version of
+ Curl, so it has to carefully consider all the possibilities.
+*/
+
+
+
+static bool
+curlAlwaysDelegatesGssapi(void) {
+/*----------------------------------------------------------------------------
+ The Curl library we're using always delegates GSSAPI credentials
+ (we don't have a choice).
+
+ This works with Curl as distributed by the Curl project, but there are
+ other versions of Curl for which it doesn't -- those versions report
+ older version numbers but in fact don't always delegate. Some never
+ delegate, and some give the user the option.
+-----------------------------------------------------------------------------*/
+ curl_version_info_data * const curlInfoP =
+ curl_version_info(CURLVERSION_NOW);
+
+ return (curlInfoP->version_num <= 0x071506); /* 7.21.6 */
+}
+
+
+
+static void
+requestGssapiDelegation(CURL * const curlSessionP ATTR_UNUSED,
+ bool * const gotItP) {
+/*----------------------------------------------------------------------------
+ Set up the Curl session *curlSessionP to delegate its GSSAPI credentials to
+ the server.
+
+ Return *gotitP is true iff we succeed. We fail when the version of libcurl
+ for which we are compiled or to which we are linked is not capable of such
+ delegation.
+-----------------------------------------------------------------------------*/
+#if HAVE_CURL_GSSAPI_DELEGATION
+ int rc;
+
+ rc = curl_easy_setopt(curlSessionP, CURLOPT_GSSAPI_DELEGATION,
+ CURLGSSAPI_DELEGATION_FLAG);
+
+ if (rc == CURLE_OK)
+ *gotItP = true;
+ else {
+ /* The only way curl_easy_setopt() could have failed is that we
+ are running with an old libcurl from before
+ CURLOPT_GSSAPI_DELEGATION was invented.
+ */
+ if (curlAlwaysDelegatesGssapi()) {
+ /* No need to request delegation; we got it anyway */
+ *gotItP = true;
+ } else
+ *gotItP = false;
+ }
+#else
+ if (curlAlwaysDelegatesGssapi())
+ *gotItP = true;
+ else {
+ /* The library may be able to do credential delegation on request, but
+ we have no way to request it; the Curl for which we are compiled is
+ too old.
+ */
+ *gotItP = false;
+ }
+#endif
+}
+
+
+
static void
setupCurlSession(xmlrpc_env * const envP,
curlTransaction * const curlTransactionP,
@@ -482,7 +575,7 @@ setupCurlSession(xmlrpc_env * const envP,
a particular transaction finished.
*/
- /* It is out policy to do a libcurl call only where necessary, I.e. not
+ /* It is our policy to do a libcurl call only where necessary, I.e. not
to set what is the default anyhow. The reduction in calls may save
some time, but mostly, it will save us encountering rare bugs or
suffering from backward incompatibilities in future libcurl. I.e. we
@@ -593,7 +686,18 @@ setupCurlSession(xmlrpc_env * const envP,
if (curlSetupP->timeout)
setCurlTimeout(curlSessionP, curlSetupP->timeout);
- {
+ if (curlSetupP->gssapiDelegation) {
+ bool gotIt;
+ requestGssapiDelegation(curlSessionP, &gotIt);
+
+ if (!gotIt)
+ xmlrpc_faultf(envP, "Cannot honor 'gssapi_delegation' "
+ "Curl transport option. "
+ "This version of libcurl is not "
+ "capable of delegating GSSAPI credentials");
+ }
+
+ if (!envP->fault_occurred) {
const char * authHdrValue;
/* NULL means we don't have to construct an explicit
Authorization: header. non-null means we have to
diff --git a/lib/curl_transport/curltransaction.h b/lib/curl_transport/curltransaction.h
index 4edc365..585dcca 100644
--- a/lib/curl_transport/curltransaction.h
+++ b/lib/curl_transport/curltransaction.h
@@ -81,6 +81,9 @@ struct curlSetup {
unsigned int proxyType;
/* see enum curl_proxytype: CURLPROXY_HTTP, CURLPROXY_SOCKS4, ... */
+ bool gssapiDelegation;
+ /* allow GSSAPI credential delegation */
+
unsigned int timeout;
/* 0 = no Curl timeout. This is in milliseconds. */
diff --git a/lib/curl_transport/curlversion.h b/lib/curl_transport/curlversion.h
index 71c5a68..4ad445a 100644
--- a/lib/curl_transport/curlversion.h
+++ b/lib/curl_transport/curlversion.h
@@ -14,6 +14,12 @@
#define HAVE_CURL_STRERROR 0
#endif
+#ifdef CURLGSSAPI_DELEGATION_FLAG
+#define HAVE_CURL_GSSAPI_DELEGATION 1
+#else
+#define HAVE_CURL_GSSAPI_DELEGATION 0
+#endif
+
#undef CMAJOR
#undef CMINOR
diff --git a/lib/curl_transport/xmlrpc_curl_transport.c b/lib/curl_transport/xmlrpc_curl_transport.c
index c48b927..9fedcda 100644
--- a/lib/curl_transport/xmlrpc_curl_transport.c
+++ b/lib/curl_transport/xmlrpc_curl_transport.c
@@ -836,6 +836,11 @@ getXportParms(xmlrpc_env * const envP,
else
curlSetupP->proxyType = curlXportParmsP->proxy_type;
+ if (!curlXportParmsP || parmSize < XMLRPC_CXPSIZE(gssapi_delegation))
+ curlSetupP->gssapiDelegation = false;
+ else
+ curlSetupP->gssapiDelegation = !!curlXportParmsP->gssapi_delegation;
+
getTimeoutParm(envP, curlXportParmsP, parmSize, &curlSetupP->timeout);
}
diff --git a/src/cpp/curl.cpp b/src/cpp/curl.cpp
index 9f38ffb..24a84ff 100644
--- a/src/cpp/curl.cpp
+++ b/src/cpp/curl.cpp
@@ -157,6 +157,7 @@ struct clientXmlTransport_curl::constrOpt_impl {
unsigned int proxy_port;
std::string proxy_userpwd;
xmlrpc_httpproxytype proxy_type;
+ bool gssapi_delegation;
} value;
struct {
bool network_interface;
@@ -184,6 +185,7 @@ struct clientXmlTransport_curl::constrOpt_impl {
bool proxy_port;
bool proxy_userpwd;
bool proxy_type;
+ bool gssapi_delegation;
} present;
};
@@ -214,6 +216,7 @@ clientXmlTransport_curl::constrOpt_impl::constrOpt_impl() {
present.proxy_auth = false;
present.proxy_userpwd = false;
present.proxy_type = false;
+ present.gssapi_delegation = false;
}
@@ -251,6 +254,7 @@ DEFINE_OPTION_SETTER(proxy_port, unsigned int);
DEFINE_OPTION_SETTER(proxy_auth, unsigned int);
DEFINE_OPTION_SETTER(proxy_userpwd, string);
DEFINE_OPTION_SETTER(proxy_type, xmlrpc_httpproxytype);
+DEFINE_OPTION_SETTER(gssapi_delegation, bool);
#undef DEFINE_OPTION_SETTER
@@ -333,6 +337,8 @@ clientXmlTransport_curl::initialize(constrOpt const& optExt) {
opt.value.proxy_userpwd.c_str() : NULL;
transportParms.proxy_type = opt.present.proxy_type ?
opt.value.proxy_type : XMLRPC_HTTPPROXY_HTTP;
+ transportParms.gssapi_delegation = opt.present.gssapi_delegation ?
+ opt.value.gssapi_delegation : false;
this->c_transportOpsP = &xmlrpc_curl_transport_ops;
@@ -340,7 +346,7 @@ clientXmlTransport_curl::initialize(constrOpt const& optExt) {
xmlrpc_curl_transport_ops.create(
&env.env_c, 0, "", "",
- &transportParms, XMLRPC_CXPSIZE(proxy_userpwd),
+ &transportParms, XMLRPC_CXPSIZE(gssapi_delegation),
&this->c_transportP);
if (env.env_c.fault_occurred)
--
1.7.7.5