# define SHIBODBC_EXPORTS
#endif
-#include <shib/shib-threads.h>
#include <shib-target/shib-target.h>
+#include <shibsp/exceptions.h>
#include <log4cpp/Category.hh>
+#include <xmltooling/util/NDC.h>
+#include <ctime>
#include <algorithm>
#include <sstream>
#include <dmalloc.h>
#endif
-using namespace std;
-using namespace saml;
-using namespace shibboleth;
+using namespace shibsp;
using namespace shibtarget;
+using namespace opensaml::saml2md;
+using namespace saml;
+using namespace xmltooling;
using namespace log4cpp;
+using namespace std;
#define PLUGIN_VER_MAJOR 3
#define PLUGIN_VER_MINOR 0
#define COLSIZE_APPLICATION_ID 256
#define COLSIZE_ADDRESS 128
#define COLSIZE_PROVIDER_ID 256
-#define LONGDATA_BUFLEN 2048
+#define LONGDATA_BUFLEN 32768
/*
CREATE TABLE state (
SQLHDBC getHDBC();
- log4cpp::Category* log;
+ Category* log;
protected:
- //ThreadKey* m_mysql;
const DOMElement* m_root; // can only use this during initialization
string m_connstring;
ODBCBase::ODBCBase(const DOMElement* e) : m_root(e), m_bInitializedODBC(false)
{
#ifdef _DEBUG
- saml::NDC ndc("ODBCBase");
+ xmltooling::NDC ndc("ODBCBase");
#endif
log = &(Category::getInstance("shibtarget.ODBC"));
m_connstring=p_connstring;
}
else {
- auto_ptr_char arg(e->getFirstChild()->getNodeValue());
+ xmltooling::auto_ptr_char arg(e->getFirstChild()->getNodeValue());
m_connstring=arg.get();
p_connstring=m_connstring.c_str();
}
SQLHDBC ODBCBase::getHDBC()
{
#ifdef _DEBUG
- saml::NDC ndc("getMYSQL");
+ xmltooling::NDC ndc("getMYSQL");
#endif
// Get a handle.
// Delegate all the ISessionCache methods.
string insert(
const IApplication* application,
- const IEntityDescriptor* source,
+ const RoleDescriptor* role,
const char* client_addr,
const SAMLSubject* subject,
const char* authnContext,
const SAMLResponse* tokens
)
- { return m_cache->insert(application,source,client_addr,subject,authnContext,tokens); }
+ { return m_cache->insert(application,role,client_addr,subject,authnContext,tokens); }
ISessionCacheEntry* find(const char* key, const IApplication* application, const char* client_addr)
{ return m_cache->find(key,application,client_addr); }
void remove(const char* key, const IApplication* application, const char* client_addr)
private:
bool m_storeAttributes;
ISessionCache* m_cache;
- CondWait* shutdown_wait;
+ xmltooling::CondWait* shutdown_wait;
bool shutdown;
- Thread* cleanup_thread;
+ xmltooling::Thread* cleanup_thread;
static void* cleanup_fcn(void*); // XXX Assumed an ODBCCCache
};
ODBCCCache::ODBCCCache(const DOMElement* e) : ODBCBase(e), m_storeAttributes(false)
{
#ifdef _DEBUG
- saml::NDC ndc("ODBCCCache");
+ xmltooling::NDC ndc("ODBCCCache");
#endif
log = &(Category::getInstance("shibtarget.SessionCache.ODBC"));
delete m_cache;
}
+void appendXML(ostream& os, const char* str)
+{
+ const char* pos=strchr(str,'\'');
+ while (pos) {
+ os.write(str,pos-str);
+ os << "''";
+ str=pos+1;
+ pos=strchr(str,'\'');
+ }
+ os << str;
+}
+
HRESULT ODBCCCache::onCreate(
const char* key,
const IApplication* application,
)
{
#ifdef _DEBUG
- saml::NDC ndc("onCreate");
+ xmltooling::NDC ndc("onCreate");
#endif
// Get XML data from entry. Default is not to return SAML objects.
ostringstream q;
q << "INSERT state VALUES ('" << key << "','" << application->getId() << "'," << timebuf << "," << timebuf
<< ",'" << entry->getClientAddress() << "'," << majorVersion << "," << minorVersion << ",'" << entry->getProviderId()
- << "',?,?,?)";
-
+ << "','";
+ appendXML(q,subject.first);
+ q << "','";
+ appendXML(q,context);
+ q << "',";
+ if (m_storeAttributes && tokens.first) {
+ q << "'";
+ appendXML(q,tokens.first);
+ q << "')";
+ }
+ else
+ q << "null)";
if (log->isDebugEnabled())
log->debug("SQL insert: %s", q.str().c_str());
ODBCConn conn(getHDBC());
SQLAllocHandle(SQL_HANDLE_STMT,conn,&hstmt);
- // Bind text parameters to statement.
- SQLINTEGER cbSubject=SQL_LEN_DATA_AT_EXEC(0),cbContext=SQL_LEN_DATA_AT_EXEC(0),cbTokens;
- if (!m_storeAttributes || !tokens.first)
- cbTokens=SQL_NULL_DATA;
- else
- cbTokens=SQL_LEN_DATA_AT_EXEC(0);
- SQLRETURN sr=SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_LONGVARCHAR,LONGDATA_BUFLEN,0,(SQLPOINTER)subject.first,0,&cbSubject);
- if (!SQL_SUCCEEDED(sr))
- log_error(hstmt, SQL_HANDLE_STMT);
- sr=SQLBindParameter(hstmt,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_LONGVARCHAR,LONGDATA_BUFLEN,0,(SQLPOINTER)context,0,&cbContext);
- if (!SQL_SUCCEEDED(sr))
- log_error(hstmt, SQL_HANDLE_STMT);
- sr=SQLBindParameter(hstmt,3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_LONGVARCHAR,LONGDATA_BUFLEN,0,(SQLPOINTER)tokens.first,0,&cbTokens);
- if (!SQL_SUCCEEDED(sr))
- log_error(hstmt, SQL_HANDLE_STMT);
-
// Execute statement.
- sr=SQLExecDirect(hstmt, (SQLCHAR*)q.str().c_str(), SQL_NTS);
- if (sr==SQL_NEED_DATA) {
- // Loop to send text data into driver.
- // pData is set each round by the driver to the pointers we bound above.
- char* pData;
- sr=SQLParamData(hstmt,(SQLPOINTER*)&pData);
- while (sr==SQL_NEED_DATA) {
- size_t len=strlen(pData);
- while (len>0) {
- size_t amt = std::min<size_t>(LONGDATA_BUFLEN,len);
- SQLPutData(hstmt, pData, amt);
- pData += amt;
- len = len - amt;
- }
- sr=SQLParamData(hstmt,(SQLPOINTER*)&pData);
- }
- }
-
HRESULT hr=NOERROR;
+ SQLRETURN sr=SQLExecDirect(hstmt, (SQLCHAR*)q.str().c_str(), SQL_NTS);
if (!SQL_SUCCEEDED(sr)) {
log->error("failed to insert record into database");
log_error(hstmt, SQL_HANDLE_STMT);
)
{
#ifdef _DEBUG
- saml::NDC ndc("onRead");
+ xmltooling::NDC ndc("onRead");
#endif
log->debug("searching database...");
HRESULT ODBCCCache::onRead(const char* key, time_t& accessed)
{
#ifdef _DEBUG
- saml::NDC ndc("onRead");
+ xmltooling::NDC ndc("onRead");
#endif
log->debug("reading last access time from database");
HRESULT ODBCCCache::onRead(const char* key, string& tokens)
{
#ifdef _DEBUG
- saml::NDC ndc("onRead");
+ xmltooling::NDC ndc("onRead");
#endif
if (!m_storeAttributes)
HRESULT ODBCCCache::onUpdate(const char* key, const char* tokens, time_t lastAccess)
{
#ifdef _DEBUG
- saml::NDC ndc("onUpdate");
+ xmltooling::NDC ndc("onUpdate");
#endif
- SQLRETURN sr;
- SQLHSTMT hstmt;
- ODBCConn conn(getHDBC());
+ ostringstream q;
if (lastAccess>0) {
#ifndef HAVE_GMTIME_R
char timebuf[32];
strftime(timebuf,32,"{ts '%Y-%m-%d %H:%M:%S'}",ptime);
- ostringstream q;
q << "UPDATE state SET atime=" << timebuf << " WHERE cookie='" << key << "'";
-
- SQLAllocHandle(SQL_HANDLE_STMT,conn,&hstmt);
- sr=SQLExecDirect(hstmt, (SQLCHAR*)q.str().c_str(), SQL_NTS);
}
else if (tokens) {
if (!m_storeAttributes)
return S_FALSE;
- string q = string("UPDATE state SET tokens=? WHERE cookie='") + key + "'";
-
- SQLAllocHandle(SQL_HANDLE_STMT,conn,&hstmt);
-
- // Bind text parameters to statement.
- SQLINTEGER cbTokens = tokens ? SQL_LEN_DATA_AT_EXEC(0) : SQL_NULL_DATA;
- sr=SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_LONGVARCHAR,LONGDATA_BUFLEN,0,(SQLPOINTER)tokens,0,&cbTokens);
-
- // Execute statement.
- sr=SQLExecDirect(hstmt, (SQLCHAR*)q.c_str(), SQL_NTS);
- if (sr==SQL_NEED_DATA) {
- // Loop to send text data into driver.
- // pData is set each round by the driver to the pointers we bound above.
- char* pData;
- sr=SQLParamData(hstmt,(SQLPOINTER*)&pData);
- while (sr==SQL_NEED_DATA) {
- size_t len=strlen(pData);
- while (len>0) {
- size_t amt=std::min<size_t>(LONGDATA_BUFLEN,len);
- SQLPutData(hstmt, pData, amt);
- pData += amt;
- len = len - amt;
- }
- sr=SQLParamData(hstmt,(SQLPOINTER*)&pData);
- }
- }
+ q << "UPDATE state SET tokens=";
+ if (*tokens) {
+ q << "'";
+ appendXML(q,tokens);
+ q << "' ";
+ }
+ else
+ q << "null ";
+ q << "WHERE cookie='" << key << "'";
}
else {
log->warn("onUpdate called with nothing to do!");
return S_FALSE;
}
- HRESULT hr;
+ HRESULT hr=NOERROR;
+ SQLHSTMT hstmt;
+ ODBCConn conn(getHDBC());
+ SQLAllocHandle(SQL_HANDLE_STMT,conn,&hstmt);
+ SQLRETURN sr=SQLExecDirect(hstmt, (SQLCHAR*)q.str().c_str(), SQL_NTS);
if (sr==SQL_NO_DATA)
hr=S_FALSE;
else if (!SQL_SUCCEEDED(sr)) {
log_error(hstmt, SQL_HANDLE_STMT);
hr=E_FAIL;
}
- else
- hr=NOERROR;
SQLFreeHandle(SQL_HANDLE_STMT,hstmt);
return hr;
HRESULT ODBCCCache::onDelete(const char* key)
{
#ifdef _DEBUG
- saml::NDC ndc("onDelete");
+ xmltooling::NDC ndc("onDelete");
#endif
SQLHSTMT hstmt;
string q = string("DELETE FROM state WHERE cookie='") + key + "'";
SQLRETURN sr=SQLExecDirect(hstmt, (SQLCHAR*)q.c_str(), SQL_NTS);
- HRESULT hr;
+ HRESULT hr=NOERROR;
if (sr==SQL_NO_DATA)
hr=S_FALSE;
else if (!SQL_SUCCEEDED(sr)) {
log_error(hstmt, SQL_HANDLE_STMT);
hr=E_FAIL;
}
- else
- hr=NOERROR;
SQLFreeHandle(SQL_HANDLE_STMT,hstmt);
return hr;
void ODBCCCache::cleanup()
{
#ifdef _DEBUG
- saml::NDC ndc("cleanup");
+ xmltooling::NDC ndc("cleanup");
#endif
- Mutex* mutex = Mutex::create();
+ Mutex* mutex = xmltooling::Mutex::create();
int rerun_timer = 0;
int timeout_life = 0;
mutex->unlock();
delete mutex;
- Thread::exit(NULL);
+ xmltooling::Thread::exit(NULL);
}
void* ODBCCCache::cleanup_fcn(void* cache_p)
{
ODBCCCache* cache = (ODBCCCache*)cache_p;
+#ifndef WIN32
// First, let's block all signals
Thread::mask_all_signals();
+#endif
// Now run the cleanup process.
cache->cleanup();
ODBCReplayCache(const DOMElement* e);
virtual ~ODBCReplayCache() {}
- bool check(const XMLCh* str, time_t expires) {auto_ptr_XMLCh temp(str); return check(temp.get(),expires);}
+ bool check(const XMLCh* str, time_t expires) {xmltooling::auto_ptr_XMLCh temp(str); return check(temp.get(),expires);}
bool check(const char* str, time_t expires);
};