File indexing completed on 2024-04-06 12:01:26
0001 #include "CondCore/CondDB/interface/CredentialStore.h"
0002 #include "CondCore/CondDB/interface/Cipher.h"
0003 #include "CondCore/CondDB/interface/Exception.h"
0004 #include "CondCore/CondDB/interface/Auth.h"
0005
0006 #include "CoralBase/AttributeList.h"
0007 #include "CoralBase/Attribute.h"
0008 #include "CoralKernel/Context.h"
0009 #include "CoralCommon/URIParser.h"
0010 #include "RelationalAccess/AuthenticationCredentials.h"
0011 #include "RelationalAccess/IBulkOperation.h"
0012 #include "RelationalAccess/IConnection.h"
0013 #include "RelationalAccess/ISession.h"
0014 #include "RelationalAccess/IRelationalService.h"
0015 #include "RelationalAccess/IRelationalDomain.h"
0016 #include "RelationalAccess/ITransaction.h"
0017 #include "RelationalAccess/ISchema.h"
0018 #include "RelationalAccess/ITable.h"
0019 #include "RelationalAccess/TableDescription.h"
0020 #include "RelationalAccess/ITableDataEditor.h"
0021 #include "RelationalAccess/ITablePrivilegeManager.h"
0022 #include "RelationalAccess/IQuery.h"
0023 #include "RelationalAccess/ICursor.h"
0024
0025 #include "RelationalAccess/AuthenticationCredentials.h"
0026
0027 #include <filesystem>
0028 #include <fstream>
0029 #include <sstream>
0030
0031 static const std::string serviceName = "CondAuthenticationService";
0032
0033 coral_bridge::AuthenticationCredentialSet::AuthenticationCredentialSet() : m_data() {}
0034
0035 coral_bridge::AuthenticationCredentialSet::~AuthenticationCredentialSet() { reset(); }
0036
0037 void coral_bridge::AuthenticationCredentialSet::reset() {
0038 for (auto iData = m_data.begin(); iData != m_data.end(); ++iData)
0039 delete iData->second;
0040 m_data.clear();
0041 }
0042
0043 void coral_bridge::AuthenticationCredentialSet::registerItem(const std::string& connectionString,
0044 const std::string& itemName,
0045 const std::string& itemValue) {
0046 registerItem(connectionString, cond::auth::COND_DEFAULT_ROLE, itemName, itemValue);
0047 }
0048
0049 void coral_bridge::AuthenticationCredentialSet::registerItem(const std::string& connectionString,
0050 const std::string& role,
0051 const std::string& itemName,
0052 const std::string& itemValue) {
0053 std::pair<std::string, std::string> connKey(connectionString, role);
0054 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
0055 m_data.find(connKey);
0056 if (iData == m_data.end()) {
0057 iData = m_data.insert(std::make_pair(connKey, new coral::AuthenticationCredentials(serviceName))).first;
0058 }
0059 iData = m_data.insert(std::make_pair(connKey, new coral::AuthenticationCredentials(serviceName))).first;
0060 iData->second->registerItem(itemName, itemValue);
0061 }
0062
0063 void coral_bridge::AuthenticationCredentialSet::registerCredentials(const std::string& connectionString,
0064 const std::string& userName,
0065 const std::string& password) {
0066 registerCredentials(connectionString, cond::auth::COND_DEFAULT_ROLE, userName, password);
0067 }
0068
0069 void coral_bridge::AuthenticationCredentialSet::registerCredentials(const std::string& connectionString,
0070 const std::string& role,
0071 const std::string& userName,
0072 const std::string& password) {
0073 std::pair<std::string, std::string> connKey(connectionString, role);
0074 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::iterator iData =
0075 m_data.find(connKey);
0076 if (iData != m_data.end()) {
0077 delete iData->second;
0078 m_data.erase(connKey);
0079 }
0080 iData = m_data.insert(std::make_pair(connKey, new coral::AuthenticationCredentials(serviceName))).first;
0081 iData->second->registerItem(coral::IAuthenticationCredentials::userItem(), userName);
0082 iData->second->registerItem(coral::IAuthenticationCredentials::passwordItem(), password);
0083 }
0084
0085 void coral_bridge::AuthenticationCredentialSet::import(const AuthenticationCredentialSet& data) {
0086 for (std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iData =
0087 data.m_data.begin();
0088 iData != data.m_data.end();
0089 ++iData) {
0090 registerCredentials(iData->first.first,
0091 iData->first.second,
0092 iData->second->valueForItem(coral::IAuthenticationCredentials::userItem()),
0093 iData->second->valueForItem(coral::IAuthenticationCredentials::passwordItem()));
0094 }
0095 }
0096
0097 const coral::IAuthenticationCredentials* coral_bridge::AuthenticationCredentialSet::get(
0098 const std::string& connectionString) const {
0099 return get(connectionString, cond::auth::COND_DEFAULT_ROLE);
0100 }
0101
0102 const coral::IAuthenticationCredentials* coral_bridge::AuthenticationCredentialSet::get(
0103 const std::string& connectionString, const std::string& role) const {
0104 const coral::IAuthenticationCredentials* ret = nullptr;
0105 std::pair<std::string, std::string> connKey(connectionString, role);
0106 std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iData =
0107 m_data.find(connKey);
0108 if (iData != m_data.end()) {
0109 ret = iData->second;
0110 }
0111 return ret;
0112 }
0113
0114 const std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>&
0115 coral_bridge::AuthenticationCredentialSet::data() const {
0116 return m_data;
0117 }
0118
0119 static const std::string TABLE_PREFIX("DB_");
0120 static const std::string LEGACY_TABLE_PREFIX("COND_");
0121 static const std::string SEQUENCE_TABLE("CREDENTIAL_SEQUENCE");
0122 static const std::string SEQUENCE_NAME_COL("NAME");
0123 static const std::string SEQUENCE_VALUE_COL("VALUE");
0124
0125 static const std::string AUTHENTICATION_TABLE("AUTHENTICATION");
0126 static const std::string PRINCIPAL_ID_COL("P_ID");
0127 static const std::string PRINCIPAL_NAME_COL("P_NAME");
0128 static const std::string VERIFICATION_COL("CRED0");
0129 static const std::string PRINCIPAL_KEY_COL("CRED1");
0130 static const std::string ADMIN_KEY_COL("CRED2");
0131
0132 static const std::string AUTHORIZATION_TABLE("AUTHORIZATION");
0133 static const std::string AUTH_ID_COL("AUTH_ID");
0134 static const std::string P_ID_COL("P_ID");
0135 static const std::string ROLE_COL("C_ROLE");
0136 static const std::string SCHEMA_COL("C_SCHEMA");
0137 static const std::string AUTH_KEY_COL("CRED3");
0138 static const std::string C_ID_COL("C_ID");
0139
0140 static const std::string CREDENTIAL_TABLE("CREDENTIAL");
0141 static const std::string CONNECTION_ID_COL("CONN_ID");
0142 static const std::string CONNECTION_LABEL_COL("CONN_LABEL");
0143 static const std::string USERNAME_COL("CRED4");
0144 static const std::string PASSWORD_COL("CRED5");
0145 static const std::string VERIFICATION_KEY_COL("CRED6");
0146 static const std::string CONNECTION_KEY_COL("CRED7");
0147
0148 const std::string DEFAULT_DATA_SOURCE("Cond_Default_Authentication");
0149
0150 std::string tname(const std::string& tableName, const std::string& schemaVersion) {
0151 std::string prefix(TABLE_PREFIX);
0152 if (schemaVersion.empty())
0153 prefix = LEGACY_TABLE_PREFIX;
0154 return prefix + tableName;
0155 }
0156
0157
0158 namespace cond {
0159
0160 std::string schemaLabel(const std::string& serviceName, const std::string& userName) {
0161 std::string ret = userName;
0162 if (!serviceName.empty()) {
0163 ret += "@" + serviceName;
0164 ret = to_lower(ret);
0165 }
0166 return ret;
0167 }
0168
0169 std::string schemaLabelForCredentialStore(const std::string& connectionString) {
0170 coral::URIParser parser;
0171 parser.setURI(connectionString);
0172 std::string serviceName = parser.hostName();
0173 std::string schemaName = parser.databaseOrSchemaName();
0174 return schemaLabel(serviceName, schemaName);
0175 }
0176
0177 class CSScopedSession {
0178 public:
0179 CSScopedSession(CredentialStore& store) : m_store(store) {}
0180 ~CSScopedSession() { m_store.closeSession(false); }
0181 void startSuper(const std::string& connectionString, const std::string& userName, const std::string& password) {
0182 m_store.startSuperSession(connectionString, userName, password);
0183 }
0184 void start(bool readOnly = true) { m_store.startSession(readOnly); }
0185 void close() { m_store.closeSession(); }
0186
0187 private:
0188 CredentialStore& m_store;
0189 };
0190
0191 struct PrincipalData {
0192 int id;
0193 std::string verifKey;
0194 std::string principalKey;
0195 std::string adminKey;
0196 PrincipalData() : id(-1), verifKey(""), principalKey(""), adminKey("") {}
0197 };
0198 bool selectPrincipal(const std::string& schemaVersion,
0199 coral::ISchema& schema,
0200 const std::string& principal,
0201 PrincipalData& destination) {
0202 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(AUTHENTICATION_TABLE, schemaVersion)).newQuery());
0203 coral::AttributeList readBuff;
0204 readBuff.extend<int>(PRINCIPAL_ID_COL);
0205 readBuff.extend<std::string>(VERIFICATION_COL);
0206 readBuff.extend<std::string>(PRINCIPAL_KEY_COL);
0207 readBuff.extend<std::string>(ADMIN_KEY_COL);
0208 coral::AttributeList whereData;
0209 whereData.extend<std::string>(PRINCIPAL_NAME_COL);
0210 whereData[PRINCIPAL_NAME_COL].data<std::string>() = principal;
0211 std::string whereClause = PRINCIPAL_NAME_COL + " = :" + PRINCIPAL_NAME_COL;
0212 query->defineOutput(readBuff);
0213 query->addToOutputList(PRINCIPAL_ID_COL);
0214 query->addToOutputList(VERIFICATION_COL);
0215 query->addToOutputList(PRINCIPAL_KEY_COL);
0216 query->addToOutputList(ADMIN_KEY_COL);
0217 query->setCondition(whereClause, whereData);
0218 coral::ICursor& cursor = query->execute();
0219 bool found = false;
0220 if (cursor.next()) {
0221 found = true;
0222 const coral::AttributeList& row = cursor.currentRow();
0223 destination.id = row[PRINCIPAL_ID_COL].data<int>();
0224 destination.verifKey = row[VERIFICATION_COL].data<std::string>();
0225 destination.principalKey = row[PRINCIPAL_KEY_COL].data<std::string>();
0226 destination.adminKey = row[ADMIN_KEY_COL].data<std::string>();
0227 }
0228 return found;
0229 }
0230
0231 struct CredentialData {
0232 int id;
0233 std::string userName;
0234 std::string password;
0235 std::string connectionKey;
0236 std::string verificationKey;
0237 CredentialData() : id(-1), userName(""), password(""), connectionKey("") {}
0238 };
0239
0240 bool selectConnection(const std::string& schemaVersion,
0241 coral::ISchema& schema,
0242 const std::string& connectionLabel,
0243 CredentialData& destination) {
0244 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(CREDENTIAL_TABLE, schemaVersion)).newQuery());
0245 coral::AttributeList readBuff;
0246 readBuff.extend<int>(CONNECTION_ID_COL);
0247 readBuff.extend<std::string>(USERNAME_COL);
0248 readBuff.extend<std::string>(PASSWORD_COL);
0249 readBuff.extend<std::string>(VERIFICATION_KEY_COL);
0250 readBuff.extend<std::string>(CONNECTION_KEY_COL);
0251 coral::AttributeList whereData;
0252 whereData.extend<std::string>(CONNECTION_LABEL_COL);
0253 whereData[CONNECTION_LABEL_COL].data<std::string>() = connectionLabel;
0254 std::string whereClause = CONNECTION_LABEL_COL + " = :" + CONNECTION_LABEL_COL;
0255 query->defineOutput(readBuff);
0256 query->addToOutputList(CONNECTION_ID_COL);
0257 query->addToOutputList(USERNAME_COL);
0258 query->addToOutputList(PASSWORD_COL);
0259 query->addToOutputList(VERIFICATION_KEY_COL);
0260 query->addToOutputList(CONNECTION_KEY_COL);
0261 query->setCondition(whereClause, whereData);
0262 coral::ICursor& cursor = query->execute();
0263 bool found = false;
0264 if (cursor.next()) {
0265 const coral::AttributeList& row = cursor.currentRow();
0266 destination.id = row[CONNECTION_ID_COL].data<int>();
0267 destination.userName = row[USERNAME_COL].data<std::string>();
0268 destination.password = row[PASSWORD_COL].data<std::string>();
0269 destination.verificationKey = row[VERIFICATION_KEY_COL].data<std::string>();
0270 destination.connectionKey = row[CONNECTION_KEY_COL].data<std::string>();
0271 found = true;
0272 }
0273 return found;
0274 }
0275
0276 struct AuthorizationData {
0277 int id;
0278 int connectionId;
0279 std::string key;
0280 AuthorizationData() : id(-1), connectionId(-1), key("") {}
0281 };
0282
0283 bool selectAuthorization(const std::string& schemaVersion,
0284 coral::ISchema& schema,
0285 int principalId,
0286 const std::string& role,
0287 const std::string& connectionString,
0288 AuthorizationData& destination) {
0289 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(AUTHORIZATION_TABLE, schemaVersion)).newQuery());
0290 coral::AttributeList readBuff;
0291 readBuff.extend<int>(AUTH_ID_COL);
0292 readBuff.extend<int>(C_ID_COL);
0293 readBuff.extend<std::string>(AUTH_KEY_COL);
0294 coral::AttributeList whereData;
0295 whereData.extend<int>(P_ID_COL);
0296 whereData.extend<std::string>(ROLE_COL);
0297 whereData.extend<std::string>(SCHEMA_COL);
0298 whereData[P_ID_COL].data<int>() = principalId;
0299 whereData[ROLE_COL].data<std::string>() = role;
0300 whereData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
0301 std::stringstream whereClause;
0302 whereClause << P_ID_COL << " = :" << P_ID_COL;
0303 whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
0304 whereClause << " AND " << SCHEMA_COL << " = :" << SCHEMA_COL;
0305 query->defineOutput(readBuff);
0306 query->addToOutputList(AUTH_ID_COL);
0307 query->addToOutputList(C_ID_COL);
0308 query->addToOutputList(AUTH_KEY_COL);
0309 query->setCondition(whereClause.str(), whereData);
0310 coral::ICursor& cursor = query->execute();
0311 bool found = false;
0312 if (cursor.next()) {
0313 const coral::AttributeList& row = cursor.currentRow();
0314 destination.id = row[AUTH_ID_COL].data<int>();
0315 destination.connectionId = row[C_ID_COL].data<int>();
0316 destination.key = row[AUTH_KEY_COL].data<std::string>();
0317 found = true;
0318 }
0319 return found;
0320 }
0321
0322 size_t getAuthorizationEntries(const std::string& schemaVersion,
0323 coral::ISchema& schema,
0324 int principalId,
0325 const std::string& role,
0326 const std::string& connectionString) {
0327 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(AUTHORIZATION_TABLE, schemaVersion)).newQuery());
0328 coral::AttributeList readBuff;
0329 readBuff.extend<int>(AUTH_ID_COL);
0330 coral::AttributeList whereData;
0331 whereData.extend<std::string>(SCHEMA_COL);
0332 std::stringstream whereClause;
0333 whereClause << SCHEMA_COL << " = :" << SCHEMA_COL;
0334 if (principalId >= 0) {
0335 whereData.extend<int>(P_ID_COL);
0336 whereClause << "AND" << P_ID_COL << " = :" << P_ID_COL;
0337 }
0338 if (!role.empty()) {
0339 whereData.extend<std::string>(ROLE_COL);
0340 whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
0341 }
0342 whereData[SCHEMA_COL].data<std::string>() = connectionString;
0343 if (principalId >= 0)
0344 whereData[P_ID_COL].data<int>() = principalId;
0345 if (!role.empty())
0346 whereData[ROLE_COL].data<std::string>() = role;
0347 query->defineOutput(readBuff);
0348 query->addToOutputList(AUTH_ID_COL);
0349 query->setCondition(whereClause.str(), whereData);
0350 coral::ICursor& cursor = query->execute();
0351 size_t n_entries = 0;
0352 while (cursor.next()) {
0353 n_entries += 1;
0354 }
0355 return n_entries;
0356 }
0357
0358 bool getNextSequenceValue(const std::string& schemaVersion,
0359 coral::ISchema& schema,
0360 const std::string& sequenceName,
0361 int& value) {
0362 bool ret = false;
0363 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(SEQUENCE_TABLE, schemaVersion)).newQuery());
0364 query->limitReturnedRows(1, 0);
0365 query->addToOutputList(SEQUENCE_VALUE_COL);
0366 query->defineOutputType(SEQUENCE_VALUE_COL, coral::AttributeSpecification::typeNameForType<int>());
0367 query->setForUpdate();
0368 std::string whereClause(SEQUENCE_NAME_COL + " = :" + SEQUENCE_NAME_COL);
0369 coral::AttributeList rowData;
0370 rowData.extend<std::string>(SEQUENCE_NAME_COL);
0371 rowData.begin()->data<std::string>() = sequenceName;
0372 query->setCondition(whereClause, rowData);
0373 coral::ICursor& cursor = query->execute();
0374 if (cursor.next()) {
0375 value = cursor.currentRow().begin()->data<int>() + 1;
0376 ret = true;
0377 } else {
0378 return false;
0379 }
0380
0381 coral::AttributeList updateData;
0382 updateData.extend<std::string>(SEQUENCE_NAME_COL);
0383 updateData.extend<int>(SEQUENCE_VALUE_COL);
0384 std::string setClause(SEQUENCE_VALUE_COL + " = :" + SEQUENCE_VALUE_COL);
0385 std::string whClause(SEQUENCE_NAME_COL + " = :" + SEQUENCE_NAME_COL);
0386 coral::AttributeList::iterator iAttribute = updateData.begin();
0387 iAttribute->data<std::string>() = sequenceName;
0388 ++iAttribute;
0389 iAttribute->data<int>() = value;
0390 schema.tableHandle(tname(SEQUENCE_TABLE, schemaVersion)).dataEditor().updateRows(setClause, whClause, updateData);
0391 return ret;
0392 }
0393
0394 std::pair<int, std::string> updatePrincipalData(const std::string& schemaVersion,
0395 coral::ISchema& schema,
0396 const std::string& authenticationKey,
0397 const std::string& principalName,
0398 const std::string& adminKey,
0399 bool init ,
0400 std::stringstream& log) {
0401 PrincipalData princData;
0402 bool found = selectPrincipal(schemaVersion, schema, principalName, princData);
0403
0404 auth::Cipher cipher0(authenticationKey);
0405 auth::Cipher cipher1(adminKey);
0406
0407 std::string verifStr = cipher0.b64encrypt(principalName);
0408 std::string principalKey("");
0409 int principalId = princData.id;
0410
0411 std::string authentication_table_name = tname(AUTHENTICATION_TABLE, schemaVersion);
0412
0413 coral::ITableDataEditor& editor = schema.tableHandle(authentication_table_name).dataEditor();
0414 if (found) {
0415 log << "Updating existing principal " << principalName << " (id: " << principalId << " )" << std::endl;
0416 principalKey = cipher1.b64decrypt(princData.adminKey);
0417 coral::AttributeList updateData;
0418 updateData.extend<int>(PRINCIPAL_ID_COL);
0419 updateData.extend<std::string>(VERIFICATION_COL);
0420 updateData.extend<std::string>(PRINCIPAL_KEY_COL);
0421 updateData.extend<std::string>(ADMIN_KEY_COL);
0422 updateData[PRINCIPAL_ID_COL].data<int>() = principalId;
0423 updateData[VERIFICATION_COL].data<std::string>() = verifStr;
0424 updateData[PRINCIPAL_KEY_COL].data<std::string>() = cipher0.b64encrypt(principalKey);
0425 updateData[ADMIN_KEY_COL].data<std::string>() = cipher1.b64encrypt(principalKey);
0426 std::stringstream setClause;
0427 setClause << VERIFICATION_COL << " = :" << VERIFICATION_COL << ", ";
0428 setClause << PRINCIPAL_KEY_COL << " = :" << PRINCIPAL_KEY_COL << ", ";
0429 setClause << ADMIN_KEY_COL << " = :" << ADMIN_KEY_COL;
0430 std::string whereClause = PRINCIPAL_ID_COL + " = :" + PRINCIPAL_ID_COL;
0431 editor.updateRows(setClause.str(), whereClause, updateData);
0432 } else {
0433 if (init) {
0434 principalKey = adminKey;
0435 } else {
0436 auth::KeyGenerator gen;
0437 principalKey = gen.make(auth::COND_DB_KEY_SIZE);
0438 }
0439 coral::ITableDataEditor& editor0 = schema.tableHandle(authentication_table_name).dataEditor();
0440
0441 if (!getNextSequenceValue(schemaVersion, schema, authentication_table_name, principalId))
0442 throwException("Can't find " + authentication_table_name + " sequence.", "CredentialStore::updatePrincipal");
0443 log << "Creating new principal " << principalName << " (id: " << principalId << " )" << std::endl;
0444 coral::AttributeList authData;
0445 editor0.rowBuffer(authData);
0446 authData[PRINCIPAL_ID_COL].data<int>() = principalId;
0447 authData[PRINCIPAL_NAME_COL].data<std::string>() = principalName;
0448 authData[VERIFICATION_COL].data<std::string>() = verifStr;
0449 authData[PRINCIPAL_KEY_COL].data<std::string>() = cipher0.b64encrypt(principalKey);
0450 authData[ADMIN_KEY_COL].data<std::string>() = cipher1.b64encrypt(principalKey);
0451 editor0.insertRow(authData);
0452 }
0453
0454 return std::make_pair(principalId, principalKey);
0455 }
0456
0457 bool setPermissionData(const std::string& schemaVersion,
0458 coral::ISchema& schema,
0459 int principalId,
0460 const std::string& principalKey,
0461 const std::string& role,
0462 const std::string& connectionString,
0463 int connectionId,
0464 const std::string& connectionKey,
0465 std::stringstream& log) {
0466 if (cond::auth::ROLES.find(role) == cond::auth::ROLES.end()) {
0467 throwException(std::string("Role ") + role + " does not exists.", "CredentialStore::setPermission");
0468 }
0469 auth::Cipher cipher(principalKey);
0470 std::string encryptedConnectionKey = cipher.b64encrypt(connectionKey);
0471 AuthorizationData authData;
0472 bool found = selectAuthorization(schemaVersion, schema, principalId, role, connectionString, authData);
0473
0474 std::string authorization_table_name = tname(AUTHORIZATION_TABLE, schemaVersion);
0475 coral::ITableDataEditor& editor = schema.tableHandle(authorization_table_name).dataEditor();
0476 if (found) {
0477 log << "Updating permission for principal id " << principalId << " to access resource " << connectionString
0478 << " with role " << role << std::endl;
0479 coral::AttributeList updateData;
0480 updateData.extend<int>(AUTH_ID_COL);
0481 updateData.extend<int>(C_ID_COL);
0482 updateData.extend<std::string>(AUTH_KEY_COL);
0483 updateData[AUTH_ID_COL].data<int>() = authData.id;
0484 updateData[C_ID_COL].data<int>() = connectionId;
0485 updateData[AUTH_KEY_COL].data<std::string>() = encryptedConnectionKey;
0486 std::string setCl = C_ID_COL + " = :" + C_ID_COL + ", " + AUTH_KEY_COL + " = :" + AUTH_KEY_COL;
0487 std::string whereCl = AUTH_ID_COL + " = :" + AUTH_ID_COL;
0488 editor.updateRows(setCl, whereCl, updateData);
0489 } else {
0490 int next = -1;
0491 if (!getNextSequenceValue(schemaVersion, schema, authorization_table_name, next))
0492 throwException("Can't find " + authorization_table_name + " sequence.", "CredentialStore::setPermission");
0493 log << "Setting permission for principal id " << principalId << " to access resource " << connectionString
0494 << " with role " << role << std::endl;
0495 coral::AttributeList insertData;
0496 insertData.extend<int>(AUTH_ID_COL);
0497 insertData.extend<int>(P_ID_COL);
0498 insertData.extend<std::string>(ROLE_COL);
0499 insertData.extend<std::string>(SCHEMA_COL);
0500 insertData.extend<std::string>(AUTH_KEY_COL);
0501 insertData.extend<int>(C_ID_COL);
0502 insertData[AUTH_ID_COL].data<int>() = next;
0503 insertData[P_ID_COL].data<int>() = principalId;
0504 insertData[ROLE_COL].data<std::string>() = role;
0505 insertData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
0506 insertData[AUTH_KEY_COL].data<std::string>() = encryptedConnectionKey;
0507 insertData[C_ID_COL].data<int>() = connectionId;
0508 editor.insertRow(insertData);
0509 }
0510 return true;
0511 }
0512
0513 std::pair<int, std::string> updateConnectionData(const std::string& schemaVersion,
0514 coral::ISchema& schema,
0515 const std::string& adminKey,
0516 const std::string& connectionLabel,
0517 const std::string& userName,
0518 const std::string& password,
0519 bool forceUpdate,
0520 std::stringstream& log) {
0521 CredentialData credsData;
0522 bool found = selectConnection(schemaVersion, schema, connectionLabel, credsData);
0523 int connId = credsData.id;
0524
0525 auth::Cipher adminCipher(adminKey);
0526 std::string connectionKey("");
0527 std::string credential_table_name = tname(CREDENTIAL_TABLE, schemaVersion);
0528 coral::ITableDataEditor& editor = schema.tableHandle(credential_table_name).dataEditor();
0529 if (found) {
0530 connectionKey = adminCipher.b64decrypt(credsData.connectionKey);
0531 auth::Cipher cipher(connectionKey);
0532 std::string verificationKey = cipher.b64decrypt(credsData.verificationKey);
0533 if (verificationKey != connectionLabel) {
0534 throwException("Decoding of connection key failed.", "CredentialStore::updateConnection");
0535 }
0536 if (forceUpdate) {
0537 std::string encryptedUserName = cipher.b64encrypt(userName);
0538 std::string encryptedPassword = cipher.b64encrypt(password);
0539 log << "Forcing update of connection " << connectionLabel << std::endl;
0540 coral::AttributeList updateData;
0541 updateData.extend<int>(CONNECTION_ID_COL);
0542 updateData.extend<std::string>(USERNAME_COL);
0543 updateData.extend<std::string>(PASSWORD_COL);
0544 updateData[CONNECTION_ID_COL].data<int>() = connId;
0545 updateData[USERNAME_COL].data<std::string>() = encryptedUserName;
0546 updateData[PASSWORD_COL].data<std::string>() = encryptedPassword;
0547 std::stringstream setCl;
0548 setCl << USERNAME_COL << " = :" << USERNAME_COL;
0549 setCl << ", " << PASSWORD_COL << " = :" << PASSWORD_COL;
0550 std::string whereCl = CONNECTION_ID_COL + " = :" + CONNECTION_ID_COL;
0551 editor.updateRows(setCl.str(), whereCl, updateData);
0552 }
0553 } else {
0554 auth::KeyGenerator gen;
0555 connectionKey = gen.make(auth::COND_DB_KEY_SIZE);
0556 auth::Cipher cipher(connectionKey);
0557 std::string encryptedUserName = cipher.b64encrypt(userName);
0558 std::string encryptedPassword = cipher.b64encrypt(password);
0559 std::string encryptedLabel = cipher.b64encrypt(connectionLabel);
0560
0561 if (!getNextSequenceValue(schemaVersion, schema, credential_table_name, connId))
0562 throwException("Can't find " + credential_table_name + " sequence.", "CredentialStore::updateConnection");
0563 log << "Creating new connection " << connectionLabel << std::endl;
0564 coral::AttributeList insertData;
0565 insertData.extend<int>(CONNECTION_ID_COL);
0566 insertData.extend<std::string>(CONNECTION_LABEL_COL);
0567 insertData.extend<std::string>(USERNAME_COL);
0568 insertData.extend<std::string>(PASSWORD_COL);
0569 insertData.extend<std::string>(VERIFICATION_KEY_COL);
0570 insertData.extend<std::string>(CONNECTION_KEY_COL);
0571 insertData[CONNECTION_ID_COL].data<int>() = connId;
0572 insertData[CONNECTION_LABEL_COL].data<std::string>() = connectionLabel;
0573 insertData[USERNAME_COL].data<std::string>() = encryptedUserName;
0574 insertData[PASSWORD_COL].data<std::string>() = encryptedPassword;
0575 insertData[VERIFICATION_KEY_COL].data<std::string>() = encryptedLabel;
0576 insertData[CONNECTION_KEY_COL].data<std::string>() = adminCipher.b64encrypt(connectionKey);
0577 ;
0578 editor.insertRow(insertData);
0579 }
0580 return std::make_pair(connId, connectionKey);
0581 }
0582
0583 }
0584
0585
0586 void cond::CredentialStore::closeSession(bool commit) {
0587 if (m_session.get()) {
0588 if (m_session->transaction().isActive()) {
0589 if (commit) {
0590 m_session->transaction().commit();
0591 } else {
0592 m_session->transaction().rollback();
0593 }
0594 }
0595 m_session->endUserSession();
0596 }
0597 m_session.reset();
0598 if (m_connection.get()) {
0599 m_connection->disconnect();
0600 }
0601 m_connection.reset();
0602 m_log << "Session has been closed." << std::endl;
0603 }
0604
0605 std::pair<std::string, std::string> cond::CredentialStore::openConnection(const std::string& connectionString) {
0606 coral::IHandle<coral::IRelationalService> relationalService =
0607 coral::Context::instance().query<coral::IRelationalService>();
0608 if (!relationalService.isValid()) {
0609 coral::Context::instance().loadComponent("CORAL/Services/RelationalService");
0610 relationalService = coral::Context::instance().query<coral::IRelationalService>();
0611 }
0612 coral::IRelationalDomain& domain = relationalService->domainForConnection(connectionString);
0613 std::pair<std::string, std::string> connTokens = domain.decodeUserConnectionString(connectionString);
0614 m_connection.reset(domain.newConnection(connTokens.first));
0615 m_connection->connect();
0616 return connTokens;
0617 }
0618
0619 void cond::CredentialStore::openSession(const std::string& schemaName,
0620 const std::string& userName,
0621 const std::string& password,
0622 bool readMode) {
0623 coral::AccessMode accessMode = coral::ReadOnly;
0624 if (!readMode)
0625 accessMode = coral::Update;
0626 m_session.reset(m_connection->newSession(schemaName, accessMode));
0627 m_session->startUserSession(userName, password);
0628
0629 m_session->transaction().start(readMode);
0630 m_log << "New session opened." << std::endl;
0631 }
0632
0633 void cond::CredentialStore::startSuperSession(const std::string& connectionString,
0634 const std::string& userName,
0635 const std::string& password) {
0636 std::pair<std::string, std::string> connTokens = openConnection(connectionString);
0637 openSession(connTokens.second, userName, password, false);
0638 }
0639
0640
0641 void cond::CredentialStore::startSession(bool readMode) {
0642 if (!m_serviceData) {
0643 throwException("The credential store has not been initialized.", "cond::CredentialStore::openConnection");
0644 }
0645 const std::string& storeConnectionString = m_serviceData->connectionString;
0646
0647 std::pair<std::string, std::string> connTokens = openConnection(storeConnectionString);
0648
0649 const std::string& userName = m_serviceData->userName;
0650 const std::string& password = m_serviceData->password;
0651
0652 openSession(connTokens.second, userName, password, true);
0653
0654 coral::ISchema& schema = m_session->nominalSchema();
0655 const std::string& schemaVersion = m_key.version();
0656 if (!schema.existsTable(tname(AUTHENTICATION_TABLE, schemaVersion)) ||
0657 !schema.existsTable(tname(AUTHORIZATION_TABLE, schemaVersion)) ||
0658 !schema.existsTable(tname(CREDENTIAL_TABLE, schemaVersion))) {
0659 throwException("Credential database does not exists in \"" + storeConnectionString + "\"",
0660 "CredentialStore::startSession");
0661 }
0662
0663 const std::string& principalName = m_key.principalName();
0664
0665 PrincipalData princData;
0666 if (!selectPrincipal(schemaVersion, m_session->nominalSchema(), principalName, princData)) {
0667 throwException("Invalid credentials provided.(0)", "CredentialStore::startSession");
0668 }
0669 auth::Cipher cipher0(m_key.principalKey());
0670 std::string verifStr = cipher0.b64decrypt(princData.verifKey);
0671 if (verifStr != principalName) {
0672 throwException("Invalid credentials provided (1)", "CredentialStore::startSession");
0673 }
0674
0675 m_principalId = princData.id;
0676 m_principalKey = cipher0.b64decrypt(princData.principalKey);
0677 m_authenticatedPrincipal = m_key.principalName();
0678
0679 if (!readMode) {
0680 auth::Cipher cipher0(m_principalKey);
0681 std::string adminKey = cipher0.b64decrypt(princData.adminKey);
0682 if (adminKey != m_principalKey) {
0683
0684 throwException("Provided credentials does not allow admin operation.", "CredentialStore::openSession");
0685 }
0686
0687
0688 std::unique_ptr<coral::IQuery> query(schema.newQuery());
0689 query->addToTableList(tname(AUTHORIZATION_TABLE, schemaVersion), "AUTHO");
0690 query->addToTableList(tname(CREDENTIAL_TABLE, schemaVersion), "CREDS");
0691 coral::AttributeList readBuff;
0692 readBuff.extend<std::string>("CREDS." + CONNECTION_LABEL_COL);
0693 readBuff.extend<std::string>("CREDS." + CONNECTION_KEY_COL);
0694 readBuff.extend<std::string>("CREDS." + USERNAME_COL);
0695 readBuff.extend<std::string>("CREDS." + PASSWORD_COL);
0696 readBuff.extend<std::string>("CREDS." + VERIFICATION_KEY_COL);
0697 coral::AttributeList whereData;
0698 whereData.extend<int>(P_ID_COL);
0699 whereData.extend<std::string>(ROLE_COL);
0700 whereData.extend<std::string>(SCHEMA_COL);
0701 whereData[P_ID_COL].data<int>() = m_principalId;
0702 whereData[ROLE_COL].data<std::string>() = auth::COND_ADMIN_ROLE;
0703 whereData[SCHEMA_COL].data<std::string>() = storeConnectionString;
0704 std::stringstream whereClause;
0705 whereClause << "AUTHO." << C_ID_COL << " = CREDS." << CONNECTION_ID_COL;
0706 whereClause << " AND AUTHO." << P_ID_COL << " = :" << P_ID_COL;
0707 whereClause << " AND AUTHO." << ROLE_COL << " = :" << ROLE_COL;
0708 whereClause << " AND AUTHO." << SCHEMA_COL << " = :" << SCHEMA_COL;
0709 query->defineOutput(readBuff);
0710 query->addToOutputList("CREDS." + CONNECTION_LABEL_COL);
0711 query->addToOutputList("CREDS." + CONNECTION_KEY_COL);
0712 query->addToOutputList("CREDS." + USERNAME_COL);
0713 query->addToOutputList("CREDS." + PASSWORD_COL);
0714 query->addToOutputList("CREDS." + VERIFICATION_KEY_COL);
0715 query->setCondition(whereClause.str(), whereData);
0716 coral::ICursor& cursor = query->execute();
0717 bool found = false;
0718 std::string writeUserName("");
0719 std::string writePassword("");
0720 if (cursor.next()) {
0721 const coral::AttributeList& row = cursor.currentRow();
0722 const std::string& connLabel = row["CREDS." + CONNECTION_LABEL_COL].data<std::string>();
0723 const std::string& encryptedConnectionKey = row["CREDS." + CONNECTION_KEY_COL].data<std::string>();
0724 std::string connectionKey = cipher0.b64decrypt(encryptedConnectionKey);
0725 auth::Cipher cipher1(connectionKey);
0726 const std::string& encryptedUserName = row["CREDS." + USERNAME_COL].data<std::string>();
0727 const std::string& encryptedPassword = row["CREDS." + PASSWORD_COL].data<std::string>();
0728 std::string verificationKey = cipher1.b64decrypt(row["CREDS." + VERIFICATION_KEY_COL].data<std::string>());
0729 if (verificationKey != connLabel) {
0730 throwException("Could not decrypt credentials.Provided key is invalid.", "CredentialStore::startSession");
0731 }
0732 writeUserName = cipher1.b64decrypt(encryptedUserName);
0733 writePassword = cipher1.b64decrypt(encryptedPassword);
0734 found = true;
0735 }
0736 if (!found) {
0737 throwException("Provided credentials are invalid for write access.", "CredentialStore::openSession");
0738 }
0739 m_session->transaction().commit();
0740 m_session->endUserSession();
0741 openSession(connTokens.second, writeUserName, writePassword, false);
0742 }
0743 }
0744
0745
0746 cond::CredentialStore::CredentialStore()
0747 : m_connection(),
0748 m_session(),
0749 m_authenticatedPrincipal(""),
0750 m_principalId(-1),
0751 m_principalKey(""),
0752 m_serviceName(""),
0753 m_serviceData(nullptr),
0754 m_key(),
0755 m_log() {}
0756
0757 cond::CredentialStore::~CredentialStore() {}
0758
0759 std::string cond::CredentialStore::setUpForService(const std::string& serviceName, const std::string& authPath) {
0760 if (serviceName.empty()) {
0761 throwException("Service name has not been provided.", "cond::CredentialStore::setUpConnection");
0762 }
0763 m_serviceName.clear();
0764 m_serviceData = nullptr;
0765
0766 if (authPath.empty()) {
0767 throwException("The authentication Path has not been provided.", "cond::CredentialStore::setUpForService");
0768 }
0769 std::filesystem::path fullPath(authPath);
0770 if (!std::filesystem::exists(authPath) || !std::filesystem::is_directory(authPath)) {
0771 throwException("Authentication Path is invalid.", "cond::CredentialStore::setUpForService");
0772 }
0773 std::filesystem::path file(auth::DecodingKey::FILE_PATH);
0774 fullPath /= file;
0775
0776 m_key.init(fullPath.string(), auth::COND_KEY);
0777
0778 std::map<std::string, auth::ServiceCredentials>::const_iterator iK = m_key.services().find(serviceName);
0779 if (iK == m_key.services().end()) {
0780 std::string msg("");
0781 msg += "Service \"" + serviceName + "\" can't be open with the current key.";
0782 throwException(msg, "cond::CredentialStore::setUpConnection");
0783 }
0784 m_serviceName = serviceName;
0785 m_serviceData = &iK->second;
0786 m_log << "Opening Credential Store for service " << m_serviceName << " on " << m_serviceData->connectionString
0787 << std::endl;
0788 return m_serviceData->connectionString;
0789 }
0790
0791 std::string cond::CredentialStore::setUpForConnectionString(const std::string& connectionString,
0792 const std::string& authPath) {
0793 coral::IHandle<coral::IRelationalService> relationalService =
0794 coral::Context::instance().query<coral::IRelationalService>();
0795 if (!relationalService.isValid()) {
0796 coral::Context::instance().loadComponent("CORAL/Services/RelationalService");
0797 relationalService = coral::Context::instance().query<coral::IRelationalService>();
0798 }
0799 coral::IRelationalDomain& domain = relationalService->domainForConnection(connectionString);
0800 std::pair<std::string, std::string> connTokens = domain.decodeUserConnectionString(connectionString);
0801 std::string& serviceName = connTokens.first;
0802 return setUpForService(serviceName, authPath);
0803 }
0804
0805 void addSequence(const std::string& schemaVersion, coral::ISchema& schema, const std::string& name) {
0806
0807 coral::AttributeList insertData;
0808 insertData.extend<std::string>(SEQUENCE_NAME_COL);
0809 insertData.extend<int>(SEQUENCE_VALUE_COL);
0810 coral::AttributeList::iterator iAttribute = insertData.begin();
0811 iAttribute->data<std::string>() = name;
0812 ++iAttribute;
0813 iAttribute->data<int>() = -1;
0814 schema.tableHandle(tname(SEQUENCE_TABLE, schemaVersion)).dataEditor().insertRow(insertData);
0815 }
0816
0817 bool cond::CredentialStore::createSchema(const std::string& connectionString,
0818 const std::string& userName,
0819 const std::string& password) {
0820 CSScopedSession session(*this);
0821 session.startSuper(connectionString, userName, password);
0822
0823 coral::ISchema& schema = m_session->nominalSchema();
0824 std::string authentication_table_name = tname(AUTHENTICATION_TABLE, m_key.version());
0825 if (schema.existsTable(authentication_table_name)) {
0826 throwException("Credential database, already exists.", "CredentialStore::create");
0827 }
0828
0829 m_log << "Creating sequence table." << std::endl;
0830 std::string sequence_table_name = tname(SEQUENCE_TABLE, m_key.version());
0831 coral::TableDescription dseq;
0832 dseq.setName(sequence_table_name);
0833 dseq.insertColumn(SEQUENCE_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>());
0834 dseq.setNotNullConstraint(SEQUENCE_NAME_COL);
0835 dseq.insertColumn(SEQUENCE_VALUE_COL, coral::AttributeSpecification::typeNameForType<int>());
0836 dseq.setNotNullConstraint(SEQUENCE_VALUE_COL);
0837 dseq.setPrimaryKey(std::vector<std::string>(1, SEQUENCE_NAME_COL));
0838 schema.createTable(dseq);
0839
0840 int columnSize = 2000;
0841
0842 m_log << "Creating authentication table." << std::endl;
0843
0844 addSequence(m_key.version(), schema, authentication_table_name);
0845 coral::TableDescription descr0;
0846 descr0.setName(authentication_table_name);
0847 descr0.insertColumn(PRINCIPAL_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
0848 descr0.insertColumn(
0849 PRINCIPAL_NAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0850 descr0.insertColumn(
0851 VERIFICATION_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0852 descr0.insertColumn(
0853 PRINCIPAL_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0854 descr0.insertColumn(ADMIN_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0855 descr0.setNotNullConstraint(PRINCIPAL_ID_COL);
0856 descr0.setNotNullConstraint(PRINCIPAL_NAME_COL);
0857 descr0.setNotNullConstraint(VERIFICATION_COL);
0858 descr0.setNotNullConstraint(PRINCIPAL_KEY_COL);
0859 descr0.setNotNullConstraint(ADMIN_KEY_COL);
0860 std::vector<std::string> columnsUnique;
0861 columnsUnique.push_back(PRINCIPAL_NAME_COL);
0862 descr0.setUniqueConstraint(columnsUnique);
0863 std::vector<std::string> columnsForIndex;
0864 columnsForIndex.push_back(PRINCIPAL_ID_COL);
0865 descr0.setPrimaryKey(columnsForIndex);
0866 schema.createTable(descr0);
0867
0868 m_log << "Creating authorization table." << std::endl;
0869 std::string authorization_table_name = tname(AUTHORIZATION_TABLE, m_key.version());
0870
0871 addSequence(m_key.version(), schema, authorization_table_name);
0872 coral::TableDescription descr1;
0873 descr1.setName(authorization_table_name);
0874 descr1.insertColumn(AUTH_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
0875 descr1.insertColumn(P_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
0876 descr1.insertColumn(ROLE_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0877 descr1.insertColumn(SCHEMA_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0878 descr1.insertColumn(AUTH_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0879 descr1.insertColumn(C_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
0880 descr1.setNotNullConstraint(AUTH_ID_COL);
0881 descr1.setNotNullConstraint(P_ID_COL);
0882 descr1.setNotNullConstraint(ROLE_COL);
0883 descr1.setNotNullConstraint(SCHEMA_COL);
0884 descr1.setNotNullConstraint(AUTH_KEY_COL);
0885 descr1.setNotNullConstraint(C_ID_COL);
0886 columnsUnique.clear();
0887 columnsUnique.push_back(P_ID_COL);
0888 columnsUnique.push_back(ROLE_COL);
0889 columnsUnique.push_back(SCHEMA_COL);
0890 descr1.setUniqueConstraint(columnsUnique);
0891 columnsForIndex.clear();
0892 columnsForIndex.push_back(AUTH_ID_COL);
0893 descr1.setPrimaryKey(columnsForIndex);
0894 schema.createTable(descr1);
0895
0896 m_log << "Creating credential table." << std::endl;
0897 std::string credential_table_name = tname(CREDENTIAL_TABLE, m_key.version());
0898
0899 addSequence(m_key.version(), schema, credential_table_name);
0900 coral::TableDescription descr2;
0901 descr2.setName(credential_table_name);
0902 descr2.insertColumn(CONNECTION_ID_COL, coral::AttributeSpecification::typeNameForType<int>());
0903 descr2.insertColumn(
0904 CONNECTION_LABEL_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0905 descr2.insertColumn(USERNAME_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0906 descr2.insertColumn(PASSWORD_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0907 descr2.insertColumn(
0908 VERIFICATION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0909 descr2.insertColumn(
0910 CONNECTION_KEY_COL, coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, false);
0911 descr2.setNotNullConstraint(CONNECTION_ID_COL);
0912 descr2.setNotNullConstraint(CONNECTION_LABEL_COL);
0913 descr2.setNotNullConstraint(USERNAME_COL);
0914 descr2.setNotNullConstraint(PASSWORD_COL);
0915 descr2.setNotNullConstraint(VERIFICATION_KEY_COL);
0916 descr2.setNotNullConstraint(CONNECTION_KEY_COL);
0917 columnsUnique.clear();
0918 columnsUnique.push_back(CONNECTION_LABEL_COL);
0919 descr2.setUniqueConstraint(columnsUnique);
0920 columnsForIndex.clear();
0921 columnsForIndex.push_back(CONNECTION_ID_COL);
0922 descr2.setPrimaryKey(columnsForIndex);
0923 schema.createTable(descr2);
0924
0925 try {
0926 schema.tableHandle(authentication_table_name)
0927 .privilegeManager()
0928 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
0929 schema.tableHandle(authorization_table_name)
0930 .privilegeManager()
0931 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
0932 schema.tableHandle(credential_table_name)
0933 .privilegeManager()
0934 .grantToUser(m_serviceData->userName, coral::ITablePrivilegeManager::Select);
0935 } catch (const coral::Exception& e) {
0936 std::cout << "WARNING: Could not grant select access to user " << m_serviceData->userName << ": [" << e.what()
0937 << "]" << std::endl;
0938 }
0939 m_log << "Granting ADMIN access permission." << std::endl;
0940 auth::KeyGenerator gen;
0941 m_principalKey = gen.make(auth::COND_DB_KEY_SIZE);
0942 auto princData = updatePrincipalData(
0943 m_key.version(), schema, m_key.principalKey(), m_key.principalName(), m_principalKey, true, m_log);
0944 std::string credentialAccessLabel = schemaLabel(m_serviceName, userName);
0945 auto connParams = updateConnectionData(
0946 m_key.version(), schema, m_principalKey, credentialAccessLabel, userName, password, true, m_log);
0947 bool ret = setPermissionData(m_key.version(),
0948 schema,
0949 princData.first,
0950 m_principalKey,
0951 auth::COND_ADMIN_ROLE,
0952 connectionString,
0953 connParams.first,
0954 connParams.second,
0955 m_log);
0956 session.close();
0957 return ret;
0958 }
0959
0960 bool cond::CredentialStore::drop(const std::string& connectionString,
0961 const std::string& userName,
0962 const std::string& password) {
0963 CSScopedSession session(*this);
0964 session.startSuper(connectionString, userName, password);
0965
0966 m_log << "Dropping AUTHORIZATION, CREDENTIAL, AUTHENTICATION and SEQUENCE tables." << std::endl;
0967 coral::ISchema& schema = m_session->nominalSchema();
0968 schema.dropIfExistsTable(tname(AUTHORIZATION_TABLE, m_key.version()));
0969 schema.dropIfExistsTable(tname(CREDENTIAL_TABLE, m_key.version()));
0970 schema.dropIfExistsTable(tname(AUTHENTICATION_TABLE, m_key.version()));
0971 schema.dropIfExistsTable(tname(SEQUENCE_TABLE, m_key.version()));
0972 session.close();
0973 return true;
0974 }
0975
0976 bool cond::CredentialStore::resetAdmin(const std::string& userName, const std::string& password) {
0977 if (!m_serviceData) {
0978 throwException("The credential store has not been initialized.", "cond::CredentialStore::installAdmin");
0979 }
0980 const std::string& connectionString = m_serviceData->connectionString;
0981
0982 CSScopedSession session(*this);
0983 session.startSuper(connectionString, userName, password);
0984
0985 coral::ISchema& schema = m_session->nominalSchema();
0986 const std::string& principalName = m_key.principalName();
0987 const std::string& authenticationKey = m_key.principalKey();
0988 PrincipalData princData;
0989 if (!selectPrincipal(m_key.version(), schema, principalName, princData)) {
0990 std::string msg("User \"");
0991 msg += principalName + "\" has not been found.";
0992 throwException(msg, "CredentialStore::resetAdmin");
0993 }
0994 auth::Cipher cipher0(authenticationKey);
0995 m_principalKey = cipher0.b64decrypt(princData.principalKey);
0996
0997 auto p = updatePrincipalData(m_key.version(), schema, authenticationKey, principalName, m_principalKey, false, m_log);
0998 std::string credentialAccessLabel = schemaLabel(m_serviceName, userName);
0999 auto connParams = updateConnectionData(
1000 m_key.version(), schema, m_principalKey, credentialAccessLabel, userName, password, true, m_log);
1001 bool ret = setPermissionData(m_key.version(),
1002 schema,
1003 p.first,
1004 m_principalKey,
1005 auth::COND_ADMIN_ROLE,
1006 connectionString,
1007 connParams.first,
1008 connParams.second,
1009 m_log);
1010 session.close();
1011 return ret;
1012 }
1013
1014 bool cond::CredentialStore::updatePrincipal(const std::string& principalName,
1015 const std::string& authenticationKey,
1016 bool setAdmin) {
1017 CSScopedSession session(*this);
1018 session.start(false);
1019 coral::ISchema& schema = m_session->nominalSchema();
1020 auto princData =
1021 updatePrincipalData(m_key.version(), schema, authenticationKey, principalName, m_principalKey, false, m_log);
1022 bool ret = false;
1023 if (setAdmin) {
1024 int princId = princData.first;
1025 std::string princKey = m_principalKey;
1026 std::string connString = m_serviceData->connectionString;
1027 std::vector<Permission> permissions;
1028 if (!selectPermissions(m_key.principalName(), auth::COND_ADMIN_ROLE, connString, permissions)) {
1029 throwException("The current operating user is not admin user on the underlying Credential Store.",
1030 "CredentialStore::updatePrincipal");
1031 }
1032 std::string connLabel = permissions.front().connectionLabel;
1033 CredentialData credsData;
1034 if (!selectConnection(m_key.version(), schema, connLabel, credsData)) {
1035 throwException("Credential Store connection has not been defined.", "CredentialStore::updatePrincipal");
1036 }
1037 auth::Cipher adminCipher(m_principalKey);
1038 ret = setPermissionData(m_key.version(),
1039 schema,
1040 princId,
1041 princKey,
1042 auth::COND_ADMIN_ROLE,
1043 connString,
1044 credsData.id,
1045 adminCipher.b64decrypt(credsData.connectionKey),
1046 m_log);
1047 }
1048 session.close();
1049 return ret;
1050 }
1051
1052 bool cond::CredentialStore::setPermission(const std::string& principal,
1053 const std::string& role,
1054 const std::string& connectionString,
1055 const std::string& connectionLabel) {
1056 CSScopedSession session(*this);
1057 session.start(false);
1058
1059 coral::ISchema& schema = m_session->nominalSchema();
1060
1061 PrincipalData princData;
1062 bool found = selectPrincipal(m_key.version(), schema, principal, princData);
1063
1064 if (!found) {
1065 std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1066 throwException(msg, "CredentialStore::setPermission");
1067 }
1068
1069 m_log << "Principal " << principal << " id: " << princData.id << std::endl;
1070 CredentialData credsData;
1071 found = selectConnection(m_key.version(), schema, connectionLabel, credsData);
1072
1073 if (!found) {
1074 std::string msg = "Connection named \"" + connectionLabel + "\" does not exist in the database.";
1075 throwException(msg, "CredentialStore::setPermission");
1076 }
1077
1078 auth::Cipher cipher(m_principalKey);
1079 bool ret = setPermissionData(m_key.version(),
1080 schema,
1081 princData.id,
1082 cipher.b64decrypt(princData.adminKey),
1083 role,
1084 connectionString,
1085 credsData.id,
1086 cipher.b64decrypt(credsData.connectionKey),
1087 m_log);
1088 session.close();
1089 return ret;
1090 }
1091
1092 size_t cond::CredentialStore::unsetPermission(const std::string& principal,
1093 const std::string& role,
1094 const std::string& connectionString) {
1095 if (!role.empty() && cond::auth::ROLES.find(role) == cond::auth::ROLES.end()) {
1096 throwException(std::string("Role ") + role + " does not exists.", "CredentialStore::unsetPermission");
1097 }
1098 CSScopedSession session(*this);
1099 session.start(false);
1100 coral::ISchema& schema = m_session->nominalSchema();
1101
1102 coral::AttributeList deleteData;
1103 deleteData.extend<std::string>(SCHEMA_COL);
1104 std::stringstream whereClause;
1105 m_log << "Removing permissions to access resource " << connectionString;
1106 if (!role.empty()) {
1107 deleteData.extend<std::string>(ROLE_COL);
1108 m_log << " with role " << role;
1109 }
1110 int princId = -1;
1111 if (!principal.empty()) {
1112 PrincipalData princData;
1113 bool found = selectPrincipal(m_key.version(), schema, principal, princData);
1114
1115 if (!found) {
1116 std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1117 throwException(msg, "CredentialStore::unsetPermission");
1118 }
1119 deleteData.extend<int>(P_ID_COL);
1120 princId = princData.id;
1121 m_log << " by principal " << principal << " (id: " << princData.id << ")";
1122 }
1123
1124 size_t n_e = getAuthorizationEntries(m_key.version(), schema, princId, role, connectionString);
1125 m_log << ": " << n_e << " authorization entries." << std::endl;
1126 if (n_e) {
1127 deleteData[SCHEMA_COL].data<std::string>() = connectionString;
1128 whereClause << SCHEMA_COL << " = :" << SCHEMA_COL;
1129 if (!role.empty()) {
1130 deleteData[ROLE_COL].data<std::string>() = role;
1131 whereClause << " AND " << ROLE_COL << " = :" << ROLE_COL;
1132 }
1133 if (!principal.empty()) {
1134 deleteData[P_ID_COL].data<int>() = princId;
1135 whereClause << " AND " << P_ID_COL + " = :" + P_ID_COL;
1136 }
1137 coral::ITableDataEditor& editor = schema.tableHandle(tname(AUTHORIZATION_TABLE, m_key.version())).dataEditor();
1138 editor.deleteRows(whereClause.str(), deleteData);
1139 }
1140 session.close();
1141 return n_e;
1142 }
1143
1144 bool cond::CredentialStore::updateConnection(const std::string& connectionLabel,
1145 const std::string& userName,
1146 const std::string& password) {
1147 CSScopedSession session(*this);
1148 session.start(false);
1149
1150 m_session->transaction().start();
1151 coral::ISchema& schema = m_session->nominalSchema();
1152 std::string connLabel = to_lower(connectionLabel);
1153 updateConnectionData(m_key.version(), schema, m_principalKey, connLabel, userName, password, true, m_log);
1154
1155 session.close();
1156 return true;
1157 }
1158
1159 bool cond::CredentialStore::removePrincipal(const std::string& principal) {
1160 CSScopedSession session(*this);
1161 session.start(false);
1162 coral::ISchema& schema = m_session->nominalSchema();
1163
1164 PrincipalData princData;
1165 bool found = selectPrincipal(m_key.version(), schema, principal, princData);
1166
1167 if (!found) {
1168 std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1169 throwException(msg, "CredentialStore::removePrincipal");
1170 }
1171
1172 m_log << "Removing principal " << principal << " (id: " << princData.id << ")" << std::endl;
1173
1174 coral::ITableDataEditor& editor0 = schema.tableHandle(tname(AUTHORIZATION_TABLE, m_key.version())).dataEditor();
1175
1176 coral::AttributeList deleteData0;
1177 deleteData0.extend<int>(P_ID_COL);
1178 deleteData0[P_ID_COL].data<int>() = princData.id;
1179 std::string whereClause0 = P_ID_COL + " = :" + P_ID_COL;
1180 editor0.deleteRows(whereClause0, deleteData0);
1181
1182 coral::ITableDataEditor& editor1 = schema.tableHandle(tname(AUTHENTICATION_TABLE, m_key.version())).dataEditor();
1183
1184 coral::AttributeList deleteData1;
1185 deleteData1.extend<int>(PRINCIPAL_ID_COL);
1186 deleteData1[PRINCIPAL_ID_COL].data<int>() = princData.id;
1187 std::string whereClause1 = PRINCIPAL_ID_COL + " = :" + PRINCIPAL_ID_COL;
1188 editor1.deleteRows(whereClause1, deleteData1);
1189
1190 session.close();
1191
1192 return true;
1193 }
1194
1195 bool cond::CredentialStore::removeConnection(const std::string& connectionLabel) {
1196 CSScopedSession session(*this);
1197 session.start(false);
1198 coral::ISchema& schema = m_session->nominalSchema();
1199
1200 CredentialData credsData;
1201 bool found = selectConnection(m_key.version(), schema, connectionLabel, credsData);
1202
1203 if (!found) {
1204 std::string msg = "Connection named \"" + connectionLabel + "\" does not exist in the database.";
1205 throwException(msg, "CredentialStore::removeConnection");
1206 }
1207
1208 m_log << "Removing connection " << connectionLabel << std::endl;
1209 coral::ITableDataEditor& editor0 = schema.tableHandle(tname(AUTHORIZATION_TABLE, m_key.version())).dataEditor();
1210
1211 coral::AttributeList deleteData0;
1212 deleteData0.extend<int>(C_ID_COL);
1213 deleteData0[C_ID_COL].data<int>() = credsData.id;
1214 std::string whereClause0 = C_ID_COL + " = :" + C_ID_COL;
1215 editor0.deleteRows(whereClause0, deleteData0);
1216
1217 coral::ITableDataEditor& editor1 = schema.tableHandle(tname(CREDENTIAL_TABLE, m_key.version())).dataEditor();
1218
1219 coral::AttributeList deleteData1;
1220 deleteData1.extend<int>(CONNECTION_ID_COL);
1221 deleteData1[CONNECTION_ID_COL].data<int>() = credsData.id;
1222 std::string whereClause1 = CONNECTION_ID_COL + " = :" + CONNECTION_ID_COL;
1223 editor1.deleteRows(whereClause1, deleteData1);
1224
1225 session.close();
1226
1227 return true;
1228 }
1229
1230 bool cond::CredentialStore::selectForUser(coral_bridge::AuthenticationCredentialSet& destinationData) {
1231 CSScopedSession session(*this);
1232 session.start(true);
1233 coral::ISchema& schema = m_session->nominalSchema();
1234
1235 auth::Cipher cipher(m_principalKey);
1236
1237 std::unique_ptr<coral::IQuery> query(schema.newQuery());
1238 query->addToTableList(tname(AUTHORIZATION_TABLE, m_key.version()), "AUTHO");
1239 query->addToTableList(tname(CREDENTIAL_TABLE, m_key.version()), "CREDS");
1240 coral::AttributeList readBuff;
1241 readBuff.extend<std::string>("AUTHO." + ROLE_COL);
1242 readBuff.extend<std::string>("AUTHO." + SCHEMA_COL);
1243 readBuff.extend<std::string>("AUTHO." + AUTH_KEY_COL);
1244 readBuff.extend<std::string>("CREDS." + CONNECTION_LABEL_COL);
1245 readBuff.extend<std::string>("CREDS." + USERNAME_COL);
1246 readBuff.extend<std::string>("CREDS." + PASSWORD_COL);
1247 readBuff.extend<std::string>("CREDS." + VERIFICATION_KEY_COL);
1248 coral::AttributeList whereData;
1249 whereData.extend<int>(P_ID_COL);
1250 whereData[P_ID_COL].data<int>() = m_principalId;
1251 std::stringstream whereClause;
1252 whereClause << "AUTHO." << C_ID_COL << "="
1253 << "CREDS." << CONNECTION_ID_COL;
1254 whereClause << " AND "
1255 << "AUTHO." << P_ID_COL << " = :" << P_ID_COL;
1256 query->defineOutput(readBuff);
1257 query->addToOutputList("AUTHO." + ROLE_COL);
1258 query->addToOutputList("AUTHO." + SCHEMA_COL);
1259 query->addToOutputList("AUTHO." + AUTH_KEY_COL);
1260 query->addToOutputList("CREDS." + CONNECTION_LABEL_COL);
1261 query->addToOutputList("CREDS." + USERNAME_COL);
1262 query->addToOutputList("CREDS." + PASSWORD_COL);
1263 query->addToOutputList("CREDS." + VERIFICATION_KEY_COL);
1264 query->setCondition(whereClause.str(), whereData);
1265 coral::ICursor& cursor = query->execute();
1266 while (cursor.next()) {
1267 const coral::AttributeList& row = cursor.currentRow();
1268 const std::string& role = row["AUTHO." + ROLE_COL].data<std::string>();
1269 const std::string& connectionString = row["AUTHO." + SCHEMA_COL].data<std::string>();
1270 const std::string& encryptedAuthKey = row["AUTHO." + AUTH_KEY_COL].data<std::string>();
1271 const std::string& connectionLabel = row["CREDS." + CONNECTION_LABEL_COL].data<std::string>();
1272 const std::string& encryptedUserName = row["CREDS." + USERNAME_COL].data<std::string>();
1273 const std::string& encryptedPassword = row["CREDS." + PASSWORD_COL].data<std::string>();
1274 std::string authKey = cipher.b64decrypt(encryptedAuthKey);
1275 auth::Cipher connCipher(authKey);
1276 std::string verificationString = connCipher.b64decrypt(row["CREDS." + VERIFICATION_KEY_COL].data<std::string>());
1277 if (verificationString == connectionLabel) {
1278 destinationData.registerCredentials(to_lower(connectionString),
1279 role,
1280 connCipher.b64decrypt(encryptedUserName),
1281 connCipher.b64decrypt(encryptedPassword));
1282 }
1283 }
1284 session.close();
1285 return true;
1286 }
1287
1288 std::pair<std::string, std::string> cond::CredentialStore::getUserCredentials(const std::string& connectionString,
1289 const std::string& role) {
1290 CSScopedSession session(*this);
1291 session.start(true);
1292 coral::ISchema& schema = m_session->nominalSchema();
1293
1294 auth::Cipher cipher(m_principalKey);
1295
1296 std::unique_ptr<coral::IQuery> query(schema.newQuery());
1297 query->addToTableList(tname(AUTHORIZATION_TABLE, m_key.version()), "AUTHO");
1298 query->addToTableList(tname(CREDENTIAL_TABLE, m_key.version()), "CREDS");
1299 coral::AttributeList readBuff;
1300 readBuff.extend<std::string>("AUTHO." + AUTH_KEY_COL);
1301 readBuff.extend<std::string>("CREDS." + CONNECTION_LABEL_COL);
1302 readBuff.extend<std::string>("CREDS." + USERNAME_COL);
1303 readBuff.extend<std::string>("CREDS." + PASSWORD_COL);
1304 readBuff.extend<std::string>("CREDS." + VERIFICATION_KEY_COL);
1305 coral::AttributeList whereData;
1306 whereData.extend<int>(P_ID_COL);
1307 whereData.extend<std::string>(SCHEMA_COL);
1308 whereData.extend<std::string>(ROLE_COL);
1309 whereData[P_ID_COL].data<int>() = m_principalId;
1310 whereData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
1311 whereData[ROLE_COL].data<std::string>() = role;
1312 std::stringstream whereClause;
1313 whereClause << "AUTHO." << C_ID_COL << "="
1314 << "CREDS." << CONNECTION_ID_COL;
1315 whereClause << " AND "
1316 << "AUTHO." << P_ID_COL << " = :" << P_ID_COL;
1317 whereClause << " AND "
1318 << "AUTHO." << SCHEMA_COL << " = :" << SCHEMA_COL;
1319 whereClause << " AND "
1320 << "AUTHO." << ROLE_COL << " = :" << ROLE_COL;
1321 query->defineOutput(readBuff);
1322 query->addToOutputList("AUTHO." + AUTH_KEY_COL);
1323 query->addToOutputList("CREDS." + CONNECTION_LABEL_COL);
1324 query->addToOutputList("CREDS." + USERNAME_COL);
1325 query->addToOutputList("CREDS." + PASSWORD_COL);
1326 query->addToOutputList("CREDS." + VERIFICATION_KEY_COL);
1327 query->setCondition(whereClause.str(), whereData);
1328 coral::ICursor& cursor = query->execute();
1329 auto ret = std::make_pair(std::string(""), std::string(""));
1330 if (cursor.next()) {
1331 const coral::AttributeList& row = cursor.currentRow();
1332 const std::string& encryptedAuthKey = row["AUTHO." + AUTH_KEY_COL].data<std::string>();
1333 const std::string& connectionLabel = row["CREDS." + CONNECTION_LABEL_COL].data<std::string>();
1334 const std::string& encryptedUserName = row["CREDS." + USERNAME_COL].data<std::string>();
1335 const std::string& encryptedPassword = row["CREDS." + PASSWORD_COL].data<std::string>();
1336 std::string authKey = cipher.b64decrypt(encryptedAuthKey);
1337 auth::Cipher connCipher(authKey);
1338 std::string verificationString = connCipher.b64decrypt(row["CREDS." + VERIFICATION_KEY_COL].data<std::string>());
1339 if (verificationString == connectionLabel) {
1340 ret.first = connCipher.b64decrypt(encryptedUserName);
1341 ret.second = connCipher.b64decrypt(encryptedPassword);
1342 }
1343 }
1344 session.close();
1345 return ret;
1346 }
1347
1348 bool cond::CredentialStore::importForPrincipal(const std::string& principal,
1349 const coral_bridge::AuthenticationCredentialSet& dataSource,
1350 bool forceUpdateConnection) {
1351 CSScopedSession session(*this);
1352 session.start(false);
1353 coral::ISchema& schema = m_session->nominalSchema();
1354
1355 PrincipalData princData;
1356 bool found = selectPrincipal(m_key.version(), schema, principal, princData);
1357
1358 if (!found) {
1359 std::string msg = "Principal \"" + principal + "\" does not exist in the database.";
1360 throwException(msg, "CredentialStore::importForPrincipal");
1361 }
1362
1363 bool imported = false;
1364 auth::Cipher cipher(m_principalKey);
1365 std::string princKey = cipher.b64decrypt(princData.adminKey);
1366
1367 const std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>& creds = dataSource.data();
1368 for (std::map<std::pair<std::string, std::string>, coral::AuthenticationCredentials*>::const_iterator iConn =
1369 creds.begin();
1370 iConn != creds.end();
1371 ++iConn) {
1372 const std::string& connectionString = iConn->first.first;
1373 coral::URIParser parser;
1374 parser.setURI(connectionString);
1375 std::string serviceName = parser.hostName();
1376 const std::string& role = iConn->first.second;
1377 std::string userName = iConn->second->valueForItem(coral::IAuthenticationCredentials::userItem());
1378 std::string password = iConn->second->valueForItem(coral::IAuthenticationCredentials::passwordItem());
1379
1380 std::pair<int, std::string> conn = updateConnectionData(m_key.version(),
1381 schema,
1382 m_principalKey,
1383 schemaLabel(serviceName, userName),
1384 userName,
1385 password,
1386 forceUpdateConnection,
1387 m_log);
1388 auth::Cipher cipher(m_principalKey);
1389
1390 setPermissionData(
1391 m_key.version(), schema, princData.id, princKey, role, connectionString, conn.first, conn.second, m_log);
1392 imported = true;
1393 }
1394 session.close();
1395 return imported;
1396 }
1397
1398 bool cond::CredentialStore::listPrincipals(std::vector<std::string>& destination) {
1399 CSScopedSession session(*this);
1400 session.start(true);
1401 coral::ISchema& schema = m_session->nominalSchema();
1402
1403 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(AUTHENTICATION_TABLE, m_key.version())).newQuery());
1404 coral::AttributeList readBuff;
1405 readBuff.extend<std::string>(PRINCIPAL_NAME_COL);
1406 query->defineOutput(readBuff);
1407 query->addToOutputList(PRINCIPAL_NAME_COL);
1408 coral::ICursor& cursor = query->execute();
1409 bool found = false;
1410 while (cursor.next()) {
1411 found = true;
1412 const coral::AttributeList& row = cursor.currentRow();
1413 destination.push_back(row[PRINCIPAL_NAME_COL].data<std::string>());
1414 }
1415 session.close();
1416 return found;
1417 }
1418
1419 bool cond::CredentialStore::listConnections(std::map<std::string, std::pair<std::string, std::string> >& destination) {
1420 CSScopedSession session(*this);
1421 session.start(true);
1422 coral::ISchema& schema = m_session->nominalSchema();
1423
1424 std::unique_ptr<coral::IQuery> query(schema.tableHandle(tname(CREDENTIAL_TABLE, m_key.version())).newQuery());
1425 coral::AttributeList readBuff;
1426 readBuff.extend<std::string>(CONNECTION_LABEL_COL);
1427 readBuff.extend<std::string>(USERNAME_COL);
1428 readBuff.extend<std::string>(PASSWORD_COL);
1429 readBuff.extend<std::string>(VERIFICATION_KEY_COL);
1430 readBuff.extend<std::string>(CONNECTION_KEY_COL);
1431 query->defineOutput(readBuff);
1432 query->addToOutputList(CONNECTION_LABEL_COL);
1433 query->addToOutputList(USERNAME_COL);
1434 query->addToOutputList(PASSWORD_COL);
1435 query->addToOutputList(VERIFICATION_KEY_COL);
1436 query->addToOutputList(CONNECTION_KEY_COL);
1437 coral::ICursor& cursor = query->execute();
1438 bool found = false;
1439 auth::Cipher cipher0(m_principalKey);
1440 while (cursor.next()) {
1441 std::string userName("");
1442 std::string password("");
1443 const coral::AttributeList& row = cursor.currentRow();
1444 const std::string& connLabel = row[CONNECTION_LABEL_COL].data<std::string>();
1445 const std::string& encryptedKey = row[CONNECTION_KEY_COL].data<std::string>();
1446 const std::string& encryptedVerif = row[VERIFICATION_KEY_COL].data<std::string>();
1447 std::string connKey = cipher0.b64decrypt(encryptedKey);
1448 auth::Cipher cipher1(connKey);
1449 std::string verif = cipher1.b64decrypt(encryptedVerif);
1450 if (verif == connLabel) {
1451 const std::string& encryptedUserName = row[USERNAME_COL].data<std::string>();
1452 const std::string& encryptedPassword = row[PASSWORD_COL].data<std::string>();
1453 userName = cipher1.b64decrypt(encryptedUserName);
1454 password = cipher1.b64decrypt(encryptedPassword);
1455 }
1456 destination.insert(std::make_pair(connLabel, std::make_pair(userName, password)));
1457 found = true;
1458 }
1459 session.close();
1460 return found;
1461 }
1462
1463 bool cond::CredentialStore::selectPermissions(const std::string& principalName,
1464 const std::string& role,
1465 const std::string& connectionString,
1466 std::vector<Permission>& destination) {
1467 CSScopedSession session(*this);
1468 session.start(true);
1469 coral::ISchema& schema = m_session->nominalSchema();
1470 std::unique_ptr<coral::IQuery> query(schema.newQuery());
1471 query->addToTableList(tname(AUTHENTICATION_TABLE, m_key.version()), "AUTHE");
1472 query->addToTableList(tname(AUTHORIZATION_TABLE, m_key.version()), "AUTHO");
1473 query->addToTableList(tname(CREDENTIAL_TABLE, m_key.version()), "CREDS");
1474 coral::AttributeList readBuff;
1475 readBuff.extend<std::string>("AUTHE." + PRINCIPAL_NAME_COL);
1476 readBuff.extend<std::string>("AUTHO." + ROLE_COL);
1477 readBuff.extend<std::string>("AUTHO." + SCHEMA_COL);
1478 readBuff.extend<std::string>("CREDS." + CONNECTION_LABEL_COL);
1479 coral::AttributeList whereData;
1480 std::stringstream whereClause;
1481 whereClause << "AUTHE." << PRINCIPAL_ID_COL << "= AUTHO." << P_ID_COL;
1482 whereClause << " AND AUTHO." << C_ID_COL << "="
1483 << "CREDS." << CONNECTION_ID_COL;
1484 if (!principalName.empty()) {
1485 whereData.extend<std::string>(PRINCIPAL_NAME_COL);
1486 whereData[PRINCIPAL_NAME_COL].data<std::string>() = principalName;
1487 whereClause << " AND AUTHE." << PRINCIPAL_NAME_COL << " = :" << PRINCIPAL_NAME_COL;
1488 }
1489 if (!role.empty()) {
1490 whereData.extend<std::string>(ROLE_COL);
1491 whereData[ROLE_COL].data<std::string>() = role;
1492 whereClause << " AND AUTHO." << ROLE_COL << " = :" << ROLE_COL;
1493 }
1494 if (!connectionString.empty()) {
1495 whereData.extend<std::string>(SCHEMA_COL);
1496 whereData[SCHEMA_COL].data<std::string>() = to_lower(connectionString);
1497 whereClause << " AND AUTHO." << SCHEMA_COL << " = :" << SCHEMA_COL;
1498 }
1499
1500 query->defineOutput(readBuff);
1501 query->addToOutputList("AUTHE." + PRINCIPAL_NAME_COL);
1502 query->addToOutputList("AUTHO." + ROLE_COL);
1503 query->addToOutputList("AUTHO." + SCHEMA_COL);
1504 query->addToOutputList("CREDS." + CONNECTION_LABEL_COL);
1505 query->setCondition(whereClause.str(), whereData);
1506 query->addToOrderList("AUTHO." + SCHEMA_COL);
1507 query->addToOrderList("AUTHE." + PRINCIPAL_NAME_COL);
1508 query->addToOrderList("AUTHO." + ROLE_COL);
1509 coral::ICursor& cursor = query->execute();
1510 bool found = false;
1511 while (cursor.next()) {
1512 const coral::AttributeList& row = cursor.currentRow();
1513 destination.resize(destination.size() + 1);
1514 Permission& perm = destination.back();
1515 perm.principalName = row["AUTHE." + PRINCIPAL_NAME_COL].data<std::string>();
1516 perm.role = row["AUTHO." + ROLE_COL].data<std::string>();
1517 perm.connectionString = row["AUTHO." + SCHEMA_COL].data<std::string>();
1518 perm.connectionLabel = row["CREDS." + CONNECTION_LABEL_COL].data<std::string>();
1519 found = true;
1520 }
1521 session.close();
1522 return found;
1523 }
1524
1525 bool cond::CredentialStore::exportAll(coral_bridge::AuthenticationCredentialSet& data) {
1526 CSScopedSession session(*this);
1527 session.start(true);
1528 coral::ISchema& schema = m_session->nominalSchema();
1529 std::unique_ptr<coral::IQuery> query(schema.newQuery());
1530 query->addToTableList(tname(AUTHORIZATION_TABLE, m_key.version()), "AUTHO");
1531 query->addToTableList(tname(CREDENTIAL_TABLE, m_key.version()), "CREDS");
1532 coral::AttributeList readBuff;
1533 readBuff.extend<std::string>("AUTHO." + ROLE_COL);
1534 readBuff.extend<std::string>("AUTHO." + SCHEMA_COL);
1535 readBuff.extend<std::string>("CREDS." + CONNECTION_LABEL_COL);
1536 readBuff.extend<std::string>("CREDS." + VERIFICATION_KEY_COL);
1537 readBuff.extend<std::string>("CREDS." + CONNECTION_KEY_COL);
1538 readBuff.extend<std::string>("CREDS." + USERNAME_COL);
1539 readBuff.extend<std::string>("CREDS." + PASSWORD_COL);
1540 coral::AttributeList whereData;
1541 std::stringstream whereClause;
1542 whereClause << "AUTHO." << C_ID_COL << "="
1543 << "CREDS." << CONNECTION_ID_COL;
1544
1545 query->defineOutput(readBuff);
1546 query->addToOutputList("AUTHO." + ROLE_COL);
1547 query->addToOutputList("AUTHO." + SCHEMA_COL);
1548 query->addToOutputList("CREDS." + CONNECTION_LABEL_COL);
1549 query->addToOutputList("CREDS." + VERIFICATION_KEY_COL);
1550 query->addToOutputList("CREDS." + CONNECTION_KEY_COL);
1551 query->addToOutputList("CREDS." + USERNAME_COL);
1552 query->addToOutputList("CREDS." + PASSWORD_COL);
1553 query->setCondition(whereClause.str(), whereData);
1554 coral::ICursor& cursor = query->execute();
1555 bool found = false;
1556 auth::Cipher cipher0(m_principalKey);
1557 while (cursor.next()) {
1558 const coral::AttributeList& row = cursor.currentRow();
1559 const std::string& role = row["AUTHO." + ROLE_COL].data<std::string>();
1560 const std::string& connectionString = row["AUTHO." + SCHEMA_COL].data<std::string>();
1561 const std::string& connectionLabel = row["CREDS." + CONNECTION_LABEL_COL].data<std::string>();
1562 const std::string& encryptedVerifKey = row["CREDS." + VERIFICATION_KEY_COL].data<std::string>();
1563 const std::string& encryptedConnection = row["CREDS." + CONNECTION_KEY_COL].data<std::string>();
1564 std::string userName("");
1565 std::string password("");
1566 std::string connectionKey = cipher0.b64decrypt(encryptedConnection);
1567 auth::Cipher cipher1(connectionKey);
1568 std::string verifKey = cipher1.b64decrypt(encryptedVerifKey);
1569 if (verifKey == connectionLabel) {
1570 const std::string& encryptedUserName = row["CREDS." + USERNAME_COL].data<std::string>();
1571 const std::string& encryptedPassword = row["CREDS." + PASSWORD_COL].data<std::string>();
1572 userName = cipher1.b64decrypt(encryptedUserName);
1573 password = cipher1.b64decrypt(encryptedPassword);
1574 }
1575 data.registerCredentials(to_lower(connectionString), role, userName, password);
1576 found = true;
1577 }
1578 session.close();
1579 return found;
1580 }
1581
1582 const std::string& cond::CredentialStore::serviceName() { return m_serviceName; }
1583
1584 const std::string& cond::CredentialStore::keyPrincipalName() { return m_authenticatedPrincipal; }
1585
1586 std::string cond::CredentialStore::log() { return m_log.str(); }