using namespace log4cpp;
using namespace std;
+
+SAML_EXCEPTION_FACTORY(ResourceAccessException);
SAML_EXCEPTION_FACTORY(MetadataException);
SAML_EXCEPTION_FACTORY(CredentialException);
SAML_EXCEPTION_FACTORY(InvalidHandleException);
+SAML_EXCEPTION_FACTORY(InvalidSessionException);
namespace {
ShibConfig g_config;
bool ShibConfig::init()
{
+ REGISTER_EXCEPTION_FACTORY(ResourceAccessException);
REGISTER_EXCEPTION_FACTORY(MetadataException);
REGISTER_EXCEPTION_FACTORY(CredentialException);
REGISTER_EXCEPTION_FACTORY(InvalidHandleException);
+ REGISTER_EXCEPTION_FACTORY(InvalidSessionException);
// Set up OpenSSL locking.
for (int i=0; i<CRYPTO_num_locks(); i++)
code=ERR_get_error_line_data(&file,&line,&data,&flags);
}
}
+
+void shibboleth::annotateException(SAMLException& e, const IEntityDescriptor* entity, bool rethrow)
+{
+ if (entity) {
+ auto_ptr_char id(entity->getId());
+ e.addProperty("providerId",id.get());
+ Iterator<const IRoleDescriptor*> roles=entity->getRoleDescriptors();
+ while (roles.hasNext()) {
+ const IRoleDescriptor* role=roles.next();
+ if (role->isValid()) {
+ const char* temp=role->getErrorURL();
+ if (temp) {
+ e.addProperty("errorURL",temp);
+ break;
+ }
+ }
+ }
+
+ Iterator<const IContactPerson*> i=entity->getContactPersons();
+ while (i.hasNext()) {
+ const IContactPerson* c=i.next();
+ if ((c->getType()==IContactPerson::technical || c->getType()==IContactPerson::support)) {
+ const char* fname=c->getGivenName();
+ const char* lname=c->getSurName();
+ if (fname && lname) {
+ string contact=string(fname) + ' ' + lname;
+ e.addProperty("contactName",contact.c_str());
+ }
+ else if (fname)
+ e.addProperty("contactName",fname);
+ else if (lname)
+ e.addProperty("contactName",lname);
+ Iterator<string> emails=c->getEmailAddresses();
+ if (emails.hasNext())
+ e.addProperty("contactEmail",emails.next().c_str());
+ break;
+ }
+ }
+ }
+
+ if (rethrow)
+ throw e;
+}
+
+void shibboleth::annotateException(saml::SAMLException& e, const IRoleDescriptor* role, bool rethrow)
+{
+ if (role) {
+ auto_ptr_char id(role->getEntityDescriptor()->getId());
+ e.addProperty("providerId",id.get());
+ const char* temp=role->getErrorURL();
+ if (role->getErrorURL())
+ e.addProperty("errorURL",role->getErrorURL());
+
+ Iterator<const IContactPerson*> i=role->getContactPersons();
+ while (i.hasNext()) {
+ const IContactPerson* c=i.next();
+ if ((c->getType()==IContactPerson::technical || c->getType()==IContactPerson::support)) {
+ const char* fname=c->getGivenName();
+ const char* lname=c->getSurName();
+ if (fname && lname) {
+ string contact=string(fname) + ' ' + lname;
+ e.addProperty("contactName",contact.c_str());
+ }
+ else if (fname)
+ e.addProperty("contactName",fname);
+ else if (lname)
+ e.addProperty("contactName",lname);
+ Iterator<string> emails=c->getEmailAddresses();
+ if (emails.hasNext())
+ e.addProperty("contactEmail",emails.next().c_str());
+ break;
+ }
+ }
+ }
+
+ if (rethrow)
+ throw e;
+}
namespace shibboleth
{
- #define DECLARE_SHIB_EXCEPTION(name,base) \
- class SHIB_EXPORTS name : public saml::base \
- { \
- public: \
- name(const char* msg, const saml::params& p=saml::params(), const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
- : saml::base(msg,p,codes,detail) {RTTI(name);} \
- name(const char* msg, const saml::namedparams& p, const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
- : saml::base(msg,p,codes,detail) {RTTI(name);} \
- name(const std::string& msg, const saml::params& p=saml::params(), const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
- : saml::base(msg,p,codes,detail) {RTTI(name);} \
- name(const std::string& msg, const saml::namedparams& p, const saml::Iterator<saml::QName>& codes=EMPTY(saml::QName), DOMElement* detail=NULL) \
- : saml::base(msg,p,codes,detail) {RTTI(name);} \
- name(const saml::QName& code, const char* msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(const saml::QName& code, const char* msg, const saml::namedparams& p, DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(const saml::QName& code, const std::string& msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(const saml::QName& code, const std::string& msg, const saml::namedparams& p, DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(HRESULT code, const char* msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(HRESULT code, const char* msg, const saml::namedparams& p, DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(HRESULT code, const std::string& msg, const saml::params& p=saml::params(), DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(HRESULT code, const std::string& msg, const saml::namedparams& p, DOMElement* detail=NULL) \
- : saml::base(code,msg,p,detail) {RTTI(name);} \
- name(DOMElement* e) : saml::base(e) {RTTI(name);} \
- name(std::istream& in) : saml::base(in) {RTTI(name);} \
- virtual ~name() throw () {} \
- }
-
- DECLARE_SHIB_EXCEPTION(MetadataException,SAMLException);
- DECLARE_SHIB_EXCEPTION(CredentialException,SAMLException);
- DECLARE_SHIB_EXCEPTION(InvalidHandleException,RetryableProfileException);
+ DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,ResourceAccessException,SAMLException);
+ DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,MetadataException,SAMLException);
+ DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,CredentialException,SAMLException);
+ DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidHandleException,RetryableProfileException);
+ DECLARE_SAML_EXCEPTION(SHIB_EXPORTS,InvalidSessionException,RetryableProfileException);
// Metadata abstract interfaces, based on SAML 2.0
virtual void setVersion(int major, int minor);
virtual saml::SAMLBrowserProfile::BrowserProfileResponse receive(
- XMLCh** pIssuer,
const char* packet,
const XMLCh* recipient,
int supportedProfiles,
time_t m_filestamp;
RWLock* m_lock;
};
+
+ /* These helpers attach metadata-derived information as exception properties and then
+ * rethrow the object. The following properties are attached, when possible:
+ *
+ * providerId The unique ID of the entity
+ * errorURL The error support URL of the entity or role
+ * contactName A formatted support or technical contact name
+ * contactEmail A contact email address
+ */
+ SHIB_EXPORTS void annotateException(saml::SAMLException& e, const IEntityDescriptor* entity, bool rethrow=true);
+ SHIB_EXPORTS void annotateException(saml::SAMLException& e, const IRoleDescriptor* role, bool rethrow=true);
}
#endif