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