"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/jrd/CryptoManager.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

CryptoManager.cpp  (Firebird-3.0.2.32703-0.tar.bz2):CryptoManager.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 72 skipping to change at line 72
return 0; return 0;
} }
const UCHAR CRYPT_RELEASE = LCK_SR; const UCHAR CRYPT_RELEASE = LCK_SR;
const UCHAR CRYPT_NORMAL = LCK_PR; const UCHAR CRYPT_NORMAL = LCK_PR;
const UCHAR CRYPT_CHANGE = LCK_PW; const UCHAR CRYPT_CHANGE = LCK_PW;
const UCHAR CRYPT_INIT = LCK_EX; const UCHAR CRYPT_INIT = LCK_EX;
const int MAX_PLUGIN_NAME_LEN = 31; const int MAX_PLUGIN_NAME_LEN = 31;
class ReleasePlugin
{
public:
static void clear(IPluginBase* ptr)
{
if (ptr)
{
PluginManagerInterfacePtr()->releasePlugin(ptr);
}
}
};
} }
namespace Jrd { namespace Jrd {
class Header class Header
{ {
protected: protected:
Header() Header()
: header(NULL) : header(NULL)
{ } { }
skipping to change at line 281 skipping to change at line 268
} }
catch(const Exception&) catch(const Exception&)
{ {
Jrd::BackupManager::StateReadGuard::unlock(tdbb); Jrd::BackupManager::StateReadGuard::unlock(tdbb);
throw; throw;
} }
Jrd::BackupManager::StateReadGuard::unlock(tdbb); Jrd::BackupManager::StateReadGuard::unlock(tdbb);
} }
private: private:
AutoPtr<UCHAR, ArrayDelete<UCHAR> &gt; buffer; AutoPtr<UCHAR, ArrayDelete> buffer;
}; };
CryptoManager::CryptoManager(thread_db* tdbb) CryptoManager::CryptoManager(thread_db* tdbb)
: PermanentStorage(*tdbb->getDatabase()->dbb_permanent), : PermanentStorage(*tdbb->getDatabase()->dbb_permanent),
sync(this), sync(this),
keyName(getPool()), keyName(getPool()),
keyHolderPlugins(getPool(), this), keyProviders(getPool()),
keyConsumers(getPool()),
hash(getPool()), hash(getPool()),
dbInfo(FB_NEW DbInfo(this)), dbInfo(FB_NEW DbInfo(this)),
cryptThreadId(0), cryptThreadId(0),
cryptPlugin(NULL), cryptPlugin(NULL),
checkFactory(NULL), checkFactory(NULL),
dbb(*tdbb->getDatabase()), dbb(*tdbb->getDatabase()),
cryptAtt(NULL), cryptAtt(NULL),
slowIO(0), slowIO(0),
crypt(false), crypt(false),
process(false), process(false),
skipping to change at line 405 skipping to change at line 393
(Arg::Gds(isc_bad_crypt_key) << keyName). raise(); (Arg::Gds(isc_bad_crypt_key) << keyName). raise();
} }
else else
hash = valid; hash = valid;
} }
if (flags & CRYPT_HDR_INIT) if (flags & CRYPT_HDR_INIT)
checkDigitalSignature(tdbb, hdr); checkDigitalSignature(tdbb, hdr);
} }
void CryptoManager::setDbInfo(IDbCryptPlugin* cp)
{
FbLocalStatus status;
cp->setInfo(&status, dbInfo);
if (status->getState() & IStatus::STATE_ERRORS)
{
const ISC_STATUS* v = status->getErrors();
if (v[0] == isc_arg_gds && v[1] != isc_arg_end && v[1] !=
isc_interface_version_too_old)
status_exception::raise(&status);
}
}
void CryptoManager::loadPlugin(thread_db* tdbb, const char* pluginName) void CryptoManager::loadPlugin(thread_db* tdbb, const char* pluginName)
{ {
if (cryptPlugin) if (cryptPlugin)
{ {
return; return;
} }
MutexLockGuard guard(pluginLoadMtx, FB_FUNCTION); MutexLockGuard guard(pluginLoadMtx, FB_FUNCTION);
if (cryptPlugin) if (cryptPlugin)
{ {
skipping to change at line 426 skipping to change at line 426
} }
AutoPtr<Factory> cryptControl(FB_NEW Factory(IPluginManager::TYPE _DB_CRYPT, dbb.dbb_config, pluginName)); AutoPtr<Factory> cryptControl(FB_NEW Factory(IPluginManager::TYPE _DB_CRYPT, dbb.dbb_config, pluginName));
if (!cryptControl->hasData()) if (!cryptControl->hasData())
{ {
(Arg::Gds(isc_no_crypt_plugin) << pluginName).raise(); (Arg::Gds(isc_no_crypt_plugin) << pluginName).raise();
} }
// do not assign cryptPlugin directly before key init complete // do not assign cryptPlugin directly before key init complete
IDbCryptPlugin* p = cryptControl->plugin(); IDbCryptPlugin* p = cryptControl->plugin();
setDbInfo(p);
FbLocalStatus status; bool fLoad = false, fTry = false;
p->setInfo(&status, dbInfo); bool holderLess = false;
if (status->getState() & IStatus::STATE_ERRORS) FbLocalStatus errorVector;
(Arg::Gds(isc_random) << "Missing correct crypt key").copyTo(&err
orVector);
for (GetPlugins<IKeyHolderPlugin> keyControl(IPluginManager::TYPE
_KEY_HOLDER, dbb.dbb_config);
keyControl.hasData(); keyControl.next())
{ {
const ISC_STATUS* v = status->getErrors(); IKeyHolderPlugin* keyPlugin = keyControl.plugin();
if (v[0] == isc_arg_gds && v[1] != isc_arg_end && v[1] !=
isc_interface_version_too_old) FbLocalStatus st;
status_exception::raise(&status); int keyCallbackRc = keyPlugin->keyCallback(&st, tdbb->get
Attachment()->att_crypt_callback);
st.check();
if (!keyCallbackRc)
continue;
fTry = true;
p->setKey(&st, 1, &keyPlugin, keyName.c_str());
if (st.isSuccess())
{
if (!keyPlugin->useOnlyOwnKeys(&st))
{
MutexLockGuard g(holdersMutex, FB_FUNCTIO
N);
keyProviders.push(tdbb->getAttachment());
}
fLoad = true;
break;
}
else
{
string msg = "Plugin ";
msg += keyControl.name();
msg += ':';
(Arg::Gds(isc_random) << msg << Arg::StatusVector
(&st)).appendTo(&errorVector);
}
} }
keyHolderPlugins.init(p, keyName); if (!fTry)
{
FbLocalStatus status;
p->setKey(&status, 0, NULL, keyName.c_str());
if (status.isSuccess())
{
holderLess = true;
fLoad = true;
}
else
{
string msg = "Plugin ";
msg += pluginName;
msg += ':';
(Arg::Gds(isc_random) << msg << Arg::StatusVector
(&status)).appendTo(&errorVector);
}
}
if (!fLoad)
errorVector.raise();
cryptPlugin = p; cryptPlugin = p;
cryptPlugin->addRef(); cryptPlugin->addRef();
// remove old factory if present // remove old factory if present
delete checkFactory; delete checkFactory;
checkFactory = NULL; checkFactory = NULL;
// store new one // store new one
if (dbb.dbb_config->getServerMode() == MODE_SUPER) if (dbb.dbb_config->getServerMode() == MODE_SUPER && !holderLess)
{
checkFactory = cryptControl.release(); checkFactory = cryptControl.release();
keyHolderPlugins.validateNewAttachment(tdbb->getAttachmen
t(), keyName);
}
} }
void CryptoManager::prepareChangeCryptState(thread_db* tdbb, const MetaNa me& plugName, void CryptoManager::prepareChangeCryptState(thread_db* tdbb, const MetaNa me& plugName,
const MetaName& key) const MetaName& key)
{ {
if (plugName.length() > MAX_PLUGIN_NAME_LEN) if (plugName.length() > MAX_PLUGIN_NAME_LEN)
{ {
(Arg::Gds(isc_cp_name_too_long) << Arg::Num(MAX_PLUGIN_NA ME_LEN)).raise(); (Arg::Gds(isc_cp_name_too_long) << Arg::Num(MAX_PLUGIN_NA ME_LEN)).raise();
} }
skipping to change at line 602 skipping to change at line 647
plugName.copyTo(header->hdr_crypt_plugin, sizeof( header->hdr_crypt_plugin)); plugName.copyTo(header->hdr_crypt_plugin, sizeof( header->hdr_crypt_plugin));
calcValidation(hash, cryptPlugin); calcValidation(hash, cryptPlugin);
hc.deleteWithTag(Ods::HDR_crypt_hash); hc.deleteWithTag(Ods::HDR_crypt_hash);
hc.insertString(Ods::HDR_crypt_hash, hash); hc.insertString(Ods::HDR_crypt_hash, hash);
hc.deleteWithTag(Ods::HDR_crypt_key); hc.deleteWithTag(Ods::HDR_crypt_key);
if (keyName.hasData()) if (keyName.hasData())
hc.insertString(Ods::HDR_crypt_key, keyNa me); hc.insertString(Ods::HDR_crypt_key, keyNa me);
if (checkFactory) if (checkFactory)
keyHolderPlugins.validateExistingAttachme {
nts(keyName); // Create local copy of existing attachme
nts
AttVector existing;
{
SyncLockGuard dsGuard(&dbb.dbb_sy
nc, SYNC_EXCLUSIVE, FB_FUNCTION);
for (Attachment* att = dbb.dbb_at
tachments; att; att = att->att_next)
existing.push(att);
}
// Loop through attachments
MutexLockGuard g(holdersMutex, FB_FUNCTIO
N);
for (unsigned n = 0; n < existing.getCoun
t(); ++n)
internalAttach(tdbb, existing[n],
true);
// In case of missing providers close con
sumers
if (keyProviders.getCount() == 0)
shutdownConsumers(tdbb);
}
} }
else else
header->hdr_flags &= ~Ods::hdr_encrypted; header->hdr_flags &= ~Ods::hdr_encrypted;
hdr.setClumplets(hc); hdr.setClumplets(hc);
// Setup hdr_crypt_page for crypt thread // Setup hdr_crypt_page for crypt thread
header->hdr_crypt_page = 1; header->hdr_crypt_page = 1;
header->hdr_flags |= Ods::hdr_crypt_process; header->hdr_flags |= Ods::hdr_crypt_process;
process = true; process = true;
skipping to change at line 644 skipping to change at line 707
LCK_write_data(tdbb, stateLock, next); LCK_write_data(tdbb, stateLock, next);
if (!LCK_convert(tdbb, stateLock, CRYPT_RELEASE, LCK_NO_WAIT)) if (!LCK_convert(tdbb, stateLock, CRYPT_RELEASE, LCK_NO_WAIT))
fb_assert(false); fb_assert(false);
lockAndReadHeader(tdbb); lockAndReadHeader(tdbb);
fb_utils::init_status(tdbb->tdbb_status_vector); fb_utils::init_status(tdbb->tdbb_status_vector);
startCryptThread(tdbb); startCryptThread(tdbb);
} }
void CryptoManager::shutdownConsumers(thread_db* tdbb)
{
MutexLockGuard g(holdersMutex, FB_FUNCTION);
for (unsigned i = 0; i < keyConsumers.getCount(); ++i)
keyConsumers[i]->signalShutdown();
keyConsumers.clear();
}
void CryptoManager::blockingAstChangeCryptState() void CryptoManager::blockingAstChangeCryptState()
{ {
AsyncContextHolder tdbb(&dbb, FB_FUNCTION); AsyncContextHolder tdbb(&dbb, FB_FUNCTION);
if (stateLock->lck_physical != CRYPT_CHANGE && stateLock->lck_phy sical != CRYPT_INIT) if (stateLock->lck_physical != CRYPT_CHANGE && stateLock->lck_phy sical != CRYPT_INIT)
{ {
sync.ast(tdbb); sync.ast(tdbb);
} }
} }
void CryptoManager::doOnAst(thread_db* tdbb) void CryptoManager::doOnAst(thread_db* tdbb)
{ {
fb_assert(stateLock); fb_assert(stateLock);
LCK_convert(tdbb, stateLock, CRYPT_RELEASE, LCK_NO_WAIT); LCK_convert(tdbb, stateLock, CRYPT_RELEASE, LCK_NO_WAIT);
} }
bool CryptoManager::internalAttach(thread_db* tdbb, Attachment* att, bool
consume)
{
bool fLoad = false, fProvide = false;
for (GetPlugins<IKeyHolderPlugin> keyControl(IPluginManager::TYPE
_KEY_HOLDER, dbb.dbb_config);
keyControl.hasData(); keyControl.next())
{
// check does keyHolder want to provide a key for us
IKeyHolderPlugin* keyHolder = keyControl.plugin();
FbLocalStatus st;
int keyCallbackRc = keyHolder->keyCallback(&st, att->att_
crypt_callback);
st.check();
if (!keyCallbackRc)
continue;
// validate a key
AutoPlugin<IDbCryptPlugin> crypt(checkFactory->makeInstan
ce());
setDbInfo(crypt);
crypt->setKey(&st, 1, &keyHolder, keyName.c_str());
if (st.isSuccess())
{
try
{
if (checkValidation(crypt))
fLoad = true;
}
catch (const Exception&)
{ } // Ignore possible errors, contin
ue analysis
if (fLoad)
fProvide = !keyHolder->useOnlyOwnKeys(&st
);
break;
}
}
// Apply results
if (fProvide)
keyProviders.push(att);
else if (consume && !fLoad)
keyConsumers.push(att);
return fLoad;
}
void CryptoManager::attach(thread_db* tdbb, Attachment* att) void CryptoManager::attach(thread_db* tdbb, Attachment* att)
{ {
keyHolderPlugins.attach(att, dbb.dbb_config); if (checkFactory)
{
MutexLockGuard g(holdersMutex, FB_FUNCTION);
Factory* f = checkFactory; if (!internalAttach(tdbb, att, false))
{
if (keyProviders.getCount() == 0)
(Arg::Gds(isc_random) << "Missing correct
crypt key").raise();
keyConsumers.push(att);
}
}
lockAndReadHeader(tdbb, CRYPT_HDR_INIT); lockAndReadHeader(tdbb, CRYPT_HDR_INIT);
}
void CryptoManager::detach(thread_db* tdbb, Attachment* att)
{
if (!checkFactory)
return;
if (f && f == checkFactory) MutexLockGuard g(holdersMutex, FB_FUNCTION);
for (unsigned n = 0; n < keyConsumers.getCount(); ++n)
{ {
if (!keyHolderPlugins.validateNewAttachment(att, keyName) if (keyConsumers[n] == att)
) {
(Arg::Gds(isc_bad_crypt_key) << keyName).raise(); keyConsumers.remove(n);
return;
}
}
for (unsigned n = 0; n < keyProviders.getCount(); ++n)
{
if (keyProviders[n] == att)
{
keyProviders.remove(n);
if (keyProviders.getCount() == 0)
shutdownConsumers(tdbb);
return;
}
} }
} }
void CryptoManager::terminateCryptThread(thread_db*, bool wait) void CryptoManager::terminateCryptThread(thread_db*, bool wait)
{ {
down = true; down = true;
if (wait && cryptThreadId) if (wait && cryptThreadId)
{ {
Thread::waitForCompletion(cryptThreadId); Thread::waitForCompletion(cryptThreadId);
cryptThreadId = 0; cryptThreadId = 0;
skipping to change at line 818 skipping to change at line 967
// Need real attachment in order to make classic mode happy // Need real attachment in order to make classic mode happy
ClumpletWriter writer(ClumpletReader::Tagged, MAX _DPB_SIZE, isc_dpb_version1); ClumpletWriter writer(ClumpletReader::Tagged, MAX _DPB_SIZE, isc_dpb_version1);
writer.insertString(isc_dpb_user_name, "SYSDBA"); writer.insertString(isc_dpb_user_name, "SYSDBA");
writer.insertByte(isc_dpb_no_db_triggers, TRUE); writer.insertByte(isc_dpb_no_db_triggers, TRUE);
// Avoid races with release_attachment() in jrd.c pp // Avoid races with release_attachment() in jrd.c pp
MutexEnsureUnlock releaseGuard(cryptAttMutex, FB_ FUNCTION); MutexEnsureUnlock releaseGuard(cryptAttMutex, FB_ FUNCTION);
releaseGuard.enter(); releaseGuard.enter();
if (!down) if (!down)
{ {
RefPtr<JAttachment> jAtt(REF_NO_INCR, dbb.dbb_pro AutoPlugin<JProvider> jInstance(JProvider::getIns
vider->attachDatabase(&status_vector, tance());
dbb.dbb_filename.c_str(), writer.getBuffe jInstance->setDbCryptCallback(&status_vector, dbb
rLength(), writer.getBuffer())); .dbb_callback);
check(&status_vector);
RefPtr<JAttachment> jAtt(REF_NO_INCR, jInstance->
attachDatabase(&status_vector,
dbb.dbb_database_name.c_str(), writer.get
BufferLength(), writer.getBuffer()));
check(&status_vector); check(&status_vector);
MutexLockGuard attGuard(*(jAtt->getStable()->getM utex()), FB_FUNCTION); MutexLockGuard attGuard(*(jAtt->getStable()->getM utex()), FB_FUNCTION);
Attachment* att = jAtt->getHandle(); Attachment* att = jAtt->getHandle();
if (!att) if (!att)
Arg::Gds(isc_att_shutdown).raise(); Arg::Gds(isc_att_shutdown).raise();
att->att_flags |= ATT_crypt_thread; att->att_flags |= ATT_crypt_thread;
releaseGuard.leave(); releaseGuard.leave();
ThreadContextHolder tdbb(att->att_database, att, &status_vector); ThreadContextHolder tdbb(att->att_database, att, &status_vector);
skipping to change at line 1051 skipping to change at line 1204
return FAILED_IO; return FAILED_IO;
if (page->pag_flags & Ods::crypted_page) if (page->pag_flags & Ods::crypted_page)
{ {
if (!cryptPlugin) if (!cryptPlugin)
{ {
Arg::Gds(isc_decrypt_error).copyTo(sv); Arg::Gds(isc_decrypt_error).copyTo(sv);
return FAILED_CRYPT; return FAILED_CRYPT;
} }
cryptPlugin->decrypt(sv, dbb.dbb_page_size - sizeof(Ods:: FbLocalStatus ls;
pag), cryptPlugin->decrypt(&ls, dbb.dbb_page_size - sizeof(Ods:
:pag),
&page[1], &page[1]); &page[1], &page[1]);
if (sv->getState() & IStatus::STATE_ERRORS) if (ls->getState() & IStatus::STATE_ERRORS)
{
ERR_post_nothrow(&ls, sv);
return FAILED_CRYPT; return FAILED_CRYPT;
}
} }
return SUCCESS_ALL; return SUCCESS_ALL;
} }
bool CryptoManager::write(thread_db* tdbb, FbStatusVector* sv, Ods::pag* page, IOCallback* io) bool CryptoManager::write(thread_db* tdbb, FbStatusVector* sv, Ods::pag* page, IOCallback* io)
{ {
// Code calling us is not ready to process exceptions correctly // Code calling us is not ready to process exceptions correctly
// Therefore use old (status vector based) method // Therefore use old (status vector based) method
try try
skipping to change at line 1136 skipping to change at line 1293
if (crypt && Ods::pag_crypt_page[page->pag_type]) if (crypt && Ods::pag_crypt_page[page->pag_type])
{ {
fb_assert(cryptPlugin); fb_assert(cryptPlugin);
if (!cryptPlugin) if (!cryptPlugin)
{ {
Arg::Gds(isc_encrypt_error).copyTo(sv); Arg::Gds(isc_encrypt_error).copyTo(sv);
return FAILED_CRYPT; return FAILED_CRYPT;
} }
FbLocalStatus ls;
to[0] = page[0]; to[0] = page[0];
cryptPlugin->encrypt(sv, dbb.dbb_page_size - sizeof(Ods:: pag), cryptPlugin->encrypt(&ls, dbb.dbb_page_size - sizeof(Ods: :pag),
&page[1], &to[1]); &page[1], &to[1]);
if (sv->getState() & IStatus::STATE_ERRORS) if (ls->getState() & IStatus::STATE_ERRORS)
{
ERR_post_nothrow(&ls, sv);
return FAILED_CRYPT; return FAILED_CRYPT;
}
to->pag_flags |= Ods::crypted_page; // Mark p age that is going to be written as encrypted to->pag_flags |= Ods::crypted_page; // Mark p age that is going to be written as encrypted
page->pag_flags |= Ods::crypted_page; // Set the mark f or page in cache as well page->pag_flags |= Ods::crypted_page; // Set the mark f or page in cache as well
dest = to; // Choose correct destination dest = to; // Choose correct destination
} }
else else
{ {
page->pag_flags &= ~Ods::crypted_page; page->pag_flags &= ~Ods::crypted_page;
} }
skipping to change at line 1181 skipping to change at line 1342
ULONG CryptoManager::getLastPage(thread_db* tdbb) ULONG CryptoManager::getLastPage(thread_db* tdbb)
{ {
return PAG_last_page(tdbb) + 1; return PAG_last_page(tdbb) + 1;
} }
UCHAR CryptoManager::getCurrentState() const UCHAR CryptoManager::getCurrentState() const
{ {
return (crypt ? fb_info_crypt_encrypted : 0) | (process ? fb_info _crypt_process : 0); return (crypt ? fb_info_crypt_encrypted : 0) | (process ? fb_info _crypt_process : 0);
} }
void CryptoManager::KeyHolderPlugins::attach(Attachment* att, const Confi const char* CryptoManager::getKeyName() const
g* config)
{
MutexLockGuard g(holdersMutex, FB_FUNCTION);
for (GetPlugins<IKeyHolderPlugin> keyControl(IPluginManager::TYPE
_KEY_HOLDER, config);
keyControl.hasData(); keyControl.next())
{
IKeyHolderPlugin* keyPlugin = keyControl.plugin();
FbLocalStatus st;
bool flProvide = false;
if (keyPlugin->keyCallback(&st, att->att_crypt_callback))
flProvide = true;
else
{
st.check();
flProvide = !keyPlugin->useOnlyOwnKeys(&st);
// Ignore error condition to support old plugins
}
if (flProvide)
{
// holder is going to provide a key
PerAttHolders* pa = NULL;
for (unsigned i = 0; i < knownHolders.getCount();
++i)
{
if (knownHolders[i].first == att)
{
pa = &knownHolders[i];
break;
}
}
if (!pa)
{
pa = &(knownHolders.add());
pa->first = att;
}
if (pa)
{
pa->second.add(keyPlugin);
keyPlugin->addRef();
}
}
}
}
void CryptoManager::KeyHolderPlugins::detach(Attachment* att)
{
MutexLockGuard g(holdersMutex, FB_FUNCTION);
for (unsigned i = 0; i < knownHolders.getCount(); ++i)
{
if (knownHolders[i].first == att)
{
releaseHolders(knownHolders[i]);
knownHolders.remove(i);
break;
}
}
}
void CryptoManager::KeyHolderPlugins::releaseHolders(PerAttHolders& pa)
{
unsigned j = 0;
for (; j < pa.second.getCount(); ++j)
{
PluginManagerInterfacePtr()->releasePlugin(pa.second[j]);
}
pa.second.removeCount(0, j);
}
void CryptoManager::KeyHolderPlugins::init(IDbCryptPlugin* crypt, const M
etaName& keyName)
{
MutexLockGuard g(holdersMutex, FB_FUNCTION);
Firebird::HalfStaticArray<Firebird::IKeyHolderPlugin*, 64> holder
sVector;
for (unsigned i = 0; i < knownHolders.getCount(); ++i)
{
PerAttHolders pa = knownHolders[i];
for (unsigned j = 0; j < pa.second.getCount(); ++j)
holdersVector.push(pa.second[j]);
}
FbLocalStatus st;
crypt->setKey(&st, holdersVector.getCount(), holdersVector.begin(
), keyName.c_str());
st.check();
}
bool CryptoManager::KeyHolderPlugins::validateHoldersGroup(PerAttHolders&
pa, const MetaName& keyName)
{
FbLocalStatus st;
fb_assert(holdersMutex.locked());
for (unsigned j = 0; j < pa.second.getCount(); ++j)
{
IKeyHolderPlugin* keyHolder = pa.second[j];
if (!keyHolder->useOnlyOwnKeys(&st))
return true;
if (validateHolder(keyHolder, keyName))
return true;
}
return false;
}
bool CryptoManager::KeyHolderPlugins::validateNewAttachment(Attachment* a
tt, const MetaName& keyName)
{
FbLocalStatus st;
MutexLockGuard g(holdersMutex, FB_FUNCTION);
// Check for current attachment
for (unsigned i = 0; i < knownHolders.getCount(); ++i)
{
PerAttHolders& pa = knownHolders[i];
if (pa.first == att)
{
bool empty = (pa.second.getCount() == 0);
bool result = empty ? false : validateHoldersGrou
p(pa, keyName);
if (empty)
break;
return result;
}
}
// Special case - holders not needed at all
return validateHolder(NULL, keyName);
}
bool CryptoManager::KeyHolderPlugins::validateHolder(IKeyHolderPlugin* ke
yHolder, const MetaName& keyName)
{ {
fb_assert(mgr->checkFactory); return keyName.c_str();
if (!mgr->checkFactory)
return false;
FbLocalStatus st;
AutoPtr<IDbCryptPlugin, ReleasePlugin> crypt(mgr->checkFactory->m
akeInstance());
crypt->setKey(&st, keyHolder ? 1 : 0, &keyHolder, keyName.c_str()
);
if (st.isSuccess())
{
try
{
if (mgr->checkValidation(crypt))
return true;
}
catch (const Exception&)
{ } // Ignore possible errors, continue analy
sis
}
return false;
}
void CryptoManager::KeyHolderPlugins::validateExistingAttachments(const M
etaName& keyName)
{
FbLocalStatus st;
// Special case - holders not needed at all
if (validateHolder(NULL, keyName))
return;
// Loop through whole attachments list of DBB, shutdown attachmen
ts missing any holders
fb_assert(!mgr->dbb.dbb_sync.isLocked());
MutexLockGuard g(holdersMutex, FB_FUNCTION);
SyncLockGuard dsGuard(&mgr->dbb.dbb_sync, SYNC_EXCLUSIVE, FB_FUNC
TION);
for (Attachment* att = mgr->dbb.dbb_attachments; att; att = att->
att_next)
{
bool found = false;
for (unsigned i = 0; i < knownHolders.getCount(); ++i)
{
if (knownHolders[i].first == att)
{
found = true;
break;
}
}
if (!found)
att->signalShutdown();
}
// Loop through internal attachments list closing one missing val
id holders
for (unsigned i = 0; i < knownHolders.getCount(); ++i)
{
if (!validateHoldersGroup(knownHolders[i], keyName))
knownHolders[i].first->signalShutdown();
}
} }
void CryptoManager::addClumplet(string& signature, ClumpletReader& block, UCHAR tag) void CryptoManager::addClumplet(string& signature, ClumpletReader& block, UCHAR tag)
{ {
if (block.find(tag)) if (block.find(tag))
{ {
string tmp; string tmp;
block.getString(tmp); block.getString(tmp);
signature += ' '; signature += ' ';
signature += tmp; signature += tmp;
 End of changes. 28 change blocks. 
251 lines changed or deleted 227 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)