CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_7_hltpatch2/src/CondCore/DBCommon/src/CredentialStore.cc

Go to the documentation of this file.
00001 #include "CondCore/DBCommon/interface/CredentialStore.h"
00002 #include "CondCore/DBCommon/interface/Cipher.h"
00003 #include "CondCore/DBCommon/interface/Exception.h"
00004 #include "CondCore/DBCommon/interface/Auth.h"
00005 #include "CondCore/ORA/interface/SequenceManager.h"
00006 //
00007 #include "CoralBase/AttributeList.h"
00008 #include "CoralBase/Attribute.h"
00009 #include "CoralBase/MessageStream.h"
00010 #include "CoralKernel/Context.h"
00011 #include "CoralCommon/URIParser.h"
00012 #include "RelationalAccess/AuthenticationCredentials.h"
00013 #include "RelationalAccess/IBulkOperation.h"
00014 #include "RelationalAccess/IConnection.h"
00015 #include "RelationalAccess/ISession.h"
00016 #include "RelationalAccess/IRelationalService.h"
00017 #include "RelationalAccess/IRelationalDomain.h"
00018 #include "RelationalAccess/ITransaction.h"
00019 #include "RelationalAccess/ISchema.h"
00020 #include "RelationalAccess/ITable.h"
00021 #include "RelationalAccess/TableDescription.h"
00022 #include "RelationalAccess/ITableDataEditor.h"
00023 #include "RelationalAccess/IQuery.h"
00024 #include "RelationalAccess/ICursor.h"
00025 //
00026 #include "RelationalAccess/AuthenticationCredentials.h"
00027 //
00028 #include <sstream>
00029 #include <fstream>
00030 #include <boost/filesystem.hpp>
00031 
00032 static const std::string serviceName = "CondAuthenticationService";
00033 
00034 coral_bridge::AuthenticationCredentialSet::AuthenticationCredentialSet() :
00035   m_data(){
00036 }
00037 
00038 coral_bridge::AuthenticationCredentialSet::~AuthenticationCredentialSet(){
00039   reset();
00040 }
00041 
00042 void coral_bridge::AuthenticationCredentialSet::reset(){
00043   for ( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::iterator iData = m_data.begin();
00044         iData != m_data.end(); ++iData )
00045     delete iData->second;
00046   m_data.clear();
00047 }
00048 
00049 void coral_bridge::AuthenticationCredentialSet::registerItem( const std::string& connectionString, 
00050                                                               const std::string& itemName,
00051                                                               const std::string& itemValue ){
00052   registerItem( connectionString, cond::Auth::COND_DEFAULT_ROLE, itemName, itemValue );
00053 }
00054                               
00055 
00056 void coral_bridge::AuthenticationCredentialSet::registerItem( const std::string& connectionString, 
00057                                                               const std::string& role,
00058                                                               const std::string& itemName,
00059                                                               const std::string& itemValue ){
00060   std::pair<std::string,std::string> connKey( connectionString, role );
00061   std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::iterator iData = m_data.find( connKey );
00062   if( iData == m_data.end() ){
00063     iData = m_data.insert( std::make_pair( connKey, new coral::AuthenticationCredentials( serviceName ) ) ).first;
00064   } 
00065   iData = m_data.insert( std::make_pair( connKey, new coral::AuthenticationCredentials( serviceName ) ) ).first;
00066   iData->second->registerItem( itemName, itemValue );
00067 }
00068 
00069 void
00070 coral_bridge::AuthenticationCredentialSet::registerCredentials( const std::string& connectionString,
00071                                                                 const std::string& userName,
00072                                                                 const std::string& password ){
00073   registerCredentials( connectionString, cond::Auth::COND_DEFAULT_ROLE, userName, password );
00074 }
00075 
00076 void
00077 coral_bridge::AuthenticationCredentialSet::registerCredentials( const std::string& connectionString,
00078                                                                 const std::string& role,
00079                                                                 const std::string& userName,
00080                                                                 const std::string& password ){
00081   std::pair<std::string,std::string> connKey( connectionString, role );
00082   std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::iterator iData = m_data.find( connKey );
00083   if( iData != m_data.end() ){
00084     delete iData->second;
00085     m_data.erase( connKey );
00086   } 
00087   iData = m_data.insert( std::make_pair( connKey, new coral::AuthenticationCredentials( serviceName ) ) ).first;
00088   iData->second->registerItem( coral::IAuthenticationCredentials::userItem(), userName );
00089   iData->second->registerItem( coral::IAuthenticationCredentials::passwordItem(), password );
00090 }
00091 
00092 void coral_bridge::AuthenticationCredentialSet::import( const AuthenticationCredentialSet& data ){
00093   for ( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iData = data.m_data.begin();
00094         iData != data.m_data.end(); ++iData ){
00095     registerCredentials( iData->first.first, iData->first.second, iData->second->valueForItem( coral::IAuthenticationCredentials::userItem() ),
00096                          iData->second->valueForItem( coral::IAuthenticationCredentials::passwordItem() ) );                                        
00097   }
00098 }
00099 
00100 const coral::IAuthenticationCredentials*
00101 coral_bridge::AuthenticationCredentialSet::get( const std::string& connectionString ) const
00102 {
00103   return get( connectionString, cond::Auth::COND_DEFAULT_ROLE );
00104 }
00105 
00106 const coral::IAuthenticationCredentials*
00107 coral_bridge::AuthenticationCredentialSet::get( const std::string& connectionString, const std::string& role ) const
00108 {
00109   const coral::IAuthenticationCredentials* ret = 0;
00110   std::pair<std::string,std::string> connKey( connectionString, role );
00111   std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iData = m_data.find( connKey );
00112   if ( iData != m_data.end() ){
00113     ret = iData->second;
00114   }
00115   return ret;
00116 }
00117 
00118 const std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >& coral_bridge::AuthenticationCredentialSet::data() const {
00119   return m_data;
00120 }
00121 
00122 static const std::string SEQUENCE_TABLE_NAME("COND_CREDENTIAL_SEQUENCE");
00123 
00124 static const std::string COND_AUTHENTICATION_TABLE("COND_AUTHENTICATION");
00125 static const std::string PRINCIPAL_ID_COL("P_ID");
00126 static const std::string PRINCIPAL_NAME_COL("P_NAME");
00127 static const std::string VERIFICATION_COL("CRED0");
00128 static const std::string PRINCIPAL_KEY_COL("CRED1");
00129 static const std::string ADMIN_KEY_COL("CRED2");
00130 
00131 static const std::string COND_AUTHORIZATION_TABLE("COND_AUTHORIZATION");
00132 static const std::string AUTH_ID_COL("AUTH_ID");
00133 static const std::string P_ID_COL("P_ID");
00134 static const std::string ROLE_COL("C_ROLE");
00135 static const std::string SCHEMA_COL("C_SCHEMA");
00136 static const std::string AUTH_KEY_COL("CRED3");
00137 static const std::string C_ID_COL("C_ID");
00138 
00139 static const std::string COND_CREDENTIAL_TABLE("COND_CREDENTIAL");
00140 static const std::string CONNECTION_ID_COL("CONN_ID");
00141 static const std::string CONNECTION_LABEL_COL("CONN_LABEL");
00142 static const std::string USERNAME_COL("CRED4");
00143 static const std::string PASSWORD_COL("CRED5");
00144 static const std::string VERIFICATION_KEY_COL("CRED6");
00145 static const std::string CONNECTION_KEY_COL("CRED7");
00146 
00147 const std::string DEFAULT_DATA_SOURCE("Cond_Default_Authentication");
00148 
00149 namespace cond {
00150 
00164   std::string schemaLabel( const std::string& serviceName, 
00165                            const std::string& userName ){
00166     std::string ret = userName;
00167     if( !serviceName.empty() ){
00168       ret += "@"+serviceName;
00169     }
00170     return ret;
00171   }
00172   std::string schemaLabelForCredentialStore( const std::string& connectionString ){
00173     coral::URIParser parser;
00174     parser.setURI( connectionString );
00175     std::string serviceName = parser.hostName();
00176     std::string schemaName = parser.databaseOrSchemaName();
00177     return schemaLabel( serviceName, schemaName );
00178   }
00179 
00180   class CSScopedSession {
00181   public: 
00182     CSScopedSession( CredentialStore& store ):
00183       m_store( store ){}
00184     ~CSScopedSession(){
00185       m_store.closeSession( false );
00186     }
00187     void startSuper( const std::string& connectionString, const std::string& userName, const std::string& password ){
00188       m_store.startSuperSession( connectionString, userName, password );
00189     }
00190     void start( bool readOnly=true ){
00191       m_store.startSession( readOnly );
00192     }
00193     void close(){
00194       m_store.closeSession();
00195     }
00196       
00197   private:
00198     CredentialStore& m_store;
00199   };
00200 
00201   struct PrincipalData {
00202     int id;
00203     std::string verifKey;
00204     std::string principalKey;
00205     std::string adminKey;
00206     PrincipalData():
00207       id(-1),
00208       verifKey(""),
00209       principalKey(""),
00210       adminKey(""){}
00211   };
00212 
00213   bool selectPrincipal( coral::ISchema& schema, const std::string& principal, PrincipalData& destination ){
00214     std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHENTICATION_TABLE).newQuery());
00215     coral::AttributeList readBuff;
00216     readBuff.extend<int>(PRINCIPAL_ID_COL);
00217     readBuff.extend<std::string>(VERIFICATION_COL);
00218     readBuff.extend<std::string>(PRINCIPAL_KEY_COL);
00219     readBuff.extend<std::string>(ADMIN_KEY_COL);
00220     coral::AttributeList whereData;
00221     whereData.extend<std::string>(PRINCIPAL_NAME_COL);
00222     whereData[ PRINCIPAL_NAME_COL ].data<std::string>() = principal;
00223     std::string whereClause = PRINCIPAL_NAME_COL + " = :" + PRINCIPAL_NAME_COL;
00224     query->defineOutput(readBuff);
00225     query->addToOutputList( PRINCIPAL_ID_COL );
00226     query->addToOutputList( VERIFICATION_COL );
00227     query->addToOutputList( PRINCIPAL_KEY_COL );
00228     query->addToOutputList( ADMIN_KEY_COL );
00229     query->setCondition( whereClause, whereData );
00230     coral::ICursor& cursor = query->execute();
00231     bool found = false;
00232     if ( cursor.next() ) {
00233       found = true;
00234       const coral::AttributeList& row = cursor.currentRow();
00235       destination.id = row[ PRINCIPAL_ID_COL ].data<int>();
00236       destination.verifKey = row[ VERIFICATION_COL ].data<std::string>();
00237       destination.principalKey = row[ PRINCIPAL_KEY_COL ].data<std::string>();
00238       destination.adminKey = row[ ADMIN_KEY_COL ].data<std::string>();
00239     }
00240     return found;
00241   }
00242 
00243   struct CredentialData {
00244     int id;
00245     std::string userName;
00246     std::string password;
00247     std::string connectionKey;
00248     std::string verificationKey;
00249     CredentialData():
00250       id(-1),
00251       userName(""),
00252       password(""),
00253       connectionKey(""){
00254     }
00255   };
00256 
00257   bool selectConnection( coral::ISchema& schema, const std::string& connectionLabel, CredentialData& destination ){
00258     
00259     std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_CREDENTIAL_TABLE).newQuery());
00260     coral::AttributeList readBuff;
00261     readBuff.extend<int>( CONNECTION_ID_COL );
00262     readBuff.extend<std::string>( USERNAME_COL );
00263     readBuff.extend<std::string>( PASSWORD_COL );
00264     readBuff.extend<std::string>( VERIFICATION_KEY_COL );
00265     readBuff.extend<std::string>( CONNECTION_KEY_COL );
00266     coral::AttributeList whereData;
00267     whereData.extend<std::string>( CONNECTION_LABEL_COL );
00268     whereData[ CONNECTION_LABEL_COL ].data<std::string>() = connectionLabel;
00269     std::string whereClause = CONNECTION_LABEL_COL + " = :" + CONNECTION_LABEL_COL;
00270     query->defineOutput(readBuff);
00271     query->addToOutputList( CONNECTION_ID_COL );
00272     query->addToOutputList( USERNAME_COL );
00273     query->addToOutputList( PASSWORD_COL );
00274     query->addToOutputList( VERIFICATION_KEY_COL );
00275     query->addToOutputList( CONNECTION_KEY_COL );
00276     query->setCondition( whereClause, whereData );
00277     coral::ICursor& cursor = query->execute();
00278     bool found = false;
00279     if ( cursor.next() ) {
00280       const coral::AttributeList& row = cursor.currentRow();
00281       destination.id = row[ CONNECTION_ID_COL].data<int>();
00282       destination.userName = row[ USERNAME_COL].data<std::string>();
00283       destination.password = row[ PASSWORD_COL].data<std::string>();
00284       destination.verificationKey = row[ VERIFICATION_KEY_COL].data<std::string>();
00285       destination.connectionKey = row[ CONNECTION_KEY_COL].data<std::string>();
00286       found = true;
00287     }
00288     return found;
00289   }
00290 
00291   struct AuthorizationData {
00292     int id;
00293     int connectionId;
00294     std::string key;
00295     AuthorizationData():
00296       id(-1),
00297       connectionId(-1),
00298       key(""){}
00299   };
00300 
00301   bool selectAuthorization( coral::ISchema& schema, int principalId, const std::string& role, const std::string& connectionString, AuthorizationData& destination ){
00302     std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHORIZATION_TABLE).newQuery());
00303     coral::AttributeList readBuff;
00304     readBuff.extend<int>(AUTH_ID_COL);
00305     readBuff.extend<int>(C_ID_COL);
00306     readBuff.extend<std::string>(AUTH_KEY_COL);
00307     coral::AttributeList whereData;
00308     whereData.extend<int>(P_ID_COL);
00309     whereData.extend<std::string>(ROLE_COL);
00310     whereData.extend<std::string>(SCHEMA_COL);
00311     whereData[ P_ID_COL ].data<int>() = principalId;
00312     whereData[ ROLE_COL ].data<std::string>() = role;
00313     whereData[ SCHEMA_COL ].data<std::string>() = connectionString;
00314     std::stringstream whereClause;
00315     whereClause << P_ID_COL << " = :"<<P_ID_COL;
00316     whereClause << " AND " << ROLE_COL << " = :"<<ROLE_COL;
00317     whereClause << " AND " << SCHEMA_COL << " = :"<<SCHEMA_COL;
00318     query->defineOutput(readBuff);
00319     query->addToOutputList( AUTH_ID_COL );
00320     query->addToOutputList( C_ID_COL );
00321     query->addToOutputList( AUTH_KEY_COL );
00322     query->setCondition( whereClause.str(), whereData );
00323     coral::ICursor& cursor = query->execute();
00324     bool found = false;
00325     if ( cursor.next() ) {
00326       const coral::AttributeList& row = cursor.currentRow();
00327       destination.id = row[AUTH_ID_COL].data<int>();  
00328       destination.connectionId = row[C_ID_COL].data<int>();
00329       destination.key = row[AUTH_KEY_COL].data<std::string>();
00330       found = true;
00331     }
00332     return found;
00333   }
00334 
00335 }
00336 
00337 void cond::CredentialStore::closeSession( bool commit ){
00338 
00339   if( m_session.get() ){
00340     if(m_session->transaction().isActive()){
00341       if( commit ){
00342         m_session->transaction().commit();
00343       } else {
00344         m_session->transaction().rollback();
00345       }
00346     }
00347     m_session->endUserSession();
00348   }
00349   m_session.reset();
00350   if( m_connection.get() ){
00351     m_connection->disconnect();
00352   }
00353   m_connection.reset();
00354 }
00355 
00356 int cond::CredentialStore::addUser( const std::string& principalName, const std::string& authenticationKey, const std::string& principalKey, const std::string& adminKey ){
00357 
00358   coral::ISchema& schema = m_session->nominalSchema();
00359   coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
00360 
00361   ora::SequenceManager sequenceMgr( SEQUENCE_TABLE_NAME,schema );
00362   int principalId = sequenceMgr.getNextId( COND_AUTHENTICATION_TABLE, true );
00363     
00364   Cipher cipher0( authenticationKey );
00365   Cipher cipher1( adminKey );
00366 
00367   coral::AttributeList authData;
00368   editor0.rowBuffer(authData);
00369   authData[ PRINCIPAL_ID_COL ].data<int>() = principalId;
00370   authData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
00371   authData[ VERIFICATION_COL ].data<std::string>() = cipher0.b64encrypt( principalName );
00372   authData[ PRINCIPAL_KEY_COL ].data<std::string>() = cipher0.b64encrypt( principalKey );
00373   authData[ ADMIN_KEY_COL ].data<std::string>() = cipher1.b64encrypt( principalKey );
00374   editor0.insertRow( authData );
00375   return principalId;
00376 }
00377 
00378 std::pair<std::string,std::string> cond::CredentialStore::openConnection( const std::string& connectionString ){
00379   coral::IHandle<coral::IRelationalService> relationalService = coral::Context::instance().query<coral::IRelationalService>();
00380   if ( ! relationalService.isValid() ){
00381     coral::Context::instance().loadComponent("CORAL/Services/RelationalService");
00382     relationalService = coral::Context::instance().query<coral::IRelationalService>();
00383   }
00384   coral::IRelationalDomain& domain = relationalService->domainForConnection( connectionString );
00385   std::pair<std::string,std::string> connTokens = domain.decodeUserConnectionString( connectionString );
00386   m_connection.reset( domain.newConnection( connTokens.first ) );
00387   m_connection->connect();
00388   return connTokens;
00389 }
00390 
00391 void cond::CredentialStore::openSession( const std::string& schemaName, const std::string& userName, const std::string& password, bool readMode ){
00392   coral::AccessMode accessMode = coral::ReadOnly;
00393   if( !readMode ) accessMode = coral::Update;  
00394   m_session.reset( m_connection->newSession( schemaName, accessMode) );
00395   m_session->startUserSession( userName, password );
00396   // open read-only transaction
00397   m_session->transaction().start( readMode );
00398 }
00399 
00400 void cond::CredentialStore::startSuperSession( const std::string& connectionString, const std::string& userName, const std::string& password ){
00401   std::pair<std::string,std::string> connTokens = openConnection( connectionString );
00402   openSession( connTokens.second, userName, password, false );
00403 }
00404 
00405 // open session on the storage
00406 void cond::CredentialStore::startSession( bool readMode ){
00407   if(!m_serviceData){
00408     throwException( "The credential store has not been initialized.","cond::CredentialStore::openConnection" );    
00409   }
00410   const std::string& storeConnectionString = m_serviceData->connectionString;
00411 
00412   std::pair<std::string,std::string> connTokens = openConnection( storeConnectionString );
00413 
00414   const std::string& userName = m_serviceData->userName;
00415   const std::string& password = m_serviceData->password;
00416  
00417   openSession( connTokens.second, userName, password, true );
00418 
00419   coral::ISchema& schema = m_session->nominalSchema();
00420   if(!schema.existsTable(COND_AUTHENTICATION_TABLE) ||
00421      !schema.existsTable(COND_AUTHORIZATION_TABLE) ||
00422      !schema.existsTable(COND_CREDENTIAL_TABLE) ){
00423     throwException("Credential database does not exists in \""+storeConnectionString+"\"","CredentialStore::startSession");
00424   }
00425 
00426   const std::string& principalName = m_key.principalName();
00427   // now authenticate...
00428   PrincipalData princData;
00429   if( !selectPrincipal( m_session->nominalSchema(), principalName, princData ) ){
00430     throwException( "Invalid credentials provided.(0)",
00431                     "CredentialStore::openSession");
00432   }
00433   Cipher cipher0( m_key.principalKey() );
00434   std::string verifStr = cipher0.b64decrypt( princData.verifKey );
00435   if( verifStr != principalName ){
00436     throwException( "Invalid credentials provided (1)",
00437                     "CredentialStore::openSession");
00438   }
00439   // ok, authenticated!
00440   m_principalId = princData.id;
00441   m_principalKey = cipher0.b64decrypt( princData.principalKey );
00442   
00443   if(!readMode ) {
00444 
00445     Cipher cipher0( m_principalKey );
00446     std::string adminKey = cipher0.b64decrypt( princData.adminKey );
00447     if( adminKey != m_principalKey ){
00448       // not admin user!
00449       throwException( "Provided credentials does not allow admin operation.",
00450                       "CredentialStore::openSession");
00451     }
00452     
00453     // first find the credentials for WRITING in the security tables
00454     std::auto_ptr<coral::IQuery> query(schema.newQuery());
00455     query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
00456     query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
00457     coral::AttributeList readBuff;
00458     readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
00459     readBuff.extend<std::string>("CREDS."+CONNECTION_KEY_COL);
00460     readBuff.extend<std::string>("CREDS."+USERNAME_COL);
00461     readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
00462     readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
00463     coral::AttributeList whereData;
00464     whereData.extend<int>(P_ID_COL);
00465     whereData.extend<std::string>(ROLE_COL);
00466     whereData.extend<std::string>(SCHEMA_COL);
00467     whereData[ P_ID_COL ].data<int>() = m_principalId;
00468     whereData[ ROLE_COL ].data<std::string>() = Auth::COND_ADMIN_ROLE;
00469     whereData[ SCHEMA_COL ].data<std::string>() = storeConnectionString;
00470     std::stringstream whereClause;
00471     whereClause << "AUTHO."<< C_ID_COL << " = CREDS."<<CONNECTION_ID_COL;
00472     whereClause << " AND AUTHO."<< P_ID_COL << " = :"<<P_ID_COL;
00473     whereClause << " AND AUTHO."<< ROLE_COL << " = :"<<ROLE_COL;
00474     whereClause << " AND AUTHO."<< SCHEMA_COL << " = :"<<SCHEMA_COL;
00475     query->defineOutput(readBuff);
00476     query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
00477     query->addToOutputList( "CREDS."+CONNECTION_KEY_COL );
00478     query->addToOutputList( "CREDS."+USERNAME_COL );
00479     query->addToOutputList( "CREDS."+PASSWORD_COL );
00480     query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
00481     query->setCondition( whereClause.str(), whereData );
00482     coral::ICursor& cursor = query->execute();
00483     bool found = false;
00484     std::string writeUserName("");
00485     std::string writePassword("");
00486     if ( cursor.next() ) {
00487       const coral::AttributeList& row = cursor.currentRow();
00488       const std::string& connLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
00489       const std::string& encryptedConnectionKey = row[ "CREDS."+CONNECTION_KEY_COL ].data<std::string>();
00490       std::string connectionKey = cipher0.b64decrypt( encryptedConnectionKey );
00491       Cipher cipher1( connectionKey );
00492       const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL ].data<std::string>();
00493       const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL ].data<std::string>();
00494       const std::string& verificationKey = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
00495       if( cipher1.b64decrypt( verificationKey ) != connLabel  ){
00496         throwException( "Could not decrypt credentials.Provided key is invalid.",
00497                         "CredentialStore::startSession");
00498       }
00499       writeUserName = cipher1.b64decrypt( encryptedUserName );
00500       writePassword = cipher1.b64decrypt( encryptedPassword );
00501       found = true;
00502     }
00503     if( ! found ){
00504       throwException( "Provided credentials are invalid for write access.",
00505                       "CredentialStore::openSession");
00506     }
00507     m_session->transaction().commit();
00508     m_session->endUserSession();
00509     openSession( connTokens.second, writeUserName, writePassword, false );
00510 
00511   }
00512 }   
00513 
00514 bool cond::CredentialStore::setPermission( int principalId, const std::string& principalKey, const std::string& role, const std::string& connectionString, int connectionId, const std::string& connectionKey ){
00515   coral::ISchema& schema = m_session->nominalSchema();
00516   Cipher cipher( principalKey );
00517   std::string encryptedConnectionKey = cipher.b64encrypt( connectionKey );
00518 
00519   AuthorizationData authData;
00520   bool found = selectAuthorization( schema, principalId, role, connectionString, authData );
00521 
00522   coral::ITableDataEditor& editor = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
00523   if( found ) {
00524     coral::AttributeList updateData;
00525     updateData.extend<int>( AUTH_ID_COL );
00526     updateData.extend<int>( C_ID_COL );
00527     updateData.extend<std::string>( AUTH_KEY_COL );
00528     updateData[ AUTH_ID_COL ].data<int>() = authData.id;
00529     updateData[ C_ID_COL ].data<int>() = connectionId;
00530     updateData[ AUTH_KEY_COL ].data<std::string>() = encryptedConnectionKey;
00531     std::string setCl = C_ID_COL+" = :"+C_ID_COL + ", "+AUTH_KEY_COL+" = :"+AUTH_KEY_COL;
00532     std::string whereCl = AUTH_ID_COL+" = :"+AUTH_ID_COL;
00533     editor.updateRows( setCl,whereCl, updateData );
00534   } else {
00535 
00536     ora::SequenceManager sequenceMgr( SEQUENCE_TABLE_NAME,schema );
00537     int next = sequenceMgr.getNextId( COND_AUTHORIZATION_TABLE, true );
00538     
00539     coral::AttributeList insertData;
00540     insertData.extend<int>( AUTH_ID_COL );
00541     insertData.extend<int>( P_ID_COL );
00542     insertData.extend<std::string>( ROLE_COL );
00543     insertData.extend<std::string>( SCHEMA_COL );
00544     insertData.extend<std::string>( AUTH_KEY_COL );
00545     insertData.extend<int>( C_ID_COL );
00546     insertData[ AUTH_ID_COL ].data<int>() = next;
00547     insertData[ P_ID_COL ].data<int>() = principalId;
00548     insertData[ ROLE_COL ].data<std::string>() = role;
00549     insertData[ SCHEMA_COL ].data<std::string>() = connectionString;
00550     insertData[ AUTH_KEY_COL ].data<std::string>() = encryptedConnectionKey;
00551     insertData[ C_ID_COL ].data<int>() = connectionId;
00552     editor.insertRow( insertData );
00553   }
00554   return true;    
00555 }
00556 
00557 std::pair<int,std::string> cond::CredentialStore::updateConnection( const std::string& connectionLabel, 
00558                                                                     const std::string& userName, 
00559                                                                     const std::string& password,
00560                                                                     bool forceUpdate ){
00561   coral::ISchema& schema = m_session->nominalSchema();
00562   CredentialData credsData;
00563   bool found = selectConnection( schema, connectionLabel, credsData );
00564   int connId = credsData.id;
00565   
00566   Cipher adminCipher( m_principalKey );
00567   std::string connectionKey("");
00568   coral::ITableDataEditor& editor = schema.tableHandle(COND_CREDENTIAL_TABLE).dataEditor();
00569   if( found ){
00570     
00571     connectionKey = adminCipher.b64decrypt( credsData.connectionKey );
00572     Cipher cipher( connectionKey );
00573     std::string verificationKey = cipher.b64decrypt( credsData.verificationKey );
00574     if( verificationKey != connectionLabel ){
00575       throwException("Decoding of connection key failed.","CredentialStore::updateConnection");
00576     }
00577     if( forceUpdate ){
00578       std::string encryptedUserName = cipher.b64encrypt( userName );
00579       std::string encryptedPassword = cipher.b64encrypt( password );
00580      
00581       coral::AttributeList updateData;
00582       updateData.extend<int>( CONNECTION_ID_COL );
00583       updateData.extend<std::string>( USERNAME_COL );
00584       updateData.extend<std::string>( PASSWORD_COL );
00585       updateData[ CONNECTION_ID_COL ].data<int>() = connId;
00586       updateData[ USERNAME_COL ].data<std::string>() = encryptedUserName;
00587       updateData[ PASSWORD_COL ].data<std::string>() = encryptedPassword;
00588       std::stringstream setCl;
00589       setCl << USERNAME_COL << " = :" << USERNAME_COL;
00590       setCl <<", " << PASSWORD_COL << " = :" << PASSWORD_COL;
00591       std::string whereCl = CONNECTION_ID_COL+" = :"+CONNECTION_ID_COL;
00592       editor.updateRows( setCl.str(),whereCl, updateData );
00593     }
00594   }
00595   
00596   if(!found){
00597     
00598     KeyGenerator gen;
00599     connectionKey = gen.make( Auth::COND_DB_KEY_SIZE );
00600     Cipher cipher( connectionKey );
00601     std::string encryptedUserName = cipher.b64encrypt( userName );
00602     std::string encryptedPassword = cipher.b64encrypt( password );
00603     std::string encryptedLabel = cipher.b64encrypt( connectionLabel );
00604     
00605     ora::SequenceManager sequenceMgr( SEQUENCE_TABLE_NAME,schema );
00606     connId = sequenceMgr.getNextId( COND_CREDENTIAL_TABLE, true );
00607     
00608     coral::AttributeList insertData;
00609     insertData.extend<int>( CONNECTION_ID_COL );
00610     insertData.extend<std::string>( CONNECTION_LABEL_COL );
00611     insertData.extend<std::string>( USERNAME_COL );
00612     insertData.extend<std::string>( PASSWORD_COL );
00613     insertData.extend<std::string>( VERIFICATION_KEY_COL );
00614     insertData.extend<std::string>( CONNECTION_KEY_COL );
00615     insertData[ CONNECTION_ID_COL ].data<int>() = connId;
00616     insertData[ CONNECTION_LABEL_COL ].data<std::string>() = connectionLabel;
00617     insertData[ USERNAME_COL ].data<std::string>() = encryptedUserName;
00618     insertData[ PASSWORD_COL ].data<std::string>() = encryptedPassword;
00619     insertData[ VERIFICATION_KEY_COL ].data<std::string>() = encryptedLabel;
00620     insertData[ CONNECTION_KEY_COL ].data<std::string>() = adminCipher.b64encrypt( connectionKey ) ;;
00621     editor.insertRow( insertData );
00622     
00623     /***
00624     // then set the admin permission on the new connection
00625     ora::SequenceManager sequenceMgr2( SEQUENCE_TABLE_NAME,schema );
00626     int authId = sequenceMgr2.getNextId( COND_AUTHORIZATION_TABLE, true );
00627     
00628     coral::ITableDataEditor& authEditor = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
00629     coral::AttributeList authData;
00630     authData.extend<int>( AUTH_ID_COL );
00631     authData.extend<int>( P_ID_COL );
00632     authData.extend<std::string>( ROLE_COL );
00633     authData.extend<std::string>( SCHEMA_COL );
00634     authData.extend<std::string>( AUTH_KEY_COL );
00635     authData.extend<int>( C_ID_COL );
00636     authData[ AUTH_ID_COL ].data<int>() = authId;
00637     authData[ P_ID_COL ].data<int>() = m_principalId;
00638     authData[ ROLE_COL ].data<std::string>() = Auth::COND_ADMIN_ROLE;
00639     authData[ SCHEMA_COL ].data<std::string>() = defaultConnectionString( m_serviceData->connectionString, m_serviceName, userName );
00640     authData[ AUTH_KEY_COL ].data<std::string>() = adminCipher.b64encrypt( connectionKey ) ;
00641     authData[ C_ID_COL ].data<int>() = connId;
00642     authEditor.insertRow( authData );
00643     **/
00644   }
00645   return std::make_pair( connId, connectionKey );
00646 }
00647 
00648 cond::CredentialStore::CredentialStore():
00649   m_connection(),
00650   m_session(),
00651   m_principalId(-1),
00652   m_principalKey(""),
00653   m_serviceName(""),
00654   m_serviceData(0),
00655   m_key(){
00656 }
00657 
00658 cond::CredentialStore::~CredentialStore(){
00659 }
00660 
00661 std::string
00662 cond::CredentialStore::setUpForService( const std::string& serviceName, 
00663                                         const std::string& authPath ){
00664   if( serviceName.empty() ){
00665     throwException( "Service name has not been provided.","cond::CredentialStore::setUpConnection" );        
00666   }
00667   m_serviceName.clear();
00668   m_serviceData = 0;
00669 
00670   if( authPath.empty() ){
00671     throwException( "The authentication Path has not been provided.","cond::CredentialStore::setUpForService" );
00672   }
00673   boost::filesystem::path fullPath( authPath );
00674   if(!boost::filesystem::exists(authPath) || !boost::filesystem::is_directory( authPath )){
00675     throwException( "Authentication Path is invalid.","cond::CredentialStore::setUpForService" );
00676   }
00677   boost::filesystem::path file( DecodingKey::FILE_PATH );
00678   fullPath /= file;
00679 
00680   m_key.init( fullPath.string(), Auth::COND_KEY ); 
00681   
00682   std::map< std::string, ServiceCredentials >::const_iterator iK = m_key.services().find( serviceName );
00683   if( iK == m_key.services().end() ){
00684     std::string msg("");
00685     msg += "Service \""+serviceName+"\" can't be open with the current key.";
00686     throwException( msg,"cond::CredentialStore::setUpConnection" );    
00687   }
00688   m_serviceName = serviceName;
00689   m_serviceData = &iK->second;
00690   return m_serviceData->connectionString;
00691 }
00692 
00693 std::string
00694 cond::CredentialStore::setUpForConnectionString( const std::string& connectionString,
00695                                                  const std::string& authPath ){
00696   coral::IHandle<coral::IRelationalService> relationalService = coral::Context::instance().query<coral::IRelationalService>();
00697   if ( ! relationalService.isValid() ){
00698     coral::Context::instance().loadComponent("CORAL/Services/RelationalService");
00699     relationalService = coral::Context::instance().query<coral::IRelationalService>();
00700   }
00701   coral::IRelationalDomain& domain = relationalService->domainForConnection( connectionString );
00702   std::pair<std::string,std::string> connTokens = domain.decodeUserConnectionString( connectionString );
00703   std::string& serviceName = connTokens.first;
00704   return setUpForService( serviceName, authPath );
00705 }
00706 
00707 
00708 bool
00709 cond::CredentialStore::createSchema( const std::string& connectionString, const std::string& userName, const std::string& password ) {
00710   CSScopedSession session( *this );
00711   session.startSuper( connectionString, userName, password );
00712 
00713   coral::ISchema& schema = m_session->nominalSchema();
00714   if(schema.existsTable(COND_AUTHENTICATION_TABLE)) {
00715     throwException("Credential database, already exists.","CredentialStore::create");
00716   }
00717   ora::SequenceManager sequenceMgr( SEQUENCE_TABLE_NAME, schema );
00718   int columnSize = 2000;
00719 
00720   // authentication table
00721   sequenceMgr.create( COND_AUTHENTICATION_TABLE );
00722   coral::TableDescription descr0;
00723   descr0.setName( COND_AUTHENTICATION_TABLE );
00724   descr0.insertColumn( PRINCIPAL_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
00725   descr0.insertColumn( PRINCIPAL_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00726   descr0.insertColumn( VERIFICATION_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00727   descr0.insertColumn( PRINCIPAL_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00728   descr0.insertColumn( ADMIN_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00729   descr0.setNotNullConstraint( PRINCIPAL_ID_COL );
00730   descr0.setNotNullConstraint( PRINCIPAL_NAME_COL );
00731   descr0.setNotNullConstraint( VERIFICATION_COL );
00732   descr0.setNotNullConstraint( PRINCIPAL_KEY_COL );
00733   descr0.setNotNullConstraint( ADMIN_KEY_COL );
00734   std::vector<std::string> columnsUnique;
00735   columnsUnique.push_back( PRINCIPAL_NAME_COL);
00736   descr0.setUniqueConstraint( columnsUnique );
00737   std::vector<std::string> columnsForIndex;
00738   columnsForIndex.push_back(PRINCIPAL_ID_COL);
00739   descr0.setPrimaryKey( columnsForIndex );
00740   schema.createTable( descr0 );
00741 
00742   // authorization table
00743   sequenceMgr.create( COND_AUTHORIZATION_TABLE );
00744   coral::TableDescription descr1;
00745   descr1.setName( COND_AUTHORIZATION_TABLE );
00746   descr1.insertColumn( AUTH_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
00747   descr1.insertColumn( P_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
00748   descr1.insertColumn( ROLE_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00749   descr1.insertColumn( SCHEMA_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00750   descr1.insertColumn( AUTH_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00751   descr1.insertColumn( C_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
00752   descr1.setNotNullConstraint( AUTH_ID_COL );
00753   descr1.setNotNullConstraint( P_ID_COL );
00754   descr1.setNotNullConstraint( ROLE_COL );
00755   descr1.setNotNullConstraint( SCHEMA_COL );
00756   descr1.setNotNullConstraint( AUTH_KEY_COL );
00757   descr1.setNotNullConstraint( C_ID_COL );
00758   columnsUnique.clear();
00759   columnsUnique.push_back( P_ID_COL);
00760   columnsUnique.push_back( ROLE_COL);
00761   columnsUnique.push_back( SCHEMA_COL);
00762   descr1.setUniqueConstraint( columnsUnique );
00763   columnsForIndex.clear();
00764   columnsForIndex.push_back(AUTH_ID_COL);
00765   descr1.setPrimaryKey( columnsForIndex );
00766   schema.createTable( descr1 );
00767 
00768   // credential table
00769   sequenceMgr.create( COND_CREDENTIAL_TABLE );
00770   coral::TableDescription descr2;
00771   descr2.setName( COND_CREDENTIAL_TABLE );
00772   descr2.insertColumn( CONNECTION_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
00773   descr2.insertColumn( CONNECTION_LABEL_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00774   descr2.insertColumn( USERNAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00775   descr2.insertColumn( PASSWORD_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00776   descr2.insertColumn( VERIFICATION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00777   descr2.insertColumn( CONNECTION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
00778   descr2.setNotNullConstraint( CONNECTION_ID_COL );
00779   descr2.setNotNullConstraint( CONNECTION_LABEL_COL );
00780   descr2.setNotNullConstraint( USERNAME_COL );
00781   descr2.setNotNullConstraint( PASSWORD_COL );
00782   descr2.setNotNullConstraint( VERIFICATION_KEY_COL );
00783   descr2.setNotNullConstraint( CONNECTION_KEY_COL );
00784   columnsUnique.clear();
00785   columnsUnique.push_back( CONNECTION_LABEL_COL);
00786   descr2.setUniqueConstraint( columnsUnique );
00787   columnsForIndex.clear();
00788   columnsForIndex.push_back(CONNECTION_ID_COL);
00789   descr2.setPrimaryKey( columnsForIndex );
00790   schema.createTable( descr2 );
00791 
00792   session.close();
00793   return true;
00794 }
00795 
00796 bool
00797 cond::CredentialStore::drop( const std::string& connectionString, const std::string& userName, const std::string& password ) {
00798   CSScopedSession session( *this );
00799   session.startSuper( connectionString, userName, password );
00800 
00801   coral::ISchema& schema = m_session->nominalSchema();
00802   schema.dropIfExistsTable( COND_AUTHORIZATION_TABLE );
00803   schema.dropIfExistsTable( COND_CREDENTIAL_TABLE );
00804   schema.dropIfExistsTable( COND_AUTHENTICATION_TABLE );
00805   schema.dropIfExistsTable(SEQUENCE_TABLE_NAME);
00806   session.close();
00807   return true;
00808 }
00809 
00810 bool cond::CredentialStore::installAdmin( const std::string& userName, const std::string& password ){
00811   if(!m_serviceData){
00812     throwException( "The credential store has not been initialized.","cond::CredentialStore::installAdmin" );    
00813   }
00814   const std::string& connectionString = m_serviceData->connectionString;
00815   const std::string& principalName = m_key.principalName();
00816 
00817   CSScopedSession session( *this );
00818   session.startSuper( connectionString, userName, password  );
00819 
00820   coral::ISchema& schema = m_session->nominalSchema();
00821 
00822   PrincipalData princData;
00823   bool found = selectPrincipal( schema, principalName, princData );
00824 
00825   if( found ){
00826     std::string msg("Principal \"");
00827     msg += principalName + "\" has been installed already.";
00828     throwException(msg,"CredentialStore::installAdmin");
00829   }
00830 
00831   KeyGenerator gen;
00832   m_principalKey = gen.make( Auth::COND_DB_KEY_SIZE );
00833 
00834   coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
00835 
00836   ora::SequenceManager sequenceMgr( SEQUENCE_TABLE_NAME,schema );
00837   int principalId = sequenceMgr.getNextId( COND_AUTHENTICATION_TABLE, true );
00838     
00839   Cipher cipher0( m_key.principalKey() );
00840   Cipher cipher1( m_principalKey );
00841 
00842   coral::AttributeList authData;
00843   editor0.rowBuffer(authData);
00844   authData[ PRINCIPAL_ID_COL ].data<int>() = principalId;
00845   authData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
00846   authData[ VERIFICATION_COL ].data<std::string>() = cipher0.b64encrypt( principalName );
00847   authData[ PRINCIPAL_KEY_COL ].data<std::string>() = cipher0.b64encrypt( m_principalKey );
00848   authData[ ADMIN_KEY_COL ].data<std::string>() = cipher1.b64encrypt( m_principalKey );
00849   editor0.insertRow( authData );
00850 
00851   std::string connLabel = schemaLabelForCredentialStore( connectionString );
00852   DecodingKey tmpKey;
00853   std::string connectionKey = gen.make( Auth::COND_DB_KEY_SIZE );
00854   std::string encryptedConnectionKey = cipher1.b64encrypt( connectionKey );    
00855 
00856   Cipher cipher2( connectionKey );
00857   std::string encryptedUserName = cipher2.b64encrypt( userName );
00858   std::string encryptedPassword = cipher2.b64encrypt( password );
00859   std::string encryptedLabel = cipher2.b64encrypt( connLabel );    
00860   
00861   int connId = sequenceMgr.getNextId( COND_CREDENTIAL_TABLE, true );
00862     
00863   coral::ITableDataEditor& editor1 = schema.tableHandle(COND_CREDENTIAL_TABLE).dataEditor();
00864   coral::AttributeList connectionData;
00865   editor1.rowBuffer(connectionData);
00866   connectionData[ CONNECTION_ID_COL ].data<int>() = connId;
00867   connectionData[ CONNECTION_LABEL_COL ].data<std::string>() = connLabel;
00868   connectionData[ USERNAME_COL ].data<std::string>() = encryptedUserName;
00869   connectionData[ PASSWORD_COL ].data<std::string>() = encryptedPassword;
00870   connectionData[ VERIFICATION_KEY_COL ].data<std::string>() = encryptedLabel;
00871   connectionData[ CONNECTION_KEY_COL ].data<std::string>() = encryptedConnectionKey;
00872   editor1.insertRow( connectionData );
00873 
00874   int authId = sequenceMgr.getNextId( COND_AUTHORIZATION_TABLE, true );
00875     
00876   coral::ITableDataEditor& editor2 = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
00877   coral::AttributeList permissionData;
00878   editor2.rowBuffer(permissionData);
00879   permissionData[ AUTH_ID_COL ].data<int>() = authId;
00880   permissionData[ P_ID_COL ].data<int>() = principalId;
00881   permissionData[ ROLE_COL ].data<std::string>() = Auth::COND_ADMIN_ROLE;
00882   permissionData[ SCHEMA_COL ].data<std::string>() = connectionString;
00883   permissionData[ AUTH_KEY_COL ].data<std::string>() = encryptedConnectionKey;
00884   permissionData[ C_ID_COL ].data<int>() = connId;
00885   editor2.insertRow( permissionData );
00886 
00887   session.close();
00888   return true;
00889 }
00890 
00891 bool cond::CredentialStore::updatePrincipal( const std::string& principalName, 
00892                                              const std::string& authenticationKey,
00893                                              bool setAdmin ){
00894   CSScopedSession session( *this );
00895   session.start( false  );
00896 
00897   coral::ISchema& schema = m_session->nominalSchema();
00898 
00899   PrincipalData princData;
00900   bool found = selectPrincipal( schema, principalName, princData );
00901 
00902   Cipher adminCipher( m_principalKey );
00903   Cipher cipher( authenticationKey );
00904   std::string verifStr = cipher.b64encrypt( principalName );
00905   std::string principalKey("");
00906   if( setAdmin ) principalKey = m_principalKey;
00907   int principalId = princData.id;
00908 
00909   coral::ITableDataEditor& editor = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
00910   if( found ){
00911     if( principalKey.empty() ) principalKey = adminCipher.b64decrypt( princData.adminKey );
00912     coral::AttributeList updateData;
00913     updateData.extend<int>( PRINCIPAL_ID_COL );
00914     updateData.extend<std::string>( VERIFICATION_COL );
00915     updateData.extend<std::string>( PRINCIPAL_KEY_COL );
00916     updateData.extend<std::string>( ADMIN_KEY_COL );
00917     updateData[ PRINCIPAL_ID_COL ].data<int>() = principalId;
00918     updateData[ VERIFICATION_COL ].data<std::string>() = verifStr;
00919     updateData[ PRINCIPAL_KEY_COL ].data<std::string>() = cipher.b64encrypt( principalKey );
00920     updateData[ ADMIN_KEY_COL ].data<std::string>() = adminCipher.b64encrypt( principalKey );
00921     std::stringstream setClause;
00922     setClause << VERIFICATION_COL <<" = :" <<VERIFICATION_COL <<", ";
00923     setClause << PRINCIPAL_KEY_COL << " = :" << PRINCIPAL_KEY_COL <<", ";
00924     setClause << ADMIN_KEY_COL << " = :" << ADMIN_KEY_COL;
00925     std::string whereClause = PRINCIPAL_ID_COL+" = :"+PRINCIPAL_ID_COL;
00926     editor.updateRows( setClause.str(),whereClause, updateData );
00927   } else {
00928     if( principalKey.empty() ) {
00929       KeyGenerator gen;
00930       principalKey = gen.make( Auth::COND_DB_KEY_SIZE );
00931     }
00932 
00933     coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
00934 
00935     ora::SequenceManager sequenceMgr( SEQUENCE_TABLE_NAME,schema );
00936     principalId = sequenceMgr.getNextId( COND_AUTHENTICATION_TABLE, true );
00937         
00938     coral::AttributeList authData;
00939     editor0.rowBuffer(authData);
00940     authData[ PRINCIPAL_ID_COL ].data<int>() = principalId;
00941     authData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
00942     authData[ VERIFICATION_COL ].data<std::string>() = cipher.b64encrypt( principalName );
00943     authData[ PRINCIPAL_KEY_COL ].data<std::string>() = cipher.b64encrypt( principalKey );
00944     authData[ ADMIN_KEY_COL ].data<std::string>() = adminCipher.b64encrypt( principalKey );
00945     editor0.insertRow( authData );
00946   }
00947 
00948   if(setAdmin){
00949     std::string connString = m_serviceData->connectionString;
00950     std::string connLabel = schemaLabelForCredentialStore( connString );
00951     CredentialData credsData;
00952     bool found = selectConnection( schema, connLabel, credsData );
00953     if(!found){
00954       throwException("Credential Store connection has not been defined.","CredentialStore::updatePrincipal");
00955     }
00956     setPermission( principalId, principalKey, Auth::COND_ADMIN_ROLE, connString, credsData.id, adminCipher.b64decrypt( credsData.connectionKey ) );
00957   }
00958 
00959   session.close();
00960   return true;
00961 }
00962 
00963 
00964 bool cond::CredentialStore::setPermission( const std::string& principal, 
00965                                            const std::string& role, 
00966                                            const std::string& connectionString, 
00967                                            const std::string& connectionLabel ){
00968   CSScopedSession session( *this );
00969   session.start( false  );
00970 
00971   coral::ISchema& schema = m_session->nominalSchema();
00972 
00973   PrincipalData princData;
00974   bool found = selectPrincipal( schema, principal, princData );
00975 
00976   if( ! found ){
00977     std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
00978     throwException( msg, "CredentialStore::setPermission");
00979   }
00980 
00981   CredentialData credsData;
00982   found = selectConnection( schema, connectionLabel, credsData );
00983   
00984   if( ! found ){
00985     std::string msg = "Connection named \"" + connectionLabel + "\" does not exist in the database.";
00986     throwException( msg, "CredentialStore::setPermission");
00987   }
00988 
00989   Cipher cipher( m_principalKey );
00990   bool ret = setPermission( princData.id, cipher.b64decrypt( princData.adminKey), role, connectionString, credsData.id, cipher.b64decrypt( credsData.connectionKey ) );
00991   session.close();
00992   return ret;
00993 }
00994 
00995 bool cond::CredentialStore::unsetPermission( const std::string& principal, 
00996                                              const std::string& role, 
00997                                              const std::string& connectionString ){
00998   CSScopedSession session( *this );
00999   session.start( false  );
01000   coral::ISchema& schema = m_session->nominalSchema();
01001 
01002   PrincipalData princData;
01003   bool found = selectPrincipal( schema, principal, princData );
01004 
01005   if( ! found ){
01006     std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
01007     throwException( msg, "CredentialStore::unsetPermission");
01008   }
01009 
01010   coral::ITableDataEditor& editor = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
01011   coral::AttributeList deleteData;
01012   deleteData.extend<int>( P_ID_COL );
01013   deleteData.extend<std::string>( ROLE_COL );
01014   deleteData.extend<std::string>( SCHEMA_COL );
01015   deleteData[ P_ID_COL ].data<int>() = princData.id;
01016   deleteData[ ROLE_COL ].data<std::string>() = role;
01017   deleteData[ SCHEMA_COL ].data<std::string>() = connectionString;
01018   std::stringstream whereClause;
01019   whereClause << P_ID_COL+" = :"+P_ID_COL;
01020   whereClause << " AND "<< ROLE_COL <<" = :"<<ROLE_COL;
01021   whereClause << " AND "<< SCHEMA_COL <<" = :"<<SCHEMA_COL;
01022   editor.deleteRows( whereClause.str(), deleteData );
01023   session.close();
01024   return true;
01025 }
01026 
01027 bool cond::CredentialStore::updateConnection( const std::string& connectionLabel, 
01028                                               const std::string& userName, 
01029                                               const std::string& password ){
01030   CSScopedSession session( *this );
01031   session.start( false  );
01032 
01033   m_session->transaction().start();
01034 
01035   updateConnection( connectionLabel,userName, password, true ); 
01036 
01037   session.close();
01038   return true;
01039 }
01040 
01041 bool cond::CredentialStore::removePrincipal( const std::string& principal ){
01042   CSScopedSession session( *this );
01043   session.start( false  );
01044   coral::ISchema& schema = m_session->nominalSchema();
01045 
01046   PrincipalData princData;
01047   bool found = selectPrincipal( schema, principal, princData );
01048 
01049   if( ! found ){
01050     std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
01051     throwException( msg, "CredentialStore::removePrincipal");
01052   }
01053 
01054   coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
01055 
01056   coral::AttributeList deleteData0;
01057   deleteData0.extend<int>( P_ID_COL );
01058   deleteData0[ P_ID_COL ].data<int>() = princData.id;
01059   std::string whereClause0 = P_ID_COL+" = :"+P_ID_COL;
01060   editor0.deleteRows( whereClause0 , deleteData0 );
01061 
01062   coral::ITableDataEditor& editor1 = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
01063 
01064   coral::AttributeList deleteData1;
01065   deleteData1.extend<int>( PRINCIPAL_ID_COL );
01066   deleteData1[ PRINCIPAL_ID_COL ].data<int>() = princData.id;
01067   std::string whereClause1 = PRINCIPAL_ID_COL+" = :"+PRINCIPAL_ID_COL;
01068   editor1.deleteRows( whereClause1 , deleteData1 );
01069 
01070   session.close();
01071   
01072   return true;
01073 }
01074 
01075 bool cond::CredentialStore::removeConnection( const std::string& connectionLabel ){
01076   CSScopedSession session( *this );
01077   session.start( false  );
01078   coral::ISchema& schema = m_session->nominalSchema();
01079 
01080   CredentialData credsData;
01081   bool found = selectConnection( schema, connectionLabel, credsData );
01082 
01083   if( ! found ){
01084     std::string msg = "Connection named \"" + connectionLabel + "\" does not exist in the database.";
01085     throwException( msg, "CredentialStore::removeConnection");
01086   }
01087 
01088   coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
01089 
01090   coral::AttributeList deleteData0;
01091   deleteData0.extend<int>( C_ID_COL );
01092   deleteData0[ C_ID_COL ].data<int>() = credsData.id;
01093   std::string whereClause0 = C_ID_COL+" = :"+C_ID_COL;
01094   editor0.deleteRows( whereClause0 , deleteData0 );
01095 
01096   coral::ITableDataEditor& editor1 = schema.tableHandle(COND_CREDENTIAL_TABLE).dataEditor();
01097 
01098   coral::AttributeList deleteData1;
01099   deleteData1.extend<int>( CONNECTION_ID_COL );
01100   deleteData1[ CONNECTION_ID_COL ].data<int>() = credsData.id;
01101   std::string whereClause1 = CONNECTION_ID_COL+" = :"+CONNECTION_ID_COL;
01102   editor1.deleteRows( whereClause1 , deleteData1 );
01103 
01104   session.close();
01105 
01106   return true;
01107 }
01108 
01109 bool cond::CredentialStore::selectForUser( coral_bridge::AuthenticationCredentialSet& destinationData ){
01110   CSScopedSession session( *this );
01111   session.start( true  );
01112   coral::ISchema& schema = m_session->nominalSchema();
01113 
01114   Cipher cipher( m_principalKey );
01115 
01116   std::auto_ptr<coral::IQuery> query(schema.newQuery());
01117   query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
01118   query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
01119   coral::AttributeList readBuff;
01120   readBuff.extend<std::string>("AUTHO."+ROLE_COL);
01121   readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
01122   readBuff.extend<std::string>("AUTHO."+AUTH_KEY_COL);
01123   readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
01124   readBuff.extend<std::string>("CREDS."+USERNAME_COL);
01125   readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
01126   readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
01127   coral::AttributeList whereData;
01128   whereData.extend<int>(P_ID_COL);
01129   whereData[ P_ID_COL ].data<int>() = m_principalId;
01130   std::stringstream whereClause;
01131   whereClause << "AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
01132   whereClause << " AND " << "AUTHO."<< P_ID_COL << " = :"<<P_ID_COL;
01133   query->defineOutput(readBuff);
01134   query->addToOutputList( "AUTHO."+ROLE_COL );
01135   query->addToOutputList( "AUTHO."+SCHEMA_COL );
01136   query->addToOutputList( "AUTHO."+AUTH_KEY_COL );
01137   query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
01138   query->addToOutputList( "CREDS."+USERNAME_COL );
01139   query->addToOutputList( "CREDS."+PASSWORD_COL );
01140   query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
01141   query->setCondition( whereClause.str(), whereData );
01142   coral::ICursor& cursor = query->execute();
01143   while ( cursor.next() ) {
01144     const coral::AttributeList& row = cursor.currentRow();
01145     const std::string& role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
01146     const std::string& connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
01147     const std::string& encryptedAuthKey = row[ "AUTHO."+AUTH_KEY_COL ].data<std::string>();
01148     const std::string& connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
01149     const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL ].data<std::string>();
01150     const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL ].data<std::string>();
01151     const std::string& encryptedLabel = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
01152     std::string authKey = cipher.b64decrypt( encryptedAuthKey );
01153     Cipher connCipher( authKey );
01154     if( connCipher.b64decrypt( encryptedLabel ) == connectionLabel ){
01155       destinationData.registerCredentials( connectionString, role, connCipher.b64decrypt( encryptedUserName ),  connCipher.b64decrypt( encryptedPassword ) );
01156     } 
01157   }
01158   session.close();
01159   return true;
01160 }
01161 
01162 bool cond::CredentialStore::importForPrincipal( const std::string& principal, 
01163                                                 const coral_bridge::AuthenticationCredentialSet& dataSource ){
01164   CSScopedSession session( *this );
01165   session.start( false  );
01166   coral::ISchema& schema = m_session->nominalSchema();
01167 
01168   PrincipalData princData;
01169   bool found = selectPrincipal( schema, principal, princData );
01170 
01171   if( ! found ){
01172     std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
01173     throwException( msg, "CredentialStore::importForPrincipal");
01174   }
01175 
01176   bool imported = false;
01177   Cipher cipher( m_principalKey );
01178   std::string princKey = cipher.b64decrypt( princData.adminKey);
01179 
01180   const std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >& creds = dataSource.data();
01181   for( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iConn = creds.begin(); iConn != creds.end(); ++iConn ){
01182     const std::string& connectionString = iConn->first.first;
01183     coral::URIParser parser;
01184     parser.setURI( connectionString );
01185     std::string serviceName = parser.hostName();
01186     const std::string& role = iConn->first.second;
01187     std::string userName = iConn->second->valueForItem( coral::IAuthenticationCredentials::userItem() );
01188     std::string password = iConn->second->valueForItem( coral::IAuthenticationCredentials::passwordItem());
01189     // first import the connections
01190     std::pair<int,std::string> conn = updateConnection( schemaLabel( serviceName, userName ), userName, password, false );
01191     Cipher cipher( m_principalKey );
01192     // than set the permission for the specific role
01193     setPermission( princData.id, princKey, role, connectionString, conn.first, conn.second );
01194     imported = true;
01195   }
01196   session.close();  
01197   return imported;
01198 }
01199 
01200 bool cond::CredentialStore::listPrincipals( std::vector<std::string>& destination ){
01201 
01202   CSScopedSession session( *this );
01203   session.start( true  );
01204   coral::ISchema& schema = m_session->nominalSchema();
01205 
01206   std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHENTICATION_TABLE).newQuery());
01207   coral::AttributeList readBuff;
01208   readBuff.extend<std::string>(PRINCIPAL_NAME_COL);
01209   query->defineOutput(readBuff);
01210   query->addToOutputList( PRINCIPAL_NAME_COL );
01211   coral::ICursor& cursor = query->execute();
01212   bool found = false;
01213   while ( cursor.next() ) {
01214     found = true;
01215     const coral::AttributeList& row = cursor.currentRow();
01216     destination.push_back( row[ PRINCIPAL_NAME_COL ].data<std::string>() );
01217   }
01218   session.close();    
01219   return found;
01220 }
01221 
01222 
01223 bool cond::CredentialStore::listConnections( std::map<std::string,std::pair<std::string,std::string> >& destination ){
01224   CSScopedSession session( *this );
01225   session.start( true  );
01226   coral::ISchema& schema = m_session->nominalSchema();
01227 
01228   std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_CREDENTIAL_TABLE).newQuery());
01229   coral::AttributeList readBuff;
01230   readBuff.extend<std::string>( CONNECTION_LABEL_COL );
01231   readBuff.extend<std::string>( USERNAME_COL );
01232   readBuff.extend<std::string>( PASSWORD_COL );
01233   readBuff.extend<std::string>( VERIFICATION_KEY_COL );
01234   readBuff.extend<std::string>( CONNECTION_KEY_COL );
01235   query->defineOutput(readBuff);
01236   query->addToOutputList( CONNECTION_LABEL_COL );
01237   query->addToOutputList( USERNAME_COL );
01238   query->addToOutputList( PASSWORD_COL );
01239   query->addToOutputList( VERIFICATION_KEY_COL );
01240   query->addToOutputList( CONNECTION_KEY_COL );
01241   coral::ICursor& cursor = query->execute();
01242   bool found = false;
01243   Cipher cipher0(m_principalKey );
01244   while ( cursor.next() ) {
01245     std::string userName("");
01246     std::string password("");
01247     const coral::AttributeList& row = cursor.currentRow();
01248     const std::string& connLabel = row[ CONNECTION_LABEL_COL].data<std::string>();
01249     const std::string& encryptedKey = row[ CONNECTION_KEY_COL].data<std::string>();
01250     const std::string& encryptedVerif = row[ VERIFICATION_KEY_COL].data<std::string>();
01251     std::string connKey = cipher0.b64decrypt( encryptedKey );
01252     Cipher cipher1( connKey );
01253     std::string verif = cipher1.b64decrypt( encryptedVerif );
01254     if( verif == connLabel ){
01255       const std::string& encryptedUserName = row[ USERNAME_COL].data<std::string>();
01256       const std::string& encryptedPassword = row[ PASSWORD_COL].data<std::string>();
01257       userName = cipher1.b64decrypt( encryptedUserName );
01258       password = cipher1.b64decrypt( encryptedPassword );
01259     }
01260     destination.insert( std::make_pair( connLabel, std::make_pair( userName, password ) ) );
01261     found = true;
01262   }
01263   session.close();    
01264   return found;
01265 }
01266 
01267 bool cond::CredentialStore::selectPermissions( const std::string& principalName, 
01268                                                const std::string& role, 
01269                                                const std::string& connectionString, 
01270                                                std::vector<Permission>& destination ){
01271   CSScopedSession session( *this );
01272   session.start( true  );
01273   coral::ISchema& schema = m_session->nominalSchema();
01274   std::auto_ptr<coral::IQuery> query(schema.newQuery());
01275   query->addToTableList(COND_AUTHENTICATION_TABLE, "AUTHE");
01276   query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
01277   query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
01278   coral::AttributeList readBuff;
01279   readBuff.extend<std::string>("AUTHE."+PRINCIPAL_NAME_COL);
01280   readBuff.extend<std::string>("AUTHO."+ROLE_COL);
01281   readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
01282   readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
01283   coral::AttributeList whereData;
01284   std::stringstream whereClause;
01285   whereClause << "AUTHE."<< PRINCIPAL_ID_COL << "= AUTHO."<< P_ID_COL;
01286   whereClause << " AND AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
01287   if( !principalName.empty() ){
01288     whereData.extend<std::string>(PRINCIPAL_NAME_COL);
01289     whereData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
01290     whereClause << " AND AUTHE."<< PRINCIPAL_NAME_COL <<" = :"<<PRINCIPAL_NAME_COL;
01291   }
01292   if( !role.empty() ){
01293     whereData.extend<std::string>(ROLE_COL);
01294     whereData[ ROLE_COL ].data<std::string>() = role;
01295     whereClause << " AND AUTHO."<< ROLE_COL <<" = :"<<ROLE_COL;
01296   }
01297   if( !connectionString.empty() ){
01298     whereData.extend<std::string>(SCHEMA_COL);
01299     whereData[ SCHEMA_COL ].data<std::string>() = connectionString;
01300     whereClause << " AND AUTHO."<< SCHEMA_COL <<" = :"<<SCHEMA_COL;
01301   }
01302   
01303   query->defineOutput(readBuff);
01304   query->addToOutputList( "AUTHE."+PRINCIPAL_NAME_COL );
01305   query->addToOutputList( "AUTHO."+ROLE_COL );
01306   query->addToOutputList( "AUTHO."+SCHEMA_COL );
01307   query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
01308   query->setCondition( whereClause.str(), whereData );
01309   query->addToOrderList( "AUTHO."+SCHEMA_COL );
01310   query->addToOrderList( "AUTHE."+PRINCIPAL_NAME_COL  );
01311   query->addToOrderList( "AUTHO."+ROLE_COL  );
01312   coral::ICursor& cursor = query->execute();
01313   bool found = false;
01314   while ( cursor.next() ) {
01315     const coral::AttributeList& row = cursor.currentRow();
01316     destination.resize( destination.size()+1 );
01317     Permission& perm = destination.back();
01318     perm.principalName = row[ "AUTHE."+PRINCIPAL_NAME_COL ].data<std::string>();
01319     perm.role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
01320     perm.connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
01321     perm.connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
01322     found = true;
01323   }
01324   session.close();
01325   return found;  
01326 }
01327 
01328 bool cond::CredentialStore::exportAll( coral_bridge::AuthenticationCredentialSet& data ){
01329   CSScopedSession session( *this );
01330   session.start( true  );
01331   coral::ISchema& schema = m_session->nominalSchema();
01332   std::auto_ptr<coral::IQuery> query(schema.newQuery());
01333   query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
01334   query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
01335   coral::AttributeList readBuff;
01336   readBuff.extend<std::string>("AUTHO."+ROLE_COL);
01337   readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
01338   readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
01339   readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
01340   readBuff.extend<std::string>("CREDS."+CONNECTION_KEY_COL);
01341   readBuff.extend<std::string>("CREDS."+USERNAME_COL);
01342   readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
01343   coral::AttributeList whereData;
01344   std::stringstream whereClause;
01345   whereClause << "AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
01346   
01347   query->defineOutput(readBuff);
01348   query->addToOutputList( "AUTHO."+ROLE_COL );
01349   query->addToOutputList( "AUTHO."+SCHEMA_COL );
01350   query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
01351   query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
01352   query->addToOutputList( "CREDS."+CONNECTION_KEY_COL );
01353   query->addToOutputList( "CREDS."+USERNAME_COL );
01354   query->addToOutputList( "CREDS."+PASSWORD_COL );
01355   query->setCondition( whereClause.str(), whereData );
01356   coral::ICursor& cursor = query->execute();
01357   bool found = false;
01358   Cipher cipher0( m_principalKey );
01359   while ( cursor.next() ) {
01360     const coral::AttributeList& row = cursor.currentRow();
01361     const std::string& role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
01362     const std::string& connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
01363     const std::string& connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
01364     const std::string& encryptedVerifKey = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
01365     const std::string& encryptedConnection = row[ "CREDS."+CONNECTION_KEY_COL ].data<std::string>();
01366     std::string userName("");
01367     std::string password("");
01368     std::string connectionKey = cipher0.b64decrypt( encryptedConnection );
01369     Cipher cipher1( connectionKey );
01370     std::string verifKey = cipher1.b64decrypt( encryptedVerifKey );
01371     if( verifKey == connectionLabel ){
01372       const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL].data<std::string>();
01373       const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL].data<std::string>();
01374       userName = cipher1.b64decrypt( encryptedUserName );
01375       password = cipher1.b64decrypt( encryptedPassword );
01376     }
01377     data.registerCredentials( connectionString, role, userName, password );
01378     found = true;
01379   }
01380   session.close();
01381   return found;  
01382 }
01383 
01384 const std::string& cond::CredentialStore::keyPrincipalName (){
01385   return m_key.principalName();
01386 }
01387 
01388