Add application cross checking to session lookup.
authorScott Cantor <cantor.2@osu.edu>
Thu, 1 Jul 2004 17:13:19 +0000 (17:13 +0000)
committerScott Cantor <cantor.2@osu.edu>
Thu, 1 Jul 2004 17:13:19 +0000 (17:13 +0000)
shib-mysql-ccache/shib-mysql-ccache.cpp
shib-target/shib-ccache.cpp
shib-target/shib-target.h
shib-target/shibrpc-server.cpp

index 945005f..698f4f8 100644 (file)
@@ -101,7 +101,7 @@ public:
   virtual void thread_end() {}
 
   virtual string generateKey() const {return m_cache->generateKey();}
-  virtual ISessionCacheEntry* find(const char* key);
+  virtual ISessionCacheEntry* find(const char* key, const IApplication* application);
   virtual void insert(
         const char* key,
         const IApplication* application,
@@ -233,10 +233,10 @@ ShibMySQLCCache::~ShibMySQLCCache()
   mysql_server_end();
 }
 
-ISessionCacheEntry* ShibMySQLCCache::find(const char* key)
+ISessionCacheEntry* ShibMySQLCCache::find(const char* key, const IApplication* application)
 {
   saml::NDC ndc("mysql::find");
-  ISessionCacheEntry* res = m_cache->find(key);
+  ISessionCacheEntry* res = m_cache->find(key,application);
   if (!res) {
 
     log->debug("Looking in database...");
@@ -273,6 +273,11 @@ ISessionCacheEntry* ShibMySQLCCache::find(const char* key)
         mysql_free_result(rows);
         throw ShibTargetException(SHIBRPC_INTERNAL_ERROR,"unable to locate application for session, deleted?");
     }
+    else if (strcmp(row[0],application->getId())) {
+        log->crit("An application (%s) attempted to access another application's (%s) session!", application->getId(), row[0]);
+        mysql_free_result(rows);
+        return NULL;
+    }
 
     istringstream str(row[2]);
     SAMLAuthenticationStatement *s = NULL;
@@ -291,7 +296,7 @@ ISessionCacheEntry* ShibMySQLCCache::find(const char* key)
 
     // Free the results, and then re-run the 'find' query
     mysql_free_result(rows);
-    res = m_cache->find(key);
+    res = m_cache->find(key,application);
     if (!res)
       return NULL;
   }
index 39077f7..8ea7136 100644 (file)
@@ -138,6 +138,8 @@ public:
 
   void setCache(InternalCCache *cache) { m_cache = cache; }
   time_t lastAccess() const { return m_lastAccess; }
+  
+  bool checkApplication(const IApplication* application) { return (m_application_id==application->getId()); }
 
 private:
   bool responseValid(int slop);
@@ -173,7 +175,7 @@ public:
   void thread_end() {};
 
   string generateKey() const;
-  ISessionCacheEntry* find(const char* key);
+  ISessionCacheEntry* find(const char* key, const IApplication* application);
   void insert(
     const char* key, const IApplication* application, SAMLAuthenticationStatement* s, const char *client_addr, SAMLResponse* r=NULL
     );
@@ -291,13 +293,18 @@ InternalCCacheEntry* InternalCCache::findi(const char* key)
   return i->second;
 }
 
-ISessionCacheEntry* InternalCCache::find(const char* key)
+ISessionCacheEntry* InternalCCache::find(const char* key, const IApplication* application)
 {
   log->debug("Find: \"%s\"", key);
   ReadLock rwlock(lock);
 
   InternalCCacheEntry* entry = findi(key);
-  if (!entry) return NULL;
+  if (!entry)
+    return NULL;
+  else if (!entry->checkApplication(application)) {
+    log->crit("An application (%s) attempted to access another application's session!", application->getId());
+    return NULL;
+  }
 
   // Lock the "database record" for the caller -- they have to unlock the item.
   entry->lock();
index 61bed55..4e1e90a 100644 (file)
@@ -213,7 +213,7 @@ namespace shibtarget {
             const char* client_addr,
             saml::SAMLResponse* r=NULL
             )=0;
-        virtual ISessionCacheEntry* find(const char* key)=0;
+        virtual ISessionCacheEntry* find(const char* key, const IApplication* application)=0;
         virtual void remove(const char* key)=0;
         virtual ~ISessionCache() {}
     };
index 62bf00a..2e0f78e 100644 (file)
@@ -157,7 +157,16 @@ shibrpc_session_is_valid_1_svc(shibrpc_session_is_valid_args_1 *argp,
   // See if the cookie exists...
   IConfig* conf=ShibTargetConfig::getConfig().getINI();
   Locker locker(conf);
-  ISessionCacheEntry* entry = conf->getSessionCache()->find(argp->cookie.cookie);
+  log.debug ("application: %s", argp->application_id);
+  const IApplication* app=conf->getApplication(argp->application_id);
+  if (!app) {
+    // Something's horribly wrong.
+    log.error("couldn't find application for session");
+    set_rpc_status(&result->status, SHIBRPC_UNKNOWN_ERROR, "Unable to locate application for session, deleted?");
+    return TRUE;
+  }
+
+  ISessionCacheEntry* entry = conf->getSessionCache()->find(argp->cookie.cookie,app);
 
   // If not, leave now..
   if (!entry) {
@@ -168,14 +177,6 @@ shibrpc_session_is_valid_1_svc(shibrpc_session_is_valid_args_1 *argp,
 
   // TEST the session...
   try {
-
-    // Try and locate support metadata for errors we throw.
-    log.debug ("application: %s", argp->application_id);
-    const IApplication* app=conf->getApplication(argp->application_id);
-    if (!app)
-        // Something's horribly wrong. Flush the session.
-        throw ShibTargetException(SHIBRPC_NO_SESSION,"Unable to locate application for session, deleted?");
-
     Metadata m(app->getMetadataProviders());
     const IProvider* origin=m.lookup(entry->getStatement()->getSubject()->getNameIdentifier()->getNameQualifier());
 
@@ -473,25 +474,26 @@ shibrpc_get_assertions_1_svc(shibrpc_get_assertions_args_1 *argp,
   // Find this session
   IConfig* conf=ShibTargetConfig::getConfig().getINI();
   Locker locker(conf);
-  ISessionCacheEntry* entry = conf->getSessionCache()->find(argp->cookie.cookie);
-
-  // If it does not exist, leave now..
-  if (!entry) {
-    log.error ("No Session");
-    set_rpc_status(&result->status, SHIBRPC_NO_SESSION, "getattrs Internal error: no session");
-    return TRUE;
-  }
 
   // Try and locate support metadata for errors we throw.
   log.debug ("application: %s", argp->application_id);
   const IApplication* app=conf->getApplication(argp->application_id);
   if (!app) {
-      // Something's horribly wrong. Flush the session.
-      log.error ("couldn't find application for session");
-      set_rpc_status(&result->status, SHIBRPC_NO_SESSION, "Unable to locate application for session, deleted?");
+      // Something's horribly wrong.
+      log.error("couldn't find application for session");
+      set_rpc_status(&result->status, SHIBRPC_INTERNAL_ERROR, "Unable to locate application for session, deleted?");
       return TRUE;
   }
 
+  ISessionCacheEntry* entry = conf->getSessionCache()->find(argp->cookie.cookie,app);
+
+  // If it does not exist, leave now..
+  if (!entry) {
+    log.error ("No Session");
+    set_rpc_status(&result->status, SHIBRPC_NO_SESSION, "getattrs Internal error: no session");
+    return TRUE;
+  }
+
   Metadata m(app->getMetadataProviders());
   const IProvider* origin=m.lookup(entry->getStatement()->getSubject()->getNameIdentifier()->getNameQualifier());