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
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
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
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
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
00449 throwException( "Provided credentials does not allow admin operation.",
00450 "CredentialStore::openSession");
00451 }
00452
00453
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
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
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
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
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
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 bool forceUpdateConnection ){
01165 CSScopedSession session( *this );
01166 session.start( false );
01167 coral::ISchema& schema = m_session->nominalSchema();
01168
01169 PrincipalData princData;
01170 bool found = selectPrincipal( schema, principal, princData );
01171
01172 if( ! found ){
01173 std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
01174 throwException( msg, "CredentialStore::importForPrincipal");
01175 }
01176
01177 bool imported = false;
01178 Cipher cipher( m_principalKey );
01179 std::string princKey = cipher.b64decrypt( princData.adminKey);
01180
01181 const std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >& creds = dataSource.data();
01182 for( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iConn = creds.begin(); iConn != creds.end(); ++iConn ){
01183 const std::string& connectionString = iConn->first.first;
01184 coral::URIParser parser;
01185 parser.setURI( connectionString );
01186 std::string serviceName = parser.hostName();
01187 const std::string& role = iConn->first.second;
01188 std::string userName = iConn->second->valueForItem( coral::IAuthenticationCredentials::userItem() );
01189 std::string password = iConn->second->valueForItem( coral::IAuthenticationCredentials::passwordItem());
01190
01191 std::pair<int,std::string> conn = updateConnection( schemaLabel( serviceName, userName ), userName, password, forceUpdateConnection );
01192 Cipher cipher( m_principalKey );
01193
01194 setPermission( princData.id, princKey, role, connectionString, conn.first, conn.second );
01195 imported = true;
01196 }
01197 session.close();
01198 return imported;
01199 }
01200
01201 bool cond::CredentialStore::listPrincipals( std::vector<std::string>& destination ){
01202
01203 CSScopedSession session( *this );
01204 session.start( true );
01205 coral::ISchema& schema = m_session->nominalSchema();
01206
01207 std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHENTICATION_TABLE).newQuery());
01208 coral::AttributeList readBuff;
01209 readBuff.extend<std::string>(PRINCIPAL_NAME_COL);
01210 query->defineOutput(readBuff);
01211 query->addToOutputList( PRINCIPAL_NAME_COL );
01212 coral::ICursor& cursor = query->execute();
01213 bool found = false;
01214 while ( cursor.next() ) {
01215 found = true;
01216 const coral::AttributeList& row = cursor.currentRow();
01217 destination.push_back( row[ PRINCIPAL_NAME_COL ].data<std::string>() );
01218 }
01219 session.close();
01220 return found;
01221 }
01222
01223
01224 bool cond::CredentialStore::listConnections( std::map<std::string,std::pair<std::string,std::string> >& destination ){
01225 CSScopedSession session( *this );
01226 session.start( true );
01227 coral::ISchema& schema = m_session->nominalSchema();
01228
01229 std::auto_ptr<coral::IQuery> query(schema.tableHandle(COND_CREDENTIAL_TABLE).newQuery());
01230 coral::AttributeList readBuff;
01231 readBuff.extend<std::string>( CONNECTION_LABEL_COL );
01232 readBuff.extend<std::string>( USERNAME_COL );
01233 readBuff.extend<std::string>( PASSWORD_COL );
01234 readBuff.extend<std::string>( VERIFICATION_KEY_COL );
01235 readBuff.extend<std::string>( CONNECTION_KEY_COL );
01236 query->defineOutput(readBuff);
01237 query->addToOutputList( CONNECTION_LABEL_COL );
01238 query->addToOutputList( USERNAME_COL );
01239 query->addToOutputList( PASSWORD_COL );
01240 query->addToOutputList( VERIFICATION_KEY_COL );
01241 query->addToOutputList( CONNECTION_KEY_COL );
01242 coral::ICursor& cursor = query->execute();
01243 bool found = false;
01244 Cipher cipher0(m_principalKey );
01245 while ( cursor.next() ) {
01246 std::string userName("");
01247 std::string password("");
01248 const coral::AttributeList& row = cursor.currentRow();
01249 const std::string& connLabel = row[ CONNECTION_LABEL_COL].data<std::string>();
01250 const std::string& encryptedKey = row[ CONNECTION_KEY_COL].data<std::string>();
01251 const std::string& encryptedVerif = row[ VERIFICATION_KEY_COL].data<std::string>();
01252 std::string connKey = cipher0.b64decrypt( encryptedKey );
01253 Cipher cipher1( connKey );
01254 std::string verif = cipher1.b64decrypt( encryptedVerif );
01255 if( verif == connLabel ){
01256 const std::string& encryptedUserName = row[ USERNAME_COL].data<std::string>();
01257 const std::string& encryptedPassword = row[ PASSWORD_COL].data<std::string>();
01258 userName = cipher1.b64decrypt( encryptedUserName );
01259 password = cipher1.b64decrypt( encryptedPassword );
01260 }
01261 destination.insert( std::make_pair( connLabel, std::make_pair( userName, password ) ) );
01262 found = true;
01263 }
01264 session.close();
01265 return found;
01266 }
01267
01268 bool cond::CredentialStore::selectPermissions( const std::string& principalName,
01269 const std::string& role,
01270 const std::string& connectionString,
01271 std::vector<Permission>& destination ){
01272 CSScopedSession session( *this );
01273 session.start( true );
01274 coral::ISchema& schema = m_session->nominalSchema();
01275 std::auto_ptr<coral::IQuery> query(schema.newQuery());
01276 query->addToTableList(COND_AUTHENTICATION_TABLE, "AUTHE");
01277 query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
01278 query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
01279 coral::AttributeList readBuff;
01280 readBuff.extend<std::string>("AUTHE."+PRINCIPAL_NAME_COL);
01281 readBuff.extend<std::string>("AUTHO."+ROLE_COL);
01282 readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
01283 readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
01284 coral::AttributeList whereData;
01285 std::stringstream whereClause;
01286 whereClause << "AUTHE."<< PRINCIPAL_ID_COL << "= AUTHO."<< P_ID_COL;
01287 whereClause << " AND AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
01288 if( !principalName.empty() ){
01289 whereData.extend<std::string>(PRINCIPAL_NAME_COL);
01290 whereData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
01291 whereClause << " AND AUTHE."<< PRINCIPAL_NAME_COL <<" = :"<<PRINCIPAL_NAME_COL;
01292 }
01293 if( !role.empty() ){
01294 whereData.extend<std::string>(ROLE_COL);
01295 whereData[ ROLE_COL ].data<std::string>() = role;
01296 whereClause << " AND AUTHO."<< ROLE_COL <<" = :"<<ROLE_COL;
01297 }
01298 if( !connectionString.empty() ){
01299 whereData.extend<std::string>(SCHEMA_COL);
01300 whereData[ SCHEMA_COL ].data<std::string>() = connectionString;
01301 whereClause << " AND AUTHO."<< SCHEMA_COL <<" = :"<<SCHEMA_COL;
01302 }
01303
01304 query->defineOutput(readBuff);
01305 query->addToOutputList( "AUTHE."+PRINCIPAL_NAME_COL );
01306 query->addToOutputList( "AUTHO."+ROLE_COL );
01307 query->addToOutputList( "AUTHO."+SCHEMA_COL );
01308 query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
01309 query->setCondition( whereClause.str(), whereData );
01310 query->addToOrderList( "AUTHO."+SCHEMA_COL );
01311 query->addToOrderList( "AUTHE."+PRINCIPAL_NAME_COL );
01312 query->addToOrderList( "AUTHO."+ROLE_COL );
01313 coral::ICursor& cursor = query->execute();
01314 bool found = false;
01315 while ( cursor.next() ) {
01316 const coral::AttributeList& row = cursor.currentRow();
01317 destination.resize( destination.size()+1 );
01318 Permission& perm = destination.back();
01319 perm.principalName = row[ "AUTHE."+PRINCIPAL_NAME_COL ].data<std::string>();
01320 perm.role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
01321 perm.connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
01322 perm.connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
01323 found = true;
01324 }
01325 session.close();
01326 return found;
01327 }
01328
01329 bool cond::CredentialStore::exportAll( coral_bridge::AuthenticationCredentialSet& data ){
01330 CSScopedSession session( *this );
01331 session.start( true );
01332 coral::ISchema& schema = m_session->nominalSchema();
01333 std::auto_ptr<coral::IQuery> query(schema.newQuery());
01334 query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
01335 query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
01336 coral::AttributeList readBuff;
01337 readBuff.extend<std::string>("AUTHO."+ROLE_COL);
01338 readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
01339 readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
01340 readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
01341 readBuff.extend<std::string>("CREDS."+CONNECTION_KEY_COL);
01342 readBuff.extend<std::string>("CREDS."+USERNAME_COL);
01343 readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
01344 coral::AttributeList whereData;
01345 std::stringstream whereClause;
01346 whereClause << "AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
01347
01348 query->defineOutput(readBuff);
01349 query->addToOutputList( "AUTHO."+ROLE_COL );
01350 query->addToOutputList( "AUTHO."+SCHEMA_COL );
01351 query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
01352 query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
01353 query->addToOutputList( "CREDS."+CONNECTION_KEY_COL );
01354 query->addToOutputList( "CREDS."+USERNAME_COL );
01355 query->addToOutputList( "CREDS."+PASSWORD_COL );
01356 query->setCondition( whereClause.str(), whereData );
01357 coral::ICursor& cursor = query->execute();
01358 bool found = false;
01359 Cipher cipher0( m_principalKey );
01360 while ( cursor.next() ) {
01361 const coral::AttributeList& row = cursor.currentRow();
01362 const std::string& role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
01363 const std::string& connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
01364 const std::string& connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
01365 const std::string& encryptedVerifKey = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
01366 const std::string& encryptedConnection = row[ "CREDS."+CONNECTION_KEY_COL ].data<std::string>();
01367 std::string userName("");
01368 std::string password("");
01369 std::string connectionKey = cipher0.b64decrypt( encryptedConnection );
01370 Cipher cipher1( connectionKey );
01371 std::string verifKey = cipher1.b64decrypt( encryptedVerifKey );
01372 if( verifKey == connectionLabel ){
01373 const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL].data<std::string>();
01374 const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL].data<std::string>();
01375 userName = cipher1.b64decrypt( encryptedUserName );
01376 password = cipher1.b64decrypt( encryptedPassword );
01377 }
01378 data.registerCredentials( connectionString, role, userName, password );
01379 found = true;
01380 }
01381 session.close();
01382 return found;
01383 }
01384
01385 const std::string& cond::CredentialStore::keyPrincipalName (){
01386 return m_key.principalName();
01387 }
01388
01389