From 16d1350e1f1e215d998a2af4d301a345edc3af29 Mon Sep 17 00:00:00 2001 From: scantor Date: Tue, 3 Apr 2012 21:37:50 +0000 Subject: [PATCH] Add name-based API to GSSRequest git-svn-id: https://svn.shibboleth.net/cpp-sp/branches/REL_2@3609 cb58f699-b61c-0410-a6fe-9272a202ed29 --- apache/mod_shib.cpp | 34 ++++++++-- shibsp/AbstractSPRequest.cpp | 5 ++ shibsp/GSSRequest.h | 8 +++ shibsp/handler/impl/RemotedHandler.cpp | 109 ++++++++++++++++++++++++++++----- 4 files changed, 136 insertions(+), 20 deletions(-) diff --git a/apache/mod_shib.cpp b/apache/mod_shib.cpp index 1da37e2..422673c 100644 --- a/apache/mod_shib.cpp +++ b/apache/mod_shib.cpp @@ -19,7 +19,7 @@ */ /** - * mod_apache.cpp + * mod_shib.cpp * * Apache module implementation. */ @@ -324,6 +324,9 @@ class ShibTargetApache : public AbstractSPRequest mutable bool m_gotBody,m_firsttime; mutable vector m_certs; set m_allhttp; +#if defined(SHIBSP_HAVE_GSSAPI) && !defined(SHIB_APACHE_13) + mutable gss_name_t m_gssname; +#endif public: bool m_handler; @@ -333,9 +336,20 @@ public: shib_request_config* m_rc; ShibTargetApache(request_rec* req) : AbstractSPRequest(SHIBSP_LOGCAT".Apache"), - m_gotBody(false),m_firsttime(true), m_handler(false), m_req(req), m_dc(nullptr), m_sc(nullptr), m_rc(nullptr) { + m_gotBody(false),m_firsttime(true), +#if defined(SHIBSP_HAVE_GSSAPI) && !defined(SHIB_APACHE_13) + m_gssname(GSS_C_NO_NAME), +#endif + m_handler(false), m_req(req), m_dc(nullptr), m_sc(nullptr), m_rc(nullptr) { + } + virtual ~ShibTargetApache() { +#if defined(SHIBSP_HAVE_GSSAPI) && !defined(SHIB_APACHE_13) + if (m_gssname != GSS_C_NO_NAME) { + OM_uint32 minor; + gss_release_name(&minor, &m_gssname); + } +#endif } - virtual ~ShibTargetApache() {} bool isInitialized() const { return (m_sc != nullptr); @@ -634,7 +648,19 @@ public: apr_pool_userdata_get((void**)&ctx, g_szGSSContextKey, m_req->pool); return ctx; } -#endif + gss_name_t getGSSName() const { + if (m_gssname == GSS_C_NO_NAME) { + gss_ctx_id_t ctx = getGSSContext(); + if (ctx != GSS_C_NO_CONTEXT) { + OM_uint32 minor; + OM_uint32 major = gss_inquire_context(&minor, ctx, &m_gssname, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + if (major != GSS_S_COMPLETE) + m_gssname = GSS_C_NO_NAME; + } + } + return m_gssname; + } + #endif }; /********************************************************************************/ diff --git a/shibsp/AbstractSPRequest.cpp b/shibsp/AbstractSPRequest.cpp index e0ccdcc..fe0de14 100644 --- a/shibsp/AbstractSPRequest.cpp +++ b/shibsp/AbstractSPRequest.cpp @@ -65,6 +65,11 @@ GSSRequest::GSSRequest() GSSRequest::~GSSRequest() { } + +gss_name_t GSSRequest::getGSSName() const +{ + return GSS_C_NO_NAME; +} #endif AbstractSPRequest::AbstractSPRequest(const char* category) diff --git a/shibsp/GSSRequest.h b/shibsp/GSSRequest.h index a140f0b..a703e58 100644 --- a/shibsp/GSSRequest.h +++ b/shibsp/GSSRequest.h @@ -58,6 +58,14 @@ namespace shibsp { * @return a GSS-API context handle, or GSS_C_NO_CONTEXT */ virtual gss_ctx_id_t getGSSContext() const=0; + + /** + * Returns the GSS-API initiator name established for this request, or + * GSS_C_NO_NAME if none is available. + * + * @return a GSS-API name, or GSS_C_NO_NAME + */ + virtual gss_name_t getGSSName() const; }; }; diff --git a/shibsp/handler/impl/RemotedHandler.cpp b/shibsp/handler/impl/RemotedHandler.cpp index fe5ce22..d92a4c1 100644 --- a/shibsp/handler/impl/RemotedHandler.cpp +++ b/shibsp/handler/impl/RemotedHandler.cpp @@ -45,6 +45,12 @@ # include #endif +#ifdef HAVE_GSSAPI_NAMINGEXTS +# ifdef SHIBSP_HAVE_GSSMIT +# include +# endif +#endif + using namespace shibsp; using namespace opensaml; using namespace xmltooling; @@ -64,12 +70,13 @@ namespace shibsp { mutable scoped_ptr m_parser; mutable vector m_certs; #ifdef SHIBSP_HAVE_GSSAPI - mutable gss_ctx_id_t m_gss; + mutable gss_ctx_id_t m_gssctx; + mutable gss_name_t m_gssname; #endif public: RemotedRequest(DDF& input) : m_input(input), m_parser(nullptr) #ifdef SHIBSP_HAVE_GSSAPI - , m_gss(GSS_C_NO_CONTEXT) + , m_gssctx(GSS_C_NO_CONTEXT), m_gssname(GSS_C_NO_NAME) #endif { } @@ -77,10 +84,11 @@ namespace shibsp { virtual ~RemotedRequest() { for_each(m_certs.begin(), m_certs.end(), xmltooling::cleanup()); #ifdef SHIBSP_HAVE_GSSAPI - if (m_gss != GSS_C_NO_CONTEXT) { - OM_uint32 minor; - gss_delete_sec_context(&minor, &m_gss, GSS_C_NO_BUFFER); - } + OM_uint32 minor; + if (m_gssctx != GSS_C_NO_CONTEXT) + gss_delete_sec_context(&minor, &m_gssctx, GSS_C_NO_BUFFER); + if (m_gssname != GSS_C_NO_NAME) + gss_release_name(&minor, &m_gssname); #endif } @@ -125,6 +133,7 @@ namespace shibsp { #ifdef SHIBSP_HAVE_GSSAPI // GSSRequest gss_ctx_id_t getGSSContext() const; + gss_name_t getGSSName() const; #endif // HTTPRequest @@ -215,19 +224,19 @@ const std::vector& RemotedRequest::getClientCertificates() cons #ifdef SHIBSP_HAVE_GSSAPI gss_ctx_id_t RemotedRequest::getGSSContext() const { - if (m_gss == GSS_C_NO_CONTEXT) { + if (m_gssctx == GSS_C_NO_CONTEXT) { const char* encoded = m_input["gss_context"].string(); if (encoded) { xsecsize_t x; - XMLByte* decoded=Base64::decode(reinterpret_cast(encoded), &x); + XMLByte* decoded = Base64::decode(reinterpret_cast(encoded), &x); if (decoded) { gss_buffer_desc importbuf; importbuf.length = x; importbuf.value = decoded; OM_uint32 minor; - OM_uint32 major = gss_import_sec_context(&minor, &importbuf, &m_gss); + OM_uint32 major = gss_import_sec_context(&minor, &importbuf, &m_gssctx); if (major != GSS_S_COMPLETE) - m_gss = GSS_C_NO_CONTEXT; + m_gssctx = GSS_C_NO_CONTEXT; #ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE XMLString::release(&decoded); #else @@ -236,7 +245,45 @@ gss_ctx_id_t RemotedRequest::getGSSContext() const } } } - return m_gss; + return m_gssctx; +} + +gss_name_t RemotedRequest::getGSSName() const +{ + if (m_gssname == GSS_C_NO_NAME) { + const char* encoded = m_input["gss_name"].string(); + if (encoded) { + xsecsize_t x; + XMLByte* decoded = Base64::decode(reinterpret_cast(encoded), &x); + gss_buffer_desc importbuf; + importbuf.length = x; + importbuf.value = decoded; + OM_uint32 major,minor; +#ifdef HAVE_GSSAPI_COMPOSITE_NAME + major = gss_import_name(&minor, &importbuf, GSS_C_NT_EXPORT_NAME_COMPOSITE, &m_gssname); +#else + major = gss_import_name(&minor, &importbuf, GSS_C_NT_EXPORT_NAME, &m_gssname); +#endif + if (major != GSS_S_COMPLETE) + m_gssname = GSS_C_NO_NAME; +#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&decoded); +#else + XMLString::release((char**)&decoded); +#endif + } + + if (m_gssname == GSS_C_NO_NAME) { + gss_ctx_id_t ctx = getGSSContext(); + if (ctx != GSS_C_NO_CONTEXT) { + OM_uint32 minor; + OM_uint32 major = gss_inquire_context(&minor, ctx, &m_gssname, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + if (major != GSS_S_COMPLETE) + m_gssname = GSS_C_NO_NAME; + } + } + } + return m_gssname; } #endif @@ -372,13 +419,12 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector* headers 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; + gss_buffer_desc contextbuf = GSS_C_EMPTY_BUFFER; 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); + xsecsize_t len = 0; + XMLByte* out = Base64::encode(reinterpret_cast(contextbuf.value), contextbuf.length, &len); + gss_release_buffer(&minor, &contextbuf); if (out) { string ctx; ctx.append(reinterpret_cast(out), len); @@ -397,6 +443,37 @@ DDF RemotedHandler::wrap(const SPRequest& request, const vector* headers request.log(SPRequest::SPError, "error while exporting GSS context"); } } +#ifdef HAVE_GSSAPI_NAMINGEXTS + else { + gss_name_t name = gss->getGSSName(); + if (name != GSS_C_NO_NAME) { + OM_uint32 minor; + gss_buffer_desc namebuf = GSS_C_EMPTY_BUFFER; + OM_uint32 major = gss_export_name_composite(&minor, name, &namebuf); + if (major == GSS_S_COMPLETE) { + xsecsize_t len = 0; + XMLByte* out = Base64::encode(reinterpret_cast(namebuf.value), namebuf.length, &len); + gss_release_buffer(&minor, &namebuf); + if (out) { + string nm; + nm.append(reinterpret_cast(out), len); +#ifdef SHIBSP_XERCESC_HAS_XMLBYTE_RELEASE + XMLString::release(&out); +#else + XMLString::release((char**)&out); +#endif + in.addmember("gss_name").string(nm.c_str()); + } + else { + request.log(SPRequest::SPError, "error while base64-encoding GSS name"); + } + } + else { + request.log(SPRequest::SPError, "error while exporting GSS name"); + } + } + } +#endif } #endif -- 2.1.4