CMS 3D CMS Logo

CredentialStore.cc
Go to the documentation of this file.
5 //
6 #include "CoralBase/AttributeList.h"
7 #include "CoralBase/Attribute.h"
8 #include "CoralKernel/Context.h"
9 #include "CoralCommon/URIParser.h"
10 #include "RelationalAccess/AuthenticationCredentials.h"
11 #include "RelationalAccess/IBulkOperation.h"
12 #include "RelationalAccess/IConnection.h"
13 #include "RelationalAccess/ISession.h"
14 #include "RelationalAccess/IRelationalService.h"
15 #include "RelationalAccess/IRelationalDomain.h"
16 #include "RelationalAccess/ITransaction.h"
17 #include "RelationalAccess/ISchema.h"
18 #include "RelationalAccess/ITable.h"
19 #include "RelationalAccess/TableDescription.h"
20 #include "RelationalAccess/ITableDataEditor.h"
21 #include "RelationalAccess/ITablePrivilegeManager.h"
22 #include "RelationalAccess/IQuery.h"
23 #include "RelationalAccess/ICursor.h"
24 //
25 #include "RelationalAccess/AuthenticationCredentials.h"
26 //
27 #include <sstream>
28 #include <fstream>
29 #include <boost/filesystem.hpp>
30 
31 static const std::string serviceName = "CondAuthenticationService";
32 
34  m_data(){
35 }
36 
38  reset();
39 }
40 
42  for ( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::iterator iData = m_data.begin();
43  iData != m_data.end(); ++iData )
44  delete iData->second;
45  m_data.clear();
46 }
47 
49  const std::string& itemName,
50  const std::string& itemValue ){
51  registerItem( connectionString, cond::auth::COND_DEFAULT_ROLE, itemName, itemValue );
52 }
53 
54 
56  const std::string& role,
57  const std::string& itemName,
58  const std::string& itemValue ){
59  std::pair<std::string,std::string> connKey( connectionString, role );
60  std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::iterator iData = m_data.find( connKey );
61  if( iData == m_data.end() ){
62  iData = m_data.insert( std::make_pair( connKey, new coral::AuthenticationCredentials( serviceName ) ) ).first;
63  }
64  iData = m_data.insert( std::make_pair( connKey, new coral::AuthenticationCredentials( serviceName ) ) ).first;
65  iData->second->registerItem( itemName, itemValue );
66 }
67 
68 void
70  const std::string& userName,
71  const std::string& password ){
72  registerCredentials( connectionString, cond::auth::COND_DEFAULT_ROLE, userName, password );
73 }
74 
75 void
77  const std::string& role,
78  const std::string& userName,
79  const std::string& password ){
80  std::pair<std::string,std::string> connKey( connectionString, role );
81  std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::iterator iData = m_data.find( connKey );
82  if( iData != m_data.end() ){
83  delete iData->second;
84  m_data.erase( connKey );
85  }
86  iData = m_data.insert( std::make_pair( connKey, new coral::AuthenticationCredentials( serviceName ) ) ).first;
87  iData->second->registerItem( coral::IAuthenticationCredentials::userItem(), userName );
88  iData->second->registerItem( coral::IAuthenticationCredentials::passwordItem(), password );
89 }
90 
92  for ( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iData = data.m_data.begin();
93  iData != data.m_data.end(); ++iData ){
94  registerCredentials( iData->first.first, iData->first.second, iData->second->valueForItem( coral::IAuthenticationCredentials::userItem() ),
95  iData->second->valueForItem( coral::IAuthenticationCredentials::passwordItem() ) );
96  }
97 }
98 
99 const coral::IAuthenticationCredentials*
101 {
102  return get( connectionString, cond::auth::COND_DEFAULT_ROLE );
103 }
104 
105 const coral::IAuthenticationCredentials*
106 coral_bridge::AuthenticationCredentialSet::get( const std::string& connectionString, const std::string& role ) const
107 {
108  const coral::IAuthenticationCredentials* ret = nullptr;
109  std::pair<std::string,std::string> connKey( connectionString, role );
110  std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iData = m_data.find( connKey );
111  if ( iData != m_data.end() ){
112  ret = iData->second;
113  }
114  return ret;
115 }
116 
117 const std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >& coral_bridge::AuthenticationCredentialSet::data() const {
118  return m_data;
119 }
120 
121 static const std::string SEQUENCE_TABLE_NAME("COND_CREDENTIAL_SEQUENCE");
122 static const std::string SEQUENCE_NAME_COL("NAME");
123 static const std::string SEQUENCE_VALUE_COL("VALUE");
124 
125 static const std::string COND_AUTHENTICATION_TABLE("COND_AUTHENTICATION");
126 static const std::string PRINCIPAL_ID_COL("P_ID");
127 static const std::string PRINCIPAL_NAME_COL("P_NAME");
128 static const std::string VERIFICATION_COL("CRED0");
129 static const std::string PRINCIPAL_KEY_COL("CRED1");
130 static const std::string ADMIN_KEY_COL("CRED2");
131 
132 static const std::string COND_AUTHORIZATION_TABLE("COND_AUTHORIZATION");
133 static const std::string AUTH_ID_COL("AUTH_ID");
134 static const std::string P_ID_COL("P_ID");
135 static const std::string ROLE_COL("C_ROLE");
136 static const std::string SCHEMA_COL("C_SCHEMA");
137 static const std::string AUTH_KEY_COL("CRED3");
138 static const std::string C_ID_COL("C_ID");
139 
140 static const std::string COND_CREDENTIAL_TABLE("COND_CREDENTIAL");
141 static const std::string CONNECTION_ID_COL("CONN_ID");
142 static const std::string CONNECTION_LABEL_COL("CONN_LABEL");
143 static const std::string USERNAME_COL("CRED4");
144 static const std::string PASSWORD_COL("CRED5");
145 static const std::string VERIFICATION_KEY_COL("CRED6");
146 static const std::string CONNECTION_KEY_COL("CRED7");
147 
148 const std::string DEFAULT_DATA_SOURCE("Cond_Default_Authentication");
149 
150 // implementation functions and helpers
151 namespace cond {
152 
154  const std::string& userName ){
155  std::string ret = userName;
156  if( !serviceName.empty() ){
157  ret += "@"+serviceName;
158  }
159  return ret;
160  }
161 
163  coral::URIParser parser;
164  parser.setURI( connectionString );
165  std::string serviceName = parser.hostName();
166  std::string schemaName = parser.databaseOrSchemaName();
167  return schemaLabel( serviceName, schemaName );
168  }
169 
171  public:
173  m_store( store ){}
175  m_store.closeSession( false );
176  }
177  void startSuper( const std::string& connectionString,
178  const std::string& userName,
179  const std::string& password ){
180  m_store.startSuperSession( connectionString, userName, password );
181  }
182  void start( bool readOnly=true ){
183  m_store.startSession( readOnly );
184  }
185  void close(){
186  m_store.closeSession();
187  }
188 
189  private:
191  };
192 
193  struct PrincipalData {
194  int id;
199  id(-1),
200  verifKey(""),
201  principalKey(""),
202  adminKey(""){}
203  };
204  bool selectPrincipal( coral::ISchema& schema,
205  const std::string& principal,
207 
208  std::unique_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHENTICATION_TABLE).newQuery());
209  coral::AttributeList readBuff;
210  readBuff.extend<int>(PRINCIPAL_ID_COL);
211  readBuff.extend<std::string>(VERIFICATION_COL);
212  readBuff.extend<std::string>(PRINCIPAL_KEY_COL);
213  readBuff.extend<std::string>(ADMIN_KEY_COL);
214  coral::AttributeList whereData;
215  whereData.extend<std::string>(PRINCIPAL_NAME_COL);
216  whereData[ PRINCIPAL_NAME_COL ].data<std::string>() = principal;
217  std::string whereClause = PRINCIPAL_NAME_COL + " = :" + PRINCIPAL_NAME_COL;
218  query->defineOutput(readBuff);
219  query->addToOutputList( PRINCIPAL_ID_COL );
220  query->addToOutputList( VERIFICATION_COL );
221  query->addToOutputList( PRINCIPAL_KEY_COL );
222  query->addToOutputList( ADMIN_KEY_COL );
223  query->setCondition( whereClause, whereData );
224  coral::ICursor& cursor = query->execute();
225  bool found = false;
226  if ( cursor.next() ) {
227  found = true;
228  const coral::AttributeList& row = cursor.currentRow();
229  destination.id = row[ PRINCIPAL_ID_COL ].data<int>();
230  destination.verifKey = row[ VERIFICATION_COL ].data<std::string>();
231  destination.principalKey = row[ PRINCIPAL_KEY_COL ].data<std::string>();
232  destination.adminKey = row[ ADMIN_KEY_COL ].data<std::string>();
233  }
234  return found;
235  }
236 
237  struct CredentialData {
238  int id;
244  id(-1),
245  userName(""),
246  password(""),
247  connectionKey(""){
248  }
249  };
250 
251  bool selectConnection( coral::ISchema& schema,
252  const std::string& connectionLabel,
254 
255  std::unique_ptr<coral::IQuery> query(schema.tableHandle(COND_CREDENTIAL_TABLE).newQuery());
256  coral::AttributeList readBuff;
257  readBuff.extend<int>( CONNECTION_ID_COL );
258  readBuff.extend<std::string>( USERNAME_COL );
259  readBuff.extend<std::string>( PASSWORD_COL );
260  readBuff.extend<std::string>( VERIFICATION_KEY_COL );
261  readBuff.extend<std::string>( CONNECTION_KEY_COL );
262  coral::AttributeList whereData;
263  whereData.extend<std::string>( CONNECTION_LABEL_COL );
264  whereData[ CONNECTION_LABEL_COL ].data<std::string>() = connectionLabel;
265  std::string whereClause = CONNECTION_LABEL_COL + " = :" + CONNECTION_LABEL_COL;
266  query->defineOutput(readBuff);
267  query->addToOutputList( CONNECTION_ID_COL );
268  query->addToOutputList( USERNAME_COL );
269  query->addToOutputList( PASSWORD_COL );
270  query->addToOutputList( VERIFICATION_KEY_COL );
271  query->addToOutputList( CONNECTION_KEY_COL );
272  query->setCondition( whereClause, whereData );
273  coral::ICursor& cursor = query->execute();
274  bool found = false;
275  if ( cursor.next() ) {
276  const coral::AttributeList& row = cursor.currentRow();
277  destination.id = row[ CONNECTION_ID_COL].data<int>();
278  destination.userName = row[ USERNAME_COL].data<std::string>();
279  destination.password = row[ PASSWORD_COL].data<std::string>();
280  destination.verificationKey = row[ VERIFICATION_KEY_COL].data<std::string>();
281  destination.connectionKey = row[ CONNECTION_KEY_COL].data<std::string>();
282  found = true;
283  }
284  return found;
285  }
286 
288  int id;
292  id(-1),
293  connectionId(-1),
294  key(""){}
295  };
296 
297  bool selectAuthorization( coral::ISchema& schema,
298  int principalId,
299  const std::string& role,
300  const std::string& connectionString,
302  std::unique_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHORIZATION_TABLE).newQuery());
303  coral::AttributeList readBuff;
304  readBuff.extend<int>(AUTH_ID_COL);
305  readBuff.extend<int>(C_ID_COL);
306  readBuff.extend<std::string>(AUTH_KEY_COL);
307  coral::AttributeList whereData;
308  whereData.extend<int>(P_ID_COL);
309  whereData.extend<std::string>(ROLE_COL);
310  whereData.extend<std::string>(SCHEMA_COL);
311  whereData[ P_ID_COL ].data<int>() = principalId;
312  whereData[ ROLE_COL ].data<std::string>() = role;
313  whereData[ SCHEMA_COL ].data<std::string>() = connectionString;
314  std::stringstream whereClause;
315  whereClause << P_ID_COL << " = :"<<P_ID_COL;
316  whereClause << " AND " << ROLE_COL << " = :"<<ROLE_COL;
317  whereClause << " AND " << SCHEMA_COL << " = :"<<SCHEMA_COL;
318  query->defineOutput(readBuff);
319  query->addToOutputList( AUTH_ID_COL );
320  query->addToOutputList( C_ID_COL );
321  query->addToOutputList( AUTH_KEY_COL );
322  query->setCondition( whereClause.str(), whereData );
323  coral::ICursor& cursor = query->execute();
324  bool found = false;
325  if ( cursor.next() ) {
326  const coral::AttributeList& row = cursor.currentRow();
327  destination.id = row[AUTH_ID_COL].data<int>();
328  destination.connectionId = row[C_ID_COL].data<int>();
329  destination.key = row[AUTH_KEY_COL].data<std::string>();
330  found = true;
331  }
332  return found;
333  }
334 
335  bool getNextSequenceValue( coral::ISchema& schema,
336  const std::string& sequenceName,
337  int& value ){
338  bool ret = false;
339  std::unique_ptr< coral::IQuery > query( schema.tableHandle( SEQUENCE_TABLE_NAME ).newQuery() );
340  query->limitReturnedRows( 1, 0 );
341  query->addToOutputList( SEQUENCE_VALUE_COL );
342  query->defineOutputType( SEQUENCE_VALUE_COL, coral::AttributeSpecification::typeNameForType<int>() );
343  query->setForUpdate();
344  std::string whereClause( SEQUENCE_NAME_COL + " = :" + SEQUENCE_NAME_COL );
345  coral::AttributeList rowData;
346  rowData.extend<std::string>( SEQUENCE_NAME_COL );
347  rowData.begin()->data< std::string >() = sequenceName;
348  query->setCondition( whereClause, rowData );
349  coral::ICursor& cursor = query->execute();
350  if ( cursor.next() ) {
351  value = cursor.currentRow().begin()->data<int>()+1;
352  ret = true;
353  } else {
354  return false;
355  }
356  // update...
357  coral::AttributeList updateData;
358  updateData.extend<std::string>( SEQUENCE_NAME_COL );
359  updateData.extend<int>( SEQUENCE_VALUE_COL );
360  std::string setClause( SEQUENCE_VALUE_COL + " = :" + SEQUENCE_VALUE_COL );
361  std::string whClause( SEQUENCE_NAME_COL + " = :" + SEQUENCE_NAME_COL );
362  coral::AttributeList::iterator iAttribute = updateData.begin();
363  iAttribute->data< std::string >() = sequenceName;
364  ++iAttribute;
365  iAttribute->data< int >() = value;
366  schema.tableHandle( SEQUENCE_TABLE_NAME ).dataEditor().updateRows( setClause,whClause,updateData );
367  return ret;
368  }
369 
370  std::pair<int,std::string> updatePrincipalData( coral::ISchema& schema,
371  const std::string& authenticationKey,
372  const std::string& principalName,
373  const std::string& adminKey,
374  bool init=false ) {
375  PrincipalData princData;
376  bool found = selectPrincipal( schema, principalName, princData );
377 
378  auth::Cipher cipher0( authenticationKey );
379  auth::Cipher cipher1( adminKey );
380 
381  std::string verifStr = cipher0.b64encrypt( principalName );
382  std::string principalKey("");
383  int principalId = princData.id;
384 
385  coral::ITableDataEditor& editor = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
386  if( found ){
387  principalKey = cipher1.b64decrypt( princData.adminKey );
388  coral::AttributeList updateData;
389  updateData.extend<int>( PRINCIPAL_ID_COL );
390  updateData.extend<std::string>( VERIFICATION_COL );
391  updateData.extend<std::string>( PRINCIPAL_KEY_COL );
392  updateData.extend<std::string>( ADMIN_KEY_COL );
393  updateData[ PRINCIPAL_ID_COL ].data<int>() = principalId;
394  updateData[ VERIFICATION_COL ].data<std::string>() = verifStr;
395  updateData[ PRINCIPAL_KEY_COL ].data<std::string>() = cipher0.b64encrypt( principalKey );
396  updateData[ ADMIN_KEY_COL ].data<std::string>() = cipher1.b64encrypt( principalKey );
397  std::stringstream setClause;
398  setClause << VERIFICATION_COL <<" = :" <<VERIFICATION_COL <<", ";
399  setClause << PRINCIPAL_KEY_COL << " = :" << PRINCIPAL_KEY_COL <<", ";
400  setClause << ADMIN_KEY_COL << " = :" << ADMIN_KEY_COL;
401  std::string whereClause = PRINCIPAL_ID_COL+" = :"+PRINCIPAL_ID_COL;
402  editor.updateRows( setClause.str(),whereClause, updateData );
403  } else {
404  if( init ){
405  principalKey = adminKey;
406  } else {
408  principalKey = gen.make( auth::COND_DB_KEY_SIZE );
409  }
410  coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
411 
412  if( !getNextSequenceValue( schema, COND_AUTHENTICATION_TABLE, principalId ) ) throwException( "Can't find "+COND_AUTHENTICATION_TABLE+" sequence.","CredentialStore::updatePrincipal" );
413 
414  coral::AttributeList authData;
415  editor0.rowBuffer(authData);
416  authData[ PRINCIPAL_ID_COL ].data<int>() = principalId;
417  authData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
418  authData[ VERIFICATION_COL ].data<std::string>() = verifStr;
419  authData[ PRINCIPAL_KEY_COL ].data<std::string>() = cipher0.b64encrypt( principalKey );
420  authData[ ADMIN_KEY_COL ].data<std::string>() = cipher1.b64encrypt( principalKey );
421  editor0.insertRow( authData );
422  }
423 
424  return std::make_pair(principalId,principalKey);
425  }
426 
427  bool setPermissionData( coral::ISchema& schema,
428  int principalId,
429  const std::string& principalKey,
430  const std::string& role,
431  const std::string& connectionString,
432  int connectionId,
433  const std::string& connectionKey ){
434  auth::Cipher cipher( principalKey );
435  std::string encryptedConnectionKey = cipher.b64encrypt( connectionKey );
436  AuthorizationData authData;
437  bool found = selectAuthorization( schema, principalId, role, connectionString, authData );
438 
439  coral::ITableDataEditor& editor = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
440  if( found ) {
441  coral::AttributeList updateData;
442  updateData.extend<int>( AUTH_ID_COL );
443  updateData.extend<int>( C_ID_COL );
444  updateData.extend<std::string>( AUTH_KEY_COL );
445  updateData[ AUTH_ID_COL ].data<int>() = authData.id;
446  updateData[ C_ID_COL ].data<int>() = connectionId;
447  updateData[ AUTH_KEY_COL ].data<std::string>() = encryptedConnectionKey;
448  std::string setCl = C_ID_COL+" = :"+C_ID_COL + ", "+AUTH_KEY_COL+" = :"+AUTH_KEY_COL;
449  std::string whereCl = AUTH_ID_COL+" = :"+AUTH_ID_COL;
450  editor.updateRows( setCl,whereCl, updateData );
451  } else {
452 
453  int next = -1;
454  if( !getNextSequenceValue( schema, COND_AUTHORIZATION_TABLE, next ) ) throwException( "Can't find "+COND_AUTHORIZATION_TABLE+" sequence.","CredentialStore::setPermission" );
455 
456  coral::AttributeList insertData;
457  insertData.extend<int>( AUTH_ID_COL );
458  insertData.extend<int>( P_ID_COL );
459  insertData.extend<std::string>( ROLE_COL );
460  insertData.extend<std::string>( SCHEMA_COL );
461  insertData.extend<std::string>( AUTH_KEY_COL );
462  insertData.extend<int>( C_ID_COL );
463  insertData[ AUTH_ID_COL ].data<int>() = next;
464  insertData[ P_ID_COL ].data<int>() = principalId;
465  insertData[ ROLE_COL ].data<std::string>() = role;
466  insertData[ SCHEMA_COL ].data<std::string>() = connectionString;
467  insertData[ AUTH_KEY_COL ].data<std::string>() = encryptedConnectionKey;
468  insertData[ C_ID_COL ].data<int>() = connectionId;
469  editor.insertRow( insertData );
470  }
471  return true;
472  }
473 
474  std::pair<int,std::string> updateConnectionData( coral::ISchema& schema,
475  const std::string& adminKey,
476  const std::string& connectionLabel,
477  const std::string& userName,
478  const std::string& password,
479  bool forceUpdate ){
480  CredentialData credsData;
481  bool found = selectConnection( schema, connectionLabel, credsData );
482  int connId = credsData.id;
483 
484  auth::Cipher adminCipher( adminKey );
485  std::string connectionKey("");
486  coral::ITableDataEditor& editor = schema.tableHandle(COND_CREDENTIAL_TABLE).dataEditor();
487  if( found ){
488 
489  connectionKey = adminCipher.b64decrypt( credsData.connectionKey );
490  auth::Cipher cipher( connectionKey );
491  std::string verificationKey = cipher.b64decrypt( credsData.verificationKey );
492  if( verificationKey != connectionLabel ){
493  throwException("Decoding of connection key failed.","CredentialStore::updateConnection");
494  }
495  if( forceUpdate ){
496  std::string encryptedUserName = cipher.b64encrypt( userName );
497  std::string encryptedPassword = cipher.b64encrypt( password );
498 
499  coral::AttributeList updateData;
500  updateData.extend<int>( CONNECTION_ID_COL );
501  updateData.extend<std::string>( USERNAME_COL );
502  updateData.extend<std::string>( PASSWORD_COL );
503  updateData[ CONNECTION_ID_COL ].data<int>() = connId;
504  updateData[ USERNAME_COL ].data<std::string>() = encryptedUserName;
505  updateData[ PASSWORD_COL ].data<std::string>() = encryptedPassword;
506  std::stringstream setCl;
507  setCl << USERNAME_COL << " = :" << USERNAME_COL;
508  setCl <<", " << PASSWORD_COL << " = :" << PASSWORD_COL;
510  editor.updateRows( setCl.str(),whereCl, updateData );
511  }
512  }
513 
514  if(!found){
515 
517  connectionKey = gen.make( auth::COND_DB_KEY_SIZE );
518  auth::Cipher cipher( connectionKey );
519  std::string encryptedUserName = cipher.b64encrypt( userName );
520  std::string encryptedPassword = cipher.b64encrypt( password );
521  std::string encryptedLabel = cipher.b64encrypt( connectionLabel );
522 
523  if( !getNextSequenceValue( schema, COND_CREDENTIAL_TABLE, connId ) ) throwException( "Can't find "+COND_CREDENTIAL_TABLE+" sequence.","CredentialStore::updateConnection" );
524 
525  coral::AttributeList insertData;
526  insertData.extend<int>( CONNECTION_ID_COL );
527  insertData.extend<std::string>( CONNECTION_LABEL_COL );
528  insertData.extend<std::string>( USERNAME_COL );
529  insertData.extend<std::string>( PASSWORD_COL );
530  insertData.extend<std::string>( VERIFICATION_KEY_COL );
531  insertData.extend<std::string>( CONNECTION_KEY_COL );
532  insertData[ CONNECTION_ID_COL ].data<int>() = connId;
533  insertData[ CONNECTION_LABEL_COL ].data<std::string>() = connectionLabel;
534  insertData[ USERNAME_COL ].data<std::string>() = encryptedUserName;
535  insertData[ PASSWORD_COL ].data<std::string>() = encryptedPassword;
536  insertData[ VERIFICATION_KEY_COL ].data<std::string>() = encryptedLabel;
537  insertData[ CONNECTION_KEY_COL ].data<std::string>() = adminCipher.b64encrypt( connectionKey ) ;;
538  editor.insertRow( insertData );
539 
540  }
541  return std::make_pair( connId, connectionKey );
542  }
543 
544 
545 }
546 
547 // class private methods
549 
550  if( m_session.get() ){
551  if(m_session->transaction().isActive()){
552  if( commit ){
553  m_session->transaction().commit();
554  } else {
555  m_session->transaction().rollback();
556  }
557  }
558  m_session->endUserSession();
559  }
560  m_session.reset();
561  if( m_connection.get() ){
562  m_connection->disconnect();
563  }
564  m_connection.reset();
565 }
566 
567 std::pair<std::string,std::string> cond::CredentialStore::openConnection( const std::string& connectionString ){
568  coral::IHandle<coral::IRelationalService> relationalService = coral::Context::instance().query<coral::IRelationalService>();
569  if ( ! relationalService.isValid() ){
570  coral::Context::instance().loadComponent("CORAL/Services/RelationalService");
571  relationalService = coral::Context::instance().query<coral::IRelationalService>();
572  }
573  coral::IRelationalDomain& domain = relationalService->domainForConnection( connectionString );
574  std::pair<std::string,std::string> connTokens = domain.decodeUserConnectionString( connectionString );
575  m_connection.reset( domain.newConnection( connTokens.first ) );
576  m_connection->connect();
577  return connTokens;
578 }
579 
581  const std::string& userName,
582  const std::string& password,
583  bool readMode ){
584  coral::AccessMode accessMode = coral::ReadOnly;
585  if( !readMode ) accessMode = coral::Update;
586  m_session.reset( m_connection->newSession( schemaName, accessMode) );
587  m_session->startUserSession( userName, password );
588  // open read-only transaction
589  m_session->transaction().start( readMode );
590 }
591 
593  const std::string& userName,
594  const std::string& password ){
595  std::pair<std::string,std::string> connTokens = openConnection( connectionString );
596  openSession( connTokens.second, userName, password, false );
597 }
598 
599 // open session on the storage
601  if(!m_serviceData){
602  throwException( "The credential store has not been initialized.","cond::CredentialStore::openConnection" );
603  }
604  const std::string& storeConnectionString = m_serviceData->connectionString;
605 
606  std::pair<std::string,std::string> connTokens = openConnection( storeConnectionString );
607 
608  const std::string& userName = m_serviceData->userName;
609  const std::string& password = m_serviceData->password;
610 
611  openSession( connTokens.second, userName, password, true );
612 
613  coral::ISchema& schema = m_session->nominalSchema();
614  if(!schema.existsTable(COND_AUTHENTICATION_TABLE) ||
615  !schema.existsTable(COND_AUTHORIZATION_TABLE) ||
616  !schema.existsTable(COND_CREDENTIAL_TABLE) ){
617  throwException("Credential database does not exists in \""+storeConnectionString+"\"","CredentialStore::startSession");
618  }
619 
620  const std::string& principalName = m_key.principalName();
621  // now authenticate...
622  PrincipalData princData;
623  if( !selectPrincipal( m_session->nominalSchema(), principalName, princData ) ){
624  throwException( "Invalid credentials provided.(0)",
625  "CredentialStore::startSession");
626  }
627  auth::Cipher cipher0( m_key.principalKey() );
628  std::string verifStr = cipher0.b64decrypt( princData.verifKey );
629  if( verifStr != principalName ){
630  throwException( "Invalid credentials provided (1)",
631  "CredentialStore::startSession");
632  }
633  // ok, authenticated!
634  m_principalId = princData.id;
635  m_principalKey = cipher0.b64decrypt( princData.principalKey );
636 
637  if(!readMode ) {
638 
639  auth::Cipher cipher0( m_principalKey );
640  std::string adminKey = cipher0.b64decrypt( princData.adminKey );
641  if( adminKey != m_principalKey ){
642  // not admin user!
643  throwException( "Provided credentials does not allow admin operation.",
644  "CredentialStore::openSession");
645  }
646 
647  // first find the credentials for WRITING in the security tables
648  std::unique_ptr<coral::IQuery> query(schema.newQuery());
649  query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
650  query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
651  coral::AttributeList readBuff;
652  readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
653  readBuff.extend<std::string>("CREDS."+CONNECTION_KEY_COL);
654  readBuff.extend<std::string>("CREDS."+USERNAME_COL);
655  readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
656  readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
657  coral::AttributeList whereData;
658  whereData.extend<int>(P_ID_COL);
659  whereData.extend<std::string>(ROLE_COL);
660  whereData.extend<std::string>(SCHEMA_COL);
661  whereData[ P_ID_COL ].data<int>() = m_principalId;
662  whereData[ ROLE_COL ].data<std::string>() = auth::COND_ADMIN_ROLE;
663  whereData[ SCHEMA_COL ].data<std::string>() = storeConnectionString;
664  std::stringstream whereClause;
665  whereClause << "AUTHO."<< C_ID_COL << " = CREDS."<<CONNECTION_ID_COL;
666  whereClause << " AND AUTHO."<< P_ID_COL << " = :"<<P_ID_COL;
667  whereClause << " AND AUTHO."<< ROLE_COL << " = :"<<ROLE_COL;
668  whereClause << " AND AUTHO."<< SCHEMA_COL << " = :"<<SCHEMA_COL;
669  query->defineOutput(readBuff);
670  query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
671  query->addToOutputList( "CREDS."+CONNECTION_KEY_COL );
672  query->addToOutputList( "CREDS."+USERNAME_COL );
673  query->addToOutputList( "CREDS."+PASSWORD_COL );
674  query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
675  query->setCondition( whereClause.str(), whereData );
676  coral::ICursor& cursor = query->execute();
677  bool found = false;
678  std::string writeUserName("");
679  std::string writePassword("");
680  if ( cursor.next() ) {
681  const coral::AttributeList& row = cursor.currentRow();
682  const std::string& connLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
683  const std::string& encryptedConnectionKey = row[ "CREDS."+CONNECTION_KEY_COL ].data<std::string>();
684  std::string connectionKey = cipher0.b64decrypt( encryptedConnectionKey );
685  auth::Cipher cipher1( connectionKey );
686  const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL ].data<std::string>();
687  const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL ].data<std::string>();
688  const std::string& verificationKey = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
689  if( cipher1.b64decrypt( verificationKey ) != connLabel ){
690  throwException( "Could not decrypt credentials.Provided key is invalid.",
691  "CredentialStore::startSession");
692  }
693  writeUserName = cipher1.b64decrypt( encryptedUserName );
694  writePassword = cipher1.b64decrypt( encryptedPassword );
695  found = true;
696  }
697  if( ! found ){
698  throwException( "Provided credentials are invalid for write access.",
699  "CredentialStore::openSession");
700  }
701  m_session->transaction().commit();
702  m_session->endUserSession();
703  openSession( connTokens.second, writeUserName, writePassword, false );
704 
705  }
706 }
707 
708 // class public methods
710  m_connection(),
711  m_session(),
712  m_principalId(-1),
713  m_principalKey(""),
714  m_serviceName(""),
715  m_serviceData(nullptr),
716  m_key(){
717 }
718 
720 }
721 
724  const std::string& authPath ){
725  if( serviceName.empty() ){
726  throwException( "Service name has not been provided.","cond::CredentialStore::setUpConnection" );
727  }
728  m_serviceName.clear();
729  m_serviceData = nullptr;
730 
731  if( authPath.empty() ){
732  throwException( "The authentication Path has not been provided.","cond::CredentialStore::setUpForService" );
733  }
734  boost::filesystem::path fullPath( authPath );
735  if(!boost::filesystem::exists(authPath) || !boost::filesystem::is_directory( authPath )){
736  throwException( "Authentication Path is invalid.","cond::CredentialStore::setUpForService" );
737  }
739  fullPath /= file;
740 
741  m_key.init( fullPath.string(), auth::COND_KEY );
742 
743  std::map< std::string, auth::ServiceCredentials >::const_iterator iK = m_key.services().find( serviceName );
744  if( iK == m_key.services().end() ){
745  std::string msg("");
746  msg += "Service \""+serviceName+"\" can't be open with the current key.";
747  throwException( msg,"cond::CredentialStore::setUpConnection" );
748  }
750  m_serviceData = &iK->second;
752 }
753 
756  const std::string& authPath ){
757  coral::IHandle<coral::IRelationalService> relationalService = coral::Context::instance().query<coral::IRelationalService>();
758  if ( ! relationalService.isValid() ){
759  coral::Context::instance().loadComponent("CORAL/Services/RelationalService");
760  relationalService = coral::Context::instance().query<coral::IRelationalService>();
761  }
762  coral::IRelationalDomain& domain = relationalService->domainForConnection( connectionString );
763  std::pair<std::string,std::string> connTokens = domain.decodeUserConnectionString( connectionString );
764  std::string& serviceName = connTokens.first;
765  return setUpForService( serviceName, authPath );
766 }
767 
768 void addSequence( coral::ISchema& schema, const std::string& name ){
769  // Create the entry in the table
770  coral::AttributeList insertData;
771  insertData.extend<std::string>( SEQUENCE_NAME_COL );
772  insertData.extend<int>(SEQUENCE_VALUE_COL);
773  coral::AttributeList::iterator iAttribute = insertData.begin();
774  iAttribute->data< std::string >() = name;
775  ++iAttribute;
776  iAttribute->data< int >() = -1;
777  schema.tableHandle( SEQUENCE_TABLE_NAME ).dataEditor().insertRow( insertData );
778 }
779 
780 bool
781 cond::CredentialStore::createSchema( const std::string& connectionString, const std::string& userName, const std::string& password ) {
782  CSScopedSession session( *this );
783  session.startSuper( connectionString, userName, password );
784 
785  coral::ISchema& schema = m_session->nominalSchema();
786  if(schema.existsTable(COND_AUTHENTICATION_TABLE)) {
787  throwException("Credential database, already exists.","CredentialStore::create");
788  }
789 
790  coral::TableDescription dseq;
791  dseq.setName( SEQUENCE_TABLE_NAME );
792 
793  dseq.insertColumn( SEQUENCE_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>() );
794  dseq.setNotNullConstraint( SEQUENCE_NAME_COL );
795  dseq.insertColumn( SEQUENCE_VALUE_COL,coral::AttributeSpecification::typeNameForType<int>() );
796  dseq.setNotNullConstraint( SEQUENCE_VALUE_COL );
797  dseq.setPrimaryKey( std::vector< std::string >( 1, SEQUENCE_NAME_COL ) );
798  schema.createTable( dseq );
799 
800  int columnSize = 2000;
801 
802  // authentication table
803 
805  coral::TableDescription descr0;
806  descr0.setName( COND_AUTHENTICATION_TABLE );
807  descr0.insertColumn( PRINCIPAL_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
808  descr0.insertColumn( PRINCIPAL_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
809  descr0.insertColumn( VERIFICATION_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
810  descr0.insertColumn( PRINCIPAL_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
811  descr0.insertColumn( ADMIN_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
812  descr0.setNotNullConstraint( PRINCIPAL_ID_COL );
813  descr0.setNotNullConstraint( PRINCIPAL_NAME_COL );
814  descr0.setNotNullConstraint( VERIFICATION_COL );
815  descr0.setNotNullConstraint( PRINCIPAL_KEY_COL );
816  descr0.setNotNullConstraint( ADMIN_KEY_COL );
817  std::vector<std::string> columnsUnique;
818  columnsUnique.push_back( PRINCIPAL_NAME_COL);
819  descr0.setUniqueConstraint( columnsUnique );
820  std::vector<std::string> columnsForIndex;
821  columnsForIndex.push_back(PRINCIPAL_ID_COL);
822  descr0.setPrimaryKey( columnsForIndex );
823  schema.createTable( descr0 );
824 
825  // authorization table
827  coral::TableDescription descr1;
828  descr1.setName( COND_AUTHORIZATION_TABLE );
829  descr1.insertColumn( AUTH_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
830  descr1.insertColumn( P_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
831  descr1.insertColumn( ROLE_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
832  descr1.insertColumn( SCHEMA_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
833  descr1.insertColumn( AUTH_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
834  descr1.insertColumn( C_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
835  descr1.setNotNullConstraint( AUTH_ID_COL );
836  descr1.setNotNullConstraint( P_ID_COL );
837  descr1.setNotNullConstraint( ROLE_COL );
838  descr1.setNotNullConstraint( SCHEMA_COL );
839  descr1.setNotNullConstraint( AUTH_KEY_COL );
840  descr1.setNotNullConstraint( C_ID_COL );
841  columnsUnique.clear();
842  columnsUnique.push_back( P_ID_COL);
843  columnsUnique.push_back( ROLE_COL);
844  columnsUnique.push_back( SCHEMA_COL);
845  descr1.setUniqueConstraint( columnsUnique );
846  columnsForIndex.clear();
847  columnsForIndex.push_back(AUTH_ID_COL);
848  descr1.setPrimaryKey( columnsForIndex );
849  schema.createTable( descr1 );
850 
851  // credential table
853  coral::TableDescription descr2;
854  descr2.setName( COND_CREDENTIAL_TABLE );
855  descr2.insertColumn( CONNECTION_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
856  descr2.insertColumn( CONNECTION_LABEL_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
857  descr2.insertColumn( USERNAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
858  descr2.insertColumn( PASSWORD_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
859  descr2.insertColumn( VERIFICATION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
860  descr2.insertColumn( CONNECTION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(),columnSize,false);
861  descr2.setNotNullConstraint( CONNECTION_ID_COL );
862  descr2.setNotNullConstraint( CONNECTION_LABEL_COL );
863  descr2.setNotNullConstraint( USERNAME_COL );
864  descr2.setNotNullConstraint( PASSWORD_COL );
865  descr2.setNotNullConstraint( VERIFICATION_KEY_COL );
866  descr2.setNotNullConstraint( CONNECTION_KEY_COL );
867  columnsUnique.clear();
868  columnsUnique.push_back( CONNECTION_LABEL_COL);
869  descr2.setUniqueConstraint( columnsUnique );
870  columnsForIndex.clear();
871  columnsForIndex.push_back(CONNECTION_ID_COL);
872  descr2.setPrimaryKey( columnsForIndex );
873  schema.createTable( descr2 );
874 
875  try{
876  schema.tableHandle( COND_AUTHENTICATION_TABLE ).privilegeManager().grantToUser( m_serviceData->userName, coral::ITablePrivilegeManager::Select );
877  schema.tableHandle( COND_AUTHORIZATION_TABLE ).privilegeManager().grantToUser( m_serviceData->userName, coral::ITablePrivilegeManager::Select );
878  schema.tableHandle( COND_CREDENTIAL_TABLE ).privilegeManager().grantToUser( m_serviceData->userName, coral::ITablePrivilegeManager::Select );
879  } catch ( const coral::Exception& e ){
880  std::cout <<"WARNING: Could not grant select access to user "<<m_serviceData->userName<<": ["<<e.what()<<"]"<<std::endl;
881  }
884  auto princData = updatePrincipalData( schema, m_key.principalKey(), m_key.principalName(), m_principalKey, true );
885  std::string credentialAccessLabel = schemaLabel( m_serviceName, userName );
886  auto connParams = updateConnectionData( schema, m_principalKey, credentialAccessLabel, userName, password, true );
887  bool ret = setPermissionData( schema, princData.first, m_principalKey, auth::COND_ADMIN_ROLE, connectionString, connParams.first, connParams.second );
888  session.close();
889  return ret;
890 }
891 
892 bool
893 cond::CredentialStore::drop( const std::string& connectionString, const std::string& userName, const std::string& password ) {
894  CSScopedSession session( *this );
895  session.startSuper( connectionString, userName, password );
896 
897  coral::ISchema& schema = m_session->nominalSchema();
898  schema.dropIfExistsTable( COND_AUTHORIZATION_TABLE );
899  schema.dropIfExistsTable( COND_CREDENTIAL_TABLE );
900  schema.dropIfExistsTable( COND_AUTHENTICATION_TABLE );
901  schema.dropIfExistsTable(SEQUENCE_TABLE_NAME);
902  session.close();
903  return true;
904 }
905 
906 bool cond::CredentialStore::resetAdmin( const std::string& userName, const std::string& password ){
907  if(!m_serviceData){
908  throwException( "The credential store has not been initialized.","cond::CredentialStore::installAdmin" );
909  }
910  const std::string& connectionString = m_serviceData->connectionString;
911 
912  CSScopedSession session( *this );
913  session.startSuper( connectionString, userName, password );
914 
915  coral::ISchema& schema = m_session->nominalSchema();
916  const std::string& principalName = m_key.principalName();
917  const std::string& authenticationKey = m_key.principalKey();
918  PrincipalData princData;
919  if(!selectPrincipal( schema, principalName, princData ) ) {
920  std::string msg("User \"");
921  msg += principalName + "\" has not been found.";
922  throwException(msg,"CredentialStore::resetAdmin");
923  }
924  auth::Cipher cipher0( authenticationKey );
925  m_principalKey = cipher0.b64decrypt( princData.principalKey );
926 
927  auto p = updatePrincipalData( schema, authenticationKey, principalName, m_principalKey );
928  std::string credentialAccessLabel = schemaLabel( m_serviceName, userName );
929  auto connParams = updateConnectionData( schema, m_principalKey, credentialAccessLabel, userName, password, true );
930  bool ret = setPermissionData( schema, p.first, m_principalKey, auth::COND_ADMIN_ROLE, connectionString, connParams.first, connParams.second );
931  session.close();
932  return ret;
933 }
934 
1021  const std::string& authenticationKey,
1022  bool setAdmin ){
1023  CSScopedSession session( *this );
1024  session.start( false );
1025  coral::ISchema& schema = m_session->nominalSchema();
1026  auto princData = updatePrincipalData( schema, m_principalKey, principalName, authenticationKey );
1027  bool ret = false;
1028  if(setAdmin){
1029  int princId = princData.first;
1030  std::string princKey = m_principalKey;
1032  std::vector<Permission> permissions;
1033  if( !selectPermissions( m_key.principalName(), auth::COND_ADMIN_ROLE, connString, permissions ) ){
1034  throwException("The current operating user is not admin user on the underlying Credential Store.","CredentialStore::updatePrincipal");
1035  }
1036  std::string connLabel = permissions.front().connectionLabel;
1037  CredentialData credsData;
1038  if(!selectConnection( schema, connLabel, credsData )){
1039  throwException("Credential Store connection has not been defined.","CredentialStore::updatePrincipal");
1040  }
1041  auth::Cipher adminCipher( m_principalKey );
1042  ret = setPermissionData( schema, princId, princKey, auth::COND_ADMIN_ROLE, connString, credsData.id, adminCipher.b64decrypt( credsData.connectionKey ) );
1043  }
1044  session.close();
1045  return ret;
1046 }
1047 
1049  const std::string& role,
1050  const std::string& connectionString,
1051  const std::string& connectionLabel ){
1052  CSScopedSession session( *this );
1053  session.start( false );
1054 
1055  coral::ISchema& schema = m_session->nominalSchema();
1056 
1057  PrincipalData princData;
1058  bool found = selectPrincipal( schema, principal, princData );
1059 
1060  if( ! found ){
1061  std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1062  throwException( msg, "CredentialStore::setPermission");
1063  }
1064 
1065  CredentialData credsData;
1066  found = selectConnection( schema, connectionLabel, credsData );
1067 
1068  if( ! found ){
1069  std::string msg = "Connection named \"" + connectionLabel + "\" does not exist in the database.";
1070  throwException( msg, "CredentialStore::setPermission");
1071  }
1072 
1073  auth::Cipher cipher( m_principalKey );
1074  bool ret = setPermissionData( schema, princData.id, cipher.b64decrypt( princData.adminKey), role, connectionString, credsData.id, cipher.b64decrypt( credsData.connectionKey ) );
1075  session.close();
1076  return ret;
1077 }
1078 
1080  const std::string& role,
1081  const std::string& connectionString ){
1082  CSScopedSession session( *this );
1083  session.start( false );
1084  coral::ISchema& schema = m_session->nominalSchema();
1085 
1086  PrincipalData princData;
1087  bool found = selectPrincipal( schema, principal, princData );
1088 
1089  if( ! found ){
1090  std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1091  throwException( msg, "CredentialStore::unsetPermission");
1092  }
1093 
1094  coral::ITableDataEditor& editor = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
1095  coral::AttributeList deleteData;
1096  deleteData.extend<int>( P_ID_COL );
1097  deleteData.extend<std::string>( ROLE_COL );
1098  deleteData.extend<std::string>( SCHEMA_COL );
1099  deleteData[ P_ID_COL ].data<int>() = princData.id;
1100  deleteData[ ROLE_COL ].data<std::string>() = role;
1101  deleteData[ SCHEMA_COL ].data<std::string>() = connectionString;
1102  std::stringstream whereClause;
1103  whereClause << P_ID_COL+" = :"+P_ID_COL;
1104  whereClause << " AND "<< ROLE_COL <<" = :"<<ROLE_COL;
1105  whereClause << " AND "<< SCHEMA_COL <<" = :"<<SCHEMA_COL;
1106  editor.deleteRows( whereClause.str(), deleteData );
1107  session.close();
1108  return true;
1109 }
1110 
1112  const std::string& userName,
1113  const std::string& password ){
1114  CSScopedSession session( *this );
1115  session.start( false );
1116 
1117  m_session->transaction().start();
1118  coral::ISchema& schema = m_session->nominalSchema();
1119  updateConnectionData( schema, m_principalKey, connectionLabel, userName, password, true );
1120 
1121  session.close();
1122  return true;
1123 }
1124 
1126  CSScopedSession session( *this );
1127  session.start( false );
1128  coral::ISchema& schema = m_session->nominalSchema();
1129 
1130  PrincipalData princData;
1131  bool found = selectPrincipal( schema, principal, princData );
1132 
1133  if( ! found ){
1134  std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1135  throwException( msg, "CredentialStore::removePrincipal");
1136  }
1137 
1138  coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
1139 
1140  coral::AttributeList deleteData0;
1141  deleteData0.extend<int>( P_ID_COL );
1142  deleteData0[ P_ID_COL ].data<int>() = princData.id;
1143  std::string whereClause0 = P_ID_COL+" = :"+P_ID_COL;
1144  editor0.deleteRows( whereClause0 , deleteData0 );
1145 
1146  coral::ITableDataEditor& editor1 = schema.tableHandle(COND_AUTHENTICATION_TABLE).dataEditor();
1147 
1148  coral::AttributeList deleteData1;
1149  deleteData1.extend<int>( PRINCIPAL_ID_COL );
1150  deleteData1[ PRINCIPAL_ID_COL ].data<int>() = princData.id;
1151  std::string whereClause1 = PRINCIPAL_ID_COL+" = :"+PRINCIPAL_ID_COL;
1152  editor1.deleteRows( whereClause1 , deleteData1 );
1153 
1154  session.close();
1155 
1156  return true;
1157 }
1158 
1160  CSScopedSession session( *this );
1161  session.start( false );
1162  coral::ISchema& schema = m_session->nominalSchema();
1163 
1164  CredentialData credsData;
1165  bool found = selectConnection( schema, connectionLabel, credsData );
1166 
1167  if( ! found ){
1168  std::string msg = "Connection named \"" + connectionLabel + "\" does not exist in the database.";
1169  throwException( msg, "CredentialStore::removeConnection");
1170  }
1171 
1172  coral::ITableDataEditor& editor0 = schema.tableHandle(COND_AUTHORIZATION_TABLE).dataEditor();
1173 
1174  coral::AttributeList deleteData0;
1175  deleteData0.extend<int>( C_ID_COL );
1176  deleteData0[ C_ID_COL ].data<int>() = credsData.id;
1177  std::string whereClause0 = C_ID_COL+" = :"+C_ID_COL;
1178  editor0.deleteRows( whereClause0 , deleteData0 );
1179 
1180  coral::ITableDataEditor& editor1 = schema.tableHandle(COND_CREDENTIAL_TABLE).dataEditor();
1181 
1182  coral::AttributeList deleteData1;
1183  deleteData1.extend<int>( CONNECTION_ID_COL );
1184  deleteData1[ CONNECTION_ID_COL ].data<int>() = credsData.id;
1185  std::string whereClause1 = CONNECTION_ID_COL+" = :"+CONNECTION_ID_COL;
1186  editor1.deleteRows( whereClause1 , deleteData1 );
1187 
1188  session.close();
1189 
1190  return true;
1191 }
1192 
1194  CSScopedSession session( *this );
1195  session.start( true );
1196  coral::ISchema& schema = m_session->nominalSchema();
1197 
1198  auth::Cipher cipher( m_principalKey );
1199 
1200  std::unique_ptr<coral::IQuery> query(schema.newQuery());
1201  query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
1202  query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
1203  coral::AttributeList readBuff;
1204  readBuff.extend<std::string>("AUTHO."+ROLE_COL);
1205  readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
1206  readBuff.extend<std::string>("AUTHO."+AUTH_KEY_COL);
1207  readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
1208  readBuff.extend<std::string>("CREDS."+USERNAME_COL);
1209  readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
1210  readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
1211  coral::AttributeList whereData;
1212  whereData.extend<int>(P_ID_COL);
1213  whereData[ P_ID_COL ].data<int>() = m_principalId;
1214  std::stringstream whereClause;
1215  whereClause << "AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
1216  whereClause << " AND " << "AUTHO."<< P_ID_COL << " = :"<<P_ID_COL;
1217  query->defineOutput(readBuff);
1218  query->addToOutputList( "AUTHO."+ROLE_COL );
1219  query->addToOutputList( "AUTHO."+SCHEMA_COL );
1220  query->addToOutputList( "AUTHO."+AUTH_KEY_COL );
1221  query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
1222  query->addToOutputList( "CREDS."+USERNAME_COL );
1223  query->addToOutputList( "CREDS."+PASSWORD_COL );
1224  query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
1225  query->setCondition( whereClause.str(), whereData );
1226  coral::ICursor& cursor = query->execute();
1227  while ( cursor.next() ) {
1228  const coral::AttributeList& row = cursor.currentRow();
1229  const std::string& role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
1230  const std::string& connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
1231  const std::string& encryptedAuthKey = row[ "AUTHO."+AUTH_KEY_COL ].data<std::string>();
1232  const std::string& connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
1233  const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL ].data<std::string>();
1234  const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL ].data<std::string>();
1235  const std::string& encryptedLabel = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
1236  std::string authKey = cipher.b64decrypt( encryptedAuthKey );
1237  auth::Cipher connCipher( authKey );
1238  if( connCipher.b64decrypt( encryptedLabel ) == connectionLabel ){
1239  destinationData.registerCredentials( connectionString, role, connCipher.b64decrypt( encryptedUserName ), connCipher.b64decrypt( encryptedPassword ) );
1240  }
1241  }
1242  session.close();
1243  return true;
1244 }
1245 
1248  bool forceUpdateConnection ){
1249  CSScopedSession session( *this );
1250  session.start( false );
1251  coral::ISchema& schema = m_session->nominalSchema();
1252 
1253  PrincipalData princData;
1254  bool found = selectPrincipal( schema, principal, princData );
1255 
1256  if( ! found ){
1257  std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1258  throwException( msg, "CredentialStore::importForPrincipal");
1259  }
1260 
1261  bool imported = false;
1262  auth::Cipher cipher( m_principalKey );
1263  std::string princKey = cipher.b64decrypt( princData.adminKey);
1264 
1265  const std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >& creds = dataSource.data();
1266  for( std::map< std::pair<std::string,std::string>, coral::AuthenticationCredentials* >::const_iterator iConn = creds.begin(); iConn != creds.end(); ++iConn ){
1267  const std::string& connectionString = iConn->first.first;
1268  coral::URIParser parser;
1269  parser.setURI( connectionString );
1270  std::string serviceName = parser.hostName();
1271  const std::string& role = iConn->first.second;
1272  std::string userName = iConn->second->valueForItem( coral::IAuthenticationCredentials::userItem() );
1273  std::string password = iConn->second->valueForItem( coral::IAuthenticationCredentials::passwordItem());
1274  // first import the connections
1275  std::pair<int,std::string> conn = updateConnectionData( schema, m_principalKey, schemaLabel( serviceName, userName ), userName, password, forceUpdateConnection );
1276  auth::Cipher cipher( m_principalKey );
1277  // than set the permission for the specific role
1278  setPermissionData( schema, princData.id, princKey, role, connectionString, conn.first, conn.second );
1279  imported = true;
1280  }
1281  session.close();
1282  return imported;
1283 }
1284 
1285 bool cond::CredentialStore::listPrincipals( std::vector<std::string>& destination ){
1286 
1287  CSScopedSession session( *this );
1288  session.start( true );
1289  coral::ISchema& schema = m_session->nominalSchema();
1290 
1291  std::unique_ptr<coral::IQuery> query(schema.tableHandle(COND_AUTHENTICATION_TABLE).newQuery());
1292  coral::AttributeList readBuff;
1293  readBuff.extend<std::string>(PRINCIPAL_NAME_COL);
1294  query->defineOutput(readBuff);
1295  query->addToOutputList( PRINCIPAL_NAME_COL );
1296  coral::ICursor& cursor = query->execute();
1297  bool found = false;
1298  while ( cursor.next() ) {
1299  found = true;
1300  const coral::AttributeList& row = cursor.currentRow();
1301  destination.push_back( row[ PRINCIPAL_NAME_COL ].data<std::string>() );
1302  }
1303  session.close();
1304  return found;
1305 }
1306 
1307 
1308 bool cond::CredentialStore::listConnections( std::map<std::string,std::pair<std::string,std::string> >& destination ){
1309  CSScopedSession session( *this );
1310  session.start( true );
1311  coral::ISchema& schema = m_session->nominalSchema();
1312 
1313  std::unique_ptr<coral::IQuery> query(schema.tableHandle(COND_CREDENTIAL_TABLE).newQuery());
1314  coral::AttributeList readBuff;
1315  readBuff.extend<std::string>( CONNECTION_LABEL_COL );
1316  readBuff.extend<std::string>( USERNAME_COL );
1317  readBuff.extend<std::string>( PASSWORD_COL );
1318  readBuff.extend<std::string>( VERIFICATION_KEY_COL );
1319  readBuff.extend<std::string>( CONNECTION_KEY_COL );
1320  query->defineOutput(readBuff);
1321  query->addToOutputList( CONNECTION_LABEL_COL );
1322  query->addToOutputList( USERNAME_COL );
1323  query->addToOutputList( PASSWORD_COL );
1324  query->addToOutputList( VERIFICATION_KEY_COL );
1325  query->addToOutputList( CONNECTION_KEY_COL );
1326  coral::ICursor& cursor = query->execute();
1327  bool found = false;
1328  auth::Cipher cipher0(m_principalKey );
1329  while ( cursor.next() ) {
1330  std::string userName("");
1331  std::string password("");
1332  const coral::AttributeList& row = cursor.currentRow();
1333  const std::string& connLabel = row[ CONNECTION_LABEL_COL].data<std::string>();
1334  const std::string& encryptedKey = row[ CONNECTION_KEY_COL].data<std::string>();
1335  const std::string& encryptedVerif = row[ VERIFICATION_KEY_COL].data<std::string>();
1336  std::string connKey = cipher0.b64decrypt( encryptedKey );
1337  auth::Cipher cipher1( connKey );
1338  std::string verif = cipher1.b64decrypt( encryptedVerif );
1339  if( verif == connLabel ){
1340  const std::string& encryptedUserName = row[ USERNAME_COL].data<std::string>();
1341  const std::string& encryptedPassword = row[ PASSWORD_COL].data<std::string>();
1342  userName = cipher1.b64decrypt( encryptedUserName );
1343  password = cipher1.b64decrypt( encryptedPassword );
1344  }
1345  destination.insert( std::make_pair( connLabel, std::make_pair( userName, password ) ) );
1346  found = true;
1347  }
1348  session.close();
1349  return found;
1350 }
1351 
1353  const std::string& role,
1354  const std::string& connectionString,
1355  std::vector<Permission>& destination ){
1356  CSScopedSession session( *this );
1357  session.start( true );
1358  coral::ISchema& schema = m_session->nominalSchema();
1359  std::unique_ptr<coral::IQuery> query(schema.newQuery());
1360  query->addToTableList(COND_AUTHENTICATION_TABLE, "AUTHE");
1361  query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
1362  query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
1363  coral::AttributeList readBuff;
1364  readBuff.extend<std::string>("AUTHE."+PRINCIPAL_NAME_COL);
1365  readBuff.extend<std::string>("AUTHO."+ROLE_COL);
1366  readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
1367  readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
1368  coral::AttributeList whereData;
1369  std::stringstream whereClause;
1370  whereClause << "AUTHE."<< PRINCIPAL_ID_COL << "= AUTHO."<< P_ID_COL;
1371  whereClause << " AND AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
1372  if( !principalName.empty() ){
1373  whereData.extend<std::string>(PRINCIPAL_NAME_COL);
1374  whereData[ PRINCIPAL_NAME_COL ].data<std::string>() = principalName;
1375  whereClause << " AND AUTHE."<< PRINCIPAL_NAME_COL <<" = :"<<PRINCIPAL_NAME_COL;
1376  }
1377  if( !role.empty() ){
1378  whereData.extend<std::string>(ROLE_COL);
1379  whereData[ ROLE_COL ].data<std::string>() = role;
1380  whereClause << " AND AUTHO."<< ROLE_COL <<" = :"<<ROLE_COL;
1381  }
1382  if( !connectionString.empty() ){
1383  whereData.extend<std::string>(SCHEMA_COL);
1384  whereData[ SCHEMA_COL ].data<std::string>() = connectionString;
1385  whereClause << " AND AUTHO."<< SCHEMA_COL <<" = :"<<SCHEMA_COL;
1386  }
1387 
1388  query->defineOutput(readBuff);
1389  query->addToOutputList( "AUTHE."+PRINCIPAL_NAME_COL );
1390  query->addToOutputList( "AUTHO."+ROLE_COL );
1391  query->addToOutputList( "AUTHO."+SCHEMA_COL );
1392  query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
1393  query->setCondition( whereClause.str(), whereData );
1394  query->addToOrderList( "AUTHO."+SCHEMA_COL );
1395  query->addToOrderList( "AUTHE."+PRINCIPAL_NAME_COL );
1396  query->addToOrderList( "AUTHO."+ROLE_COL );
1397  coral::ICursor& cursor = query->execute();
1398  bool found = false;
1399  while ( cursor.next() ) {
1400  const coral::AttributeList& row = cursor.currentRow();
1401  destination.resize( destination.size()+1 );
1402  Permission& perm = destination.back();
1403  perm.principalName = row[ "AUTHE."+PRINCIPAL_NAME_COL ].data<std::string>();
1404  perm.role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
1405  perm.connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
1406  perm.connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
1407  found = true;
1408  }
1409  session.close();
1410  return found;
1411 }
1412 
1414  CSScopedSession session( *this );
1415  session.start( true );
1416  coral::ISchema& schema = m_session->nominalSchema();
1417  std::unique_ptr<coral::IQuery> query(schema.newQuery());
1418  query->addToTableList(COND_AUTHORIZATION_TABLE, "AUTHO");
1419  query->addToTableList(COND_CREDENTIAL_TABLE, "CREDS");
1420  coral::AttributeList readBuff;
1421  readBuff.extend<std::string>("AUTHO."+ROLE_COL);
1422  readBuff.extend<std::string>("AUTHO."+SCHEMA_COL);
1423  readBuff.extend<std::string>("CREDS."+CONNECTION_LABEL_COL);
1424  readBuff.extend<std::string>("CREDS."+VERIFICATION_KEY_COL);
1425  readBuff.extend<std::string>("CREDS."+CONNECTION_KEY_COL);
1426  readBuff.extend<std::string>("CREDS."+USERNAME_COL);
1427  readBuff.extend<std::string>("CREDS."+PASSWORD_COL);
1428  coral::AttributeList whereData;
1429  std::stringstream whereClause;
1430  whereClause << "AUTHO."<< C_ID_COL << "="<<"CREDS."<<CONNECTION_ID_COL;
1431 
1432  query->defineOutput(readBuff);
1433  query->addToOutputList( "AUTHO."+ROLE_COL );
1434  query->addToOutputList( "AUTHO."+SCHEMA_COL );
1435  query->addToOutputList( "CREDS."+CONNECTION_LABEL_COL );
1436  query->addToOutputList( "CREDS."+VERIFICATION_KEY_COL );
1437  query->addToOutputList( "CREDS."+CONNECTION_KEY_COL );
1438  query->addToOutputList( "CREDS."+USERNAME_COL );
1439  query->addToOutputList( "CREDS."+PASSWORD_COL );
1440  query->setCondition( whereClause.str(), whereData );
1441  coral::ICursor& cursor = query->execute();
1442  bool found = false;
1443  auth::Cipher cipher0( m_principalKey );
1444  while ( cursor.next() ) {
1445  const coral::AttributeList& row = cursor.currentRow();
1446  const std::string& role = row[ "AUTHO."+ROLE_COL ].data<std::string>();
1447  const std::string& connectionString = row[ "AUTHO."+SCHEMA_COL ].data<std::string>();
1448  const std::string& connectionLabel = row[ "CREDS."+CONNECTION_LABEL_COL ].data<std::string>();
1449  const std::string& encryptedVerifKey = row[ "CREDS."+VERIFICATION_KEY_COL ].data<std::string>();
1450  const std::string& encryptedConnection = row[ "CREDS."+CONNECTION_KEY_COL ].data<std::string>();
1451  std::string userName("");
1452  std::string password("");
1453  std::string connectionKey = cipher0.b64decrypt( encryptedConnection );
1454  auth::Cipher cipher1( connectionKey );
1455  std::string verifKey = cipher1.b64decrypt( encryptedVerifKey );
1456  if( verifKey == connectionLabel ){
1457  const std::string& encryptedUserName = row[ "CREDS."+USERNAME_COL].data<std::string>();
1458  const std::string& encryptedPassword = row[ "CREDS."+PASSWORD_COL].data<std::string>();
1459  userName = cipher1.b64decrypt( encryptedUserName );
1460  password = cipher1.b64decrypt( encryptedPassword );
1461  }
1462  data.registerCredentials( connectionString, role, userName, password );
1463  found = true;
1464  }
1465  session.close();
1466  return found;
1467 }
1468 
1470  return m_key.principalName();
1471 }
1472 
1473 
CSScopedSession(CredentialStore &store)
const std::string & keyPrincipalName()
std::pair< int, std::string > updatePrincipalData(coral::ISchema &schema, const std::string &authenticationKey, const std::string &principalName, const std::string &adminKey, bool init=false)
std::map< std::pair< std::string, std::string >, coral::AuthenticationCredentials * > m_data
credentials for the specific roles
void import(const AuthenticationCredentialSet &data)
static const std::string SEQUENCE_VALUE_COL("VALUE")
std::pair< int, std::string > updateConnectionData(coral::ISchema &schema, const std::string &adminKey, const std::string &connectionLabel, const std::string &userName, const std::string &password, bool forceUpdate)
bool updatePrincipal(const std::string &principal, const std::string &principalKey, bool setAdmin=false)
size_t init(const std::string &keyFileName, const std::string &password, bool readMode=true)
Definition: DecodingKey.cc:109
CredentialStore()
Standard Constructor.
static const std::string ROLE_COL("C_ROLE")
virtual ~AuthenticationCredentialSet()
Destructor.
static PFTauRenderPlugin instance
bool removeConnection(const std::string &connectionLabel)
void openSession(const std::string &schemaName, const std::string &userName, const std::string &password, bool readMode)
const std::map< std::string, ServiceCredentials > & services() const
Definition: DecodingKey.h:131
bool resetAdmin(const std::string &userName, const std::string &password)
static const std::string SCHEMA_COL("C_SCHEMA")
#define nullptr
bool listConnections(std::map< std::string, std::pair< std::string, std::string > > &destination)
bool getNextSequenceValue(coral::ISchema &schema, const std::string &sequenceName, int &value)
void start(bool readOnly=true)
static const std::string COND_AUTHENTICATION_TABLE("COND_AUTHENTICATION")
static const std::string SEQUENCE_TABLE_NAME("COND_CREDENTIAL_SEQUENCE")
static const std::string COND_AUTHORIZATION_TABLE("COND_AUTHORIZATION")
void startSuper(const std::string &connectionString, const std::string &userName, const std::string &password)
static const std::string serviceName
CredentialStore & m_store
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:21
static const std::string PASSWORD_COL("CRED5")
def query(query_str, verbose=False)
Definition: das.py:6
static const std::string COND_CREDENTIAL_TABLE("COND_CREDENTIAL")
void closeSession(bool commit=true)
static const std::string CONNECTION_KEY_COL("CRED7")
Definition: query.py:1
void registerItem(const std::string &connectionString, const std::string &itemName, const std::string &itemValue)
def principal(options)
const std::map< std::pair< std::string, std::string >, coral::AuthenticationCredentials * > & data() const
static const std::string ADMIN_KEY_COL("CRED2")
static const std::string VERIFICATION_KEY_COL("CRED6")
void startSession(bool readMode)
bool updateConnection(const std::string &connectionLabel, const std::string &userName, const std::string &password)
bool createSchema(const std::string &connectionString, const std::string &userName, const std::string &password)
static constexpr const char *const COND_ADMIN_ROLE
Definition: Auth.h:18
bool exportAll(coral_bridge::AuthenticationCredentialSet &data)
std::string schemaLabel(const std::string &serviceName, const std::string &userName)
static constexpr unsigned int COND_DB_KEY_SIZE
Definition: Auth.h:25
bool listPrincipals(std::vector< std::string > &destination)
bool selectConnection(coral::ISchema &schema, const std::string &connectionLabel, CredentialData &destination)
std::string setUpForConnectionString(const std::string &connectionString, const std::string &authPath)
static const std::string VERIFICATION_COL("CRED0")
static const std::string SEQUENCE_NAME_COL("NAME")
const std::string & principalName() const
Definition: DecodingKey.h:107
Definition: value.py:1
std::string setUpForService(const std::string &serviceName, const std::string &authPath)
Sets the initialization parameters.
bool importForPrincipal(const std::string &principal, const coral_bridge::AuthenticationCredentialSet &data, bool forceUpdateConnection=false)
import data
static const std::string USERNAME_COL("CRED4")
def gen(fragment, howMuch)
Production test section ####.
bool selectPrincipal(coral::ISchema &schema, const std::string &principal, PrincipalData &destination)
bool setPermission(const std::string &principal, const std::string &role, const std::string &connectionString, const std::string &connectionLabel)
virtual ~CredentialStore()
Standard Destructor.
std::string schemaLabelForCredentialStore(const std::string &connectionString)
bool selectForUser(coral_bridge::AuthenticationCredentialSet &destinationData)
static const std::string CONNECTION_ID_COL("CONN_ID")
Definition: init.py:1
bool selectAuthorization(coral::ISchema &schema, int principalId, const std::string &role, const std::string &connectionString, AuthorizationData &destination)
bool removePrincipal(const std::string &principal)
auth::DecodingKey m_key
void startSuperSession(const std::string &connectionString, const std::string &userName, const std::string &password)
static const std::string PRINCIPAL_ID_COL("P_ID")
std::string make(size_t keySize)
Definition: DecodingKey.cc:75
tuple msg
Definition: mps_check.py:285
bool selectPermissions(const std::string &principalName, const std::string &role, const std::string &connectionString, std::vector< Permission > &destination)
std::string b64encrypt(const std::string &input)
Definition: Cipher.cc:105
std::shared_ptr< coral::ISession > m_session
static const std::string AUTH_ID_COL("AUTH_ID")
void registerCredentials(const std::string &connectionString, const std::string &userName, const std::string &password)
const std::string DEFAULT_DATA_SOURCE("Cond_Default_Authentication")
std::pair< std::string, std::string > openConnection(const std::string &connectionString)
Definition: plugin.cc:24
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
const coral::IAuthenticationCredentials * get(const std::string &connectionString) const
void addSequence(coral::ISchema &schema, const std::string &name)
bool drop(const std::string &connectionString, const std::string &userName, const std::string &password)
static const std::string PRINCIPAL_KEY_COL("CRED1")
static const std::string P_ID_COL("P_ID")
static constexpr const char *const FILE_PATH
Definition: DecodingKey.h:39
const std::string & principalKey() const
Definition: DecodingKey.h:113
const auth::ServiceCredentials * m_serviceData
static const std::string CONNECTION_LABEL_COL("CONN_LABEL")
void throwException(const std::string &message, const std::string &methodName)
Definition: Exception.cc:14
bool unsetPermission(const std::string &principal, const std::string &role, const std::string &connectionString)
static const std::string C_ID_COL("C_ID")
static constexpr const char *const COND_KEY
Definition: Auth.h:22
std::string b64decrypt(const std::string &input)
Definition: Cipher.cc:117
bool setPermissionData(coral::ISchema &schema, int principalId, const std::string &principalKey, const std::string &role, const std::string &connectionString, int connectionId, const std::string &connectionKey)
static const std::string AUTH_KEY_COL("CRED3")
static constexpr const char *const COND_DEFAULT_ROLE
Definition: Auth.h:15
static const std::string PRINCIPAL_NAME_COL("P_NAME")