From: Scott Cantor Date: Fri, 15 Oct 2010 23:46:04 +0000 (+0000) Subject: Support for GSS-API contexts attached to requests. X-Git-Tag: 2.4RC1~19 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-sp.git;a=commitdiff_plain;h=239a201c1c65172cd0f32774a332a64de8721630 Support for GSS-API contexts attached to requests. --- diff --git a/apache/mod_apache.cpp b/apache/mod_apache.cpp index 13d817e..64d16a9 100644 --- a/apache/mod_apache.cpp +++ b/apache/mod_apache.cpp @@ -31,14 +31,16 @@ # define _CRT_SECURE_NO_DEPRECATE 1 #endif +#include #include #include -#include +#include #include #include #include #include #include + #include #include #include @@ -95,6 +97,9 @@ namespace { string g_unsetHeaderValue,g_spoofKey; bool g_checkSpoofing = true; bool g_catchAll = false; +#ifndef SHIB_APACHE_13 + char* g_szGSSContextKey = "mod_auth_gssapi:gss_ctx"; +#endif static const char* g_UserDataKey = "urn:mace:shibboleth:Apache:shib_check_user"; } @@ -294,10 +299,11 @@ extern "C" const char* shib_table_set(cmd_parms* parms, shib_dir_config* dc, con return nullptr; } -/********************************************************************************/ -// Apache ShibTarget subclass(es) here. class ShibTargetApache : public AbstractSPRequest +#if defined(HAVE_GSSAPI) && !defined(SHIB_APACHE_13) + , public GSSRequest +#endif { bool m_handler; mutable string m_body; @@ -574,6 +580,13 @@ public: } long returnDecline(void) { return DECLINED; } long returnOK(void) { return OK; } +#if defined(HAVE_GSSAPI) && !defined(SHIB_APACHE_13) + gss_ctx_id_t getGSSContext() const { + gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; + apr_pool_userdata_get((void**)&ctx, g_szGSSContextKey, m_req->pool); + return ctx; + } +#endif }; /********************************************************************************/ @@ -1536,6 +1549,8 @@ static command_rec shib_cmds[] = { RSRC_CONF, "Path to shibboleth2.xml config file"), AP_INIT_TAKE1("ShibCatalogs", (config_fn_t)ap_set_global_string_slot, &g_szSchemaDir, RSRC_CONF, "Paths of XML schema catalogs"), + AP_INIT_TAKE1("ShibGSSKey", (config_fn_t)ap_set_global_string_slot, &g_szGSSContextKey, + RSRC_CONF, "Name of user data key containing GSS context established by GSS module"), AP_INIT_TAKE1("ShibURLScheme", (config_fn_t)shib_set_server_string_slot, (void *) offsetof (shib_server_config, szScheme), diff --git a/shibsp/AbstractSPRequest.cpp b/shibsp/AbstractSPRequest.cpp index b6c5e80..6f9b005 100644 --- a/shibsp/AbstractSPRequest.cpp +++ b/shibsp/AbstractSPRequest.cpp @@ -50,6 +50,16 @@ void SPRequest::setAuthType(const char* authtype) { } +#ifdef HAVE_GSSAPI +GSSRequest::GSSRequest() +{ +} + +GSSRequest::~GSSRequest() +{ +} +#endif + AbstractSPRequest::AbstractSPRequest(const char* category) : m_sp(nullptr), m_mapper(nullptr), m_app(nullptr), m_sessionTried(false), m_session(nullptr), m_log(&Category::getInstance(category)), m_parser(nullptr) diff --git a/shibsp/GSSRequest.h b/shibsp/GSSRequest.h new file mode 100644 index 0000000..a58cc51 --- /dev/null +++ b/shibsp/GSSRequest.h @@ -0,0 +1,60 @@ +/* + * Copyright 2010 Internet2 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file shibsp/GSSRequest.h + * + * Interface to a GSS-authenticated request. + */ + +#if !defined(__shibsp_gssreq_h__) && defined(HAVE_GSSAPI) +#define __shibsp_gssreq_h__ + +#include +#include + +#ifdef HAVE_GSSGNU +# include +#elif defined HAVE_GSSMIT +# include +# include +#else +# include +#endif + +namespace shibsp { + + /** + * Interface to a GSS-authenticated request. + */ + class SHIBSP_API GSSRequest : public virtual xmltooling::GenericRequest + { + protected: + GSSRequest(); + public: + virtual ~GSSRequest(); + + /** + * Returns the GSS-API context established for this request, or + * GSS_C_NO_CONTEXT if none is available. + * + * @return a GSS-API context handle, or GSS_C_NO_CONTEXT + */ + virtual gss_ctx_id_t getGSSContext() const=0; + }; +}; + +#endif /* __shibsp_gssreq_h__ */ diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am index 55072f9..7681b5e 100644 --- a/shibsp/Makefile.am +++ b/shibsp/Makefile.am @@ -31,6 +31,7 @@ libshibspinclude_HEADERS = \ base.h \ exceptions.h \ paths.h \ + GSSRequest.h \ RequestMapper.h \ ServiceProvider.h \ SessionCache.h \ diff --git a/shibsp/handler/impl/RemotedHandler.cpp b/shibsp/handler/impl/RemotedHandler.cpp index e7ca6d7..a843751 100644 --- a/shibsp/handler/impl/RemotedHandler.cpp +++ b/shibsp/handler/impl/RemotedHandler.cpp @@ -21,14 +21,16 @@ */ #include "internal.h" -#include "Application.h" #include "exceptions.h" +#include "Application.h" +#include "GSSRequest.h" #include "ServiceProvider.h" #include "SPRequest.h" #include "handler/RemotedHandler.h" #include #include +#include #ifndef SHIBSP_LITE # include "util/CGIParser.h" @@ -46,16 +48,35 @@ using namespace std; #ifndef SHIBSP_LITE namespace shibsp { - class SHIBSP_DLLLOCAL RemotedRequest : public virtual HTTPRequest + class SHIBSP_DLLLOCAL RemotedRequest : +#ifdef HAVE_GSSAPI + public virtual GSSRequest, +#endif + public virtual HTTPRequest { DDF& m_input; mutable CGIParser* m_parser; mutable vector m_certs; +#ifdef HAVE_GSSAPI + mutable gss_ctx_id_t m_gss; +#endif public: - RemotedRequest(DDF& input) : m_input(input), m_parser(nullptr) {} + RemotedRequest(DDF& input) : m_input(input), m_parser(nullptr) +#ifdef HAVE_GSSAPI + , m_ctx(GSS_C_NO_CONTEXT) +#endif + { + } + virtual ~RemotedRequest() { for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup()); delete m_parser; +#ifdef HAVE_GSSAPI + if (m_ctx != GSS_C_NO_CONTEXT) { + OM_uint32 minor; + gss_delete_sec_context(&minor, &m_ctx, GSS_C_NO_BUFFER); + } +#endif } // GenericRequest @@ -93,6 +114,11 @@ namespace shibsp { const std::vector& getClientCertificates() const; +#ifdef HAVE_GSSAPI + // GSSRequest + gss_ctx_id_t getGSSContext() const; +#endif + // HTTPRequest const char* getMethod() const { return m_input["method"].string(); @@ -177,6 +203,34 @@ const std::vector& RemotedRequest::getClientCertificates() cons return m_certs; } +#ifdef HAVE_GSSAPI +gss_ctx_id_t RemotedRequest::getGSSContext() const +{ + if (m_ctx == GSS_C_NO_CONTEXT) { + const char* encoded = m_input["gss_context"]; + if (encoded) { + xsecsize_t x; + XMLByte* decoded=Base64::decode(reinterpret_cast(encoded), &x); + if (decoded) { + gss_buffer_desc importbuf; + importbuf.length = x; + importbuf.data = decoded; + OM_uint32 minor; + OM_uint32 major = gss_import_sec_context(&minor, &importbuf, &m_ctx); + if (major != GSS_S_COMPLETE) + m_ctx = GSS_C_NO_CONTEXT; +#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&decoded); +#else + XMLString::release((char**)&decoded); +#endif + } + } + } + return m_ctx; +} +#endif + long RemotedResponse::sendResponse(std::istream& in, long status) { string msg; @@ -289,6 +343,40 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector* headers #endif } +#ifdef HAVE_GSSAPI + const GSSRequest* gss = dynamic_cast(&request); + if (gss) { + gss_ctx_id_t ctx = gss->getGSSContext(); + if (ctx != GSS_C_NO_CONTEXT) { + OM_uint32 minor; + gss_buffer_desc contextbuf; + contextbuf.length = 0; + contextbuf.value = nullptr; + OM_uint32 major = gss_export_sec_context(&minor, &ctx, &contextbuf); + if (major == GSS_S_COMPLETE) { + xsecsize_t len=0; + XMLByte* out=Base64::encode(reinterpret_cast(contextbuf.value), contextbuf.length, &len); + if (out) { + string ctx; + ctx.append(reinterpret_cast(out), len); +#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&out); +#else + XMLString::release((char**)&out); +#endif + in.addmember("gss_context").string(ctx.c_str()); + } + else { + request.log(SPRequest::SPError, "error while base64-encoding GSS context"); + } + } + else { + request.log(SPRequest::SPError, "error while exporting GSS context"); + } + } + } +#endif + return in; } diff --git a/shibsp/shibsp-lite.vcxproj b/shibsp/shibsp-lite.vcxproj index 81a331c..ade8cb9 100644 --- a/shibsp/shibsp-lite.vcxproj +++ b/shibsp/shibsp-lite.vcxproj @@ -241,6 +241,7 @@ + diff --git a/shibsp/shibsp-lite.vcxproj.filters b/shibsp/shibsp-lite.vcxproj.filters index 2eff898..654a364 100644 --- a/shibsp/shibsp-lite.vcxproj.filters +++ b/shibsp/shibsp-lite.vcxproj.filters @@ -338,6 +338,9 @@ Header Files\binding + + Header Files + diff --git a/shibsp/shibsp.vcxproj b/shibsp/shibsp.vcxproj index cd56309..58cb9a6 100644 --- a/shibsp/shibsp.vcxproj +++ b/shibsp/shibsp.vcxproj @@ -279,6 +279,7 @@ + diff --git a/shibsp/shibsp.vcxproj.filters b/shibsp/shibsp.vcxproj.filters index f1da19e..a9d09ff 100644 --- a/shibsp/shibsp.vcxproj.filters +++ b/shibsp/shibsp.vcxproj.filters @@ -539,6 +539,9 @@ Header Files\binding + + Header Files +