mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 18:43:02 +01:00
Implemented CORE-5374: Make database name available to crypt plugin
This commit is contained in:
parent
d079557458
commit
b76648f1f6
@ -81,6 +81,13 @@ public:
|
||||
void decrypt(CheckStatusWrapper* status, unsigned int length, const void* from, void* to);
|
||||
void setKey(CheckStatusWrapper* status, unsigned int length, IKeyHolderPlugin** sources,
|
||||
const char* keyName);
|
||||
// One if free to ignore passed info when not needed
|
||||
void setInfo(CheckStatusWrapper* status, IDbCryptInfo* info)
|
||||
{
|
||||
#ifdef NEVERDEF
|
||||
fprintf(stderr, "DbInfo: name is %s\n", info->getDatabaseFullPath(status));
|
||||
#endif
|
||||
}
|
||||
|
||||
int release()
|
||||
{
|
||||
|
@ -735,6 +735,13 @@ interface KeyHolderPlugin : PluginBase
|
||||
}
|
||||
|
||||
|
||||
// Information calls available for crypt plugin
|
||||
interface DbCryptInfo : ReferenceCounted
|
||||
{
|
||||
const string getDatabaseFullPath(Status status);
|
||||
}
|
||||
|
||||
|
||||
interface DbCryptPlugin : PluginBase
|
||||
{
|
||||
// When database crypt plugin is loaded, setKey() is called to provide information
|
||||
@ -745,6 +752,10 @@ interface DbCryptPlugin : PluginBase
|
||||
void setKey(Status status, uint length, KeyHolderPlugin* sources, const string keyName);
|
||||
void encrypt(Status status, uint length, const void* from, void* to);
|
||||
void decrypt(Status status, uint length, const void* from, void* to);
|
||||
|
||||
version: // 3.0.1 => 4.0
|
||||
// Crypto manager may pass some additional info to plugin
|
||||
void setInfo(Status status, DbCryptInfo info);
|
||||
}
|
||||
|
||||
|
||||
|
@ -73,6 +73,7 @@ namespace Firebird
|
||||
class IWireCryptPlugin;
|
||||
class ICryptKeyCallback;
|
||||
class IKeyHolderPlugin;
|
||||
class IDbCryptInfo;
|
||||
class IDbCryptPlugin;
|
||||
class IExternalContext;
|
||||
class IExternalResultSet;
|
||||
@ -2936,6 +2937,36 @@ namespace Firebird
|
||||
}
|
||||
};
|
||||
|
||||
class IDbCryptInfo : public IReferenceCounted
|
||||
{
|
||||
public:
|
||||
struct VTable : public IReferenceCounted::VTable
|
||||
{
|
||||
const char* (CLOOP_CARG *getDatabaseFullPath)(IDbCryptInfo* self, IStatus* status) throw();
|
||||
};
|
||||
|
||||
protected:
|
||||
IDbCryptInfo(DoNotInherit)
|
||||
: IReferenceCounted(DoNotInherit())
|
||||
{
|
||||
}
|
||||
|
||||
~IDbCryptInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static const unsigned VERSION = 3;
|
||||
|
||||
template <typename StatusType> const char* getDatabaseFullPath(StatusType* status)
|
||||
{
|
||||
StatusType::clearException(status);
|
||||
const char* ret = static_cast<VTable*>(this->cloopVTable)->getDatabaseFullPath(this, status);
|
||||
StatusType::checkException(status);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
class IDbCryptPlugin : public IPluginBase
|
||||
{
|
||||
public:
|
||||
@ -2944,6 +2975,7 @@ namespace Firebird
|
||||
void (CLOOP_CARG *setKey)(IDbCryptPlugin* self, IStatus* status, unsigned length, IKeyHolderPlugin** sources, const char* keyName) throw();
|
||||
void (CLOOP_CARG *encrypt)(IDbCryptPlugin* self, IStatus* status, unsigned length, const void* from, void* to) throw();
|
||||
void (CLOOP_CARG *decrypt)(IDbCryptPlugin* self, IStatus* status, unsigned length, const void* from, void* to) throw();
|
||||
void (CLOOP_CARG *setInfo)(IDbCryptPlugin* self, IStatus* status, IDbCryptInfo* info) throw();
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -2957,7 +2989,7 @@ namespace Firebird
|
||||
}
|
||||
|
||||
public:
|
||||
static const unsigned VERSION = 4;
|
||||
static const unsigned VERSION = 5;
|
||||
|
||||
template <typename StatusType> void setKey(StatusType* status, unsigned length, IKeyHolderPlugin** sources, const char* keyName)
|
||||
{
|
||||
@ -2979,6 +3011,19 @@ namespace Firebird
|
||||
static_cast<VTable*>(this->cloopVTable)->decrypt(this, status, length, from, to);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
|
||||
template <typename StatusType> void setInfo(StatusType* status, IDbCryptInfo* info)
|
||||
{
|
||||
if (cloopVTable->version < 5)
|
||||
{
|
||||
StatusType::setVersionError(status, "IDbCryptPlugin", cloopVTable->version, 5);
|
||||
StatusType::checkException(status);
|
||||
return;
|
||||
}
|
||||
StatusType::clearException(status);
|
||||
static_cast<VTable*>(this->cloopVTable)->setInfo(this, status, info);
|
||||
StatusType::checkException(status);
|
||||
}
|
||||
};
|
||||
|
||||
class IExternalContext : public IVersioned
|
||||
@ -11289,6 +11334,85 @@ namespace Firebird
|
||||
virtual ICryptKeyCallback* keyHandle(StatusType* status, const char* keyName) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
class IDbCryptInfoBaseImpl : public Base
|
||||
{
|
||||
public:
|
||||
typedef IDbCryptInfo Declaration;
|
||||
|
||||
IDbCryptInfoBaseImpl(DoNotInherit = DoNotInherit())
|
||||
{
|
||||
static struct VTableImpl : Base::VTable
|
||||
{
|
||||
VTableImpl()
|
||||
{
|
||||
this->version = Base::VERSION;
|
||||
this->addRef = &Name::cloopaddRefDispatcher;
|
||||
this->release = &Name::cloopreleaseDispatcher;
|
||||
this->getDatabaseFullPath = &Name::cloopgetDatabaseFullPathDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
this->cloopVTable = &vTable;
|
||||
}
|
||||
|
||||
static const char* CLOOP_CARG cloopgetDatabaseFullPathDispatcher(IDbCryptInfo* self, IStatus* status) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
return static_cast<Name*>(self)->Name::getDatabaseFullPath(&status2);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
return static_cast<const char*>(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) throw()
|
||||
{
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::addRef();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int CLOOP_CARG cloopreleaseDispatcher(IReferenceCounted* self) throw()
|
||||
{
|
||||
try
|
||||
{
|
||||
return static_cast<Name*>(self)->Name::release();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(0);
|
||||
return static_cast<int>(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base = IReferenceCountedImpl<Name, StatusType, Inherit<IVersionedImpl<Name, StatusType, Inherit<IDbCryptInfo> > > > >
|
||||
class IDbCryptInfoImpl : public IDbCryptInfoBaseImpl<Name, StatusType, Base>
|
||||
{
|
||||
protected:
|
||||
IDbCryptInfoImpl(DoNotInherit = DoNotInherit())
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~IDbCryptInfoImpl()
|
||||
{
|
||||
}
|
||||
|
||||
virtual const char* getDatabaseFullPath(StatusType* status) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
class IDbCryptPluginBaseImpl : public Base
|
||||
{
|
||||
@ -11309,6 +11433,7 @@ namespace Firebird
|
||||
this->setKey = &Name::cloopsetKeyDispatcher;
|
||||
this->encrypt = &Name::cloopencryptDispatcher;
|
||||
this->decrypt = &Name::cloopdecryptDispatcher;
|
||||
this->setInfo = &Name::cloopsetInfoDispatcher;
|
||||
}
|
||||
} vTable;
|
||||
|
||||
@ -11357,6 +11482,20 @@ namespace Firebird
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopsetInfoDispatcher(IDbCryptPlugin* self, IStatus* status, IDbCryptInfo* info) throw()
|
||||
{
|
||||
StatusType status2(status);
|
||||
|
||||
try
|
||||
{
|
||||
static_cast<Name*>(self)->Name::setInfo(&status2, info);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
StatusType::catchException(&status2);
|
||||
}
|
||||
}
|
||||
|
||||
static void CLOOP_CARG cloopsetOwnerDispatcher(IPluginBase* self, IReferenceCounted* r) throw()
|
||||
{
|
||||
try
|
||||
@ -11424,6 +11563,7 @@ namespace Firebird
|
||||
virtual void setKey(StatusType* status, unsigned length, IKeyHolderPlugin** sources, const char* keyName) = 0;
|
||||
virtual void encrypt(StatusType* status, unsigned length, const void* from, void* to) = 0;
|
||||
virtual void decrypt(StatusType* status, unsigned length, const void* from, void* to) = 0;
|
||||
virtual void setInfo(StatusType* status, IDbCryptInfo* info) = 0;
|
||||
};
|
||||
|
||||
template <typename Name, typename StatusType, typename Base>
|
||||
|
@ -266,6 +266,7 @@ namespace Jrd {
|
||||
sync(this),
|
||||
keyName(getPool()),
|
||||
keyHolderPlugins(getPool()),
|
||||
dbInfo(FB_NEW DbInfo(this)),
|
||||
cryptThreadId(0),
|
||||
cryptPlugin(NULL),
|
||||
dbb(*tdbb->getDatabase()),
|
||||
@ -288,6 +289,8 @@ namespace Jrd {
|
||||
|
||||
delete stateLock;
|
||||
delete threadLock;
|
||||
|
||||
dbInfo->destroy();
|
||||
}
|
||||
|
||||
void CryptoManager::shutdown(thread_db* tdbb)
|
||||
@ -396,6 +399,16 @@ namespace Jrd {
|
||||
|
||||
// do not assign cryptPlugin directly before key init complete
|
||||
IDbCryptPlugin* p = cryptControl.plugin();
|
||||
|
||||
FbLocalStatus status;
|
||||
p->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);
|
||||
}
|
||||
|
||||
keyHolderPlugins.init(p, keyName.c_str());
|
||||
cryptPlugin = p;
|
||||
cryptPlugin->addRef();
|
||||
@ -1319,4 +1332,11 @@ namespace Jrd {
|
||||
}
|
||||
}
|
||||
|
||||
const char* CryptoManager::DbInfo::getDatabaseFullPath(Firebird::CheckStatusWrapper* status)
|
||||
{
|
||||
if (!cryptoManager)
|
||||
return NULL;
|
||||
return cryptoManager->dbb.dbb_filename.c_str();
|
||||
}
|
||||
|
||||
} // namespace Jrd
|
||||
|
@ -357,6 +357,37 @@ private:
|
||||
Firebird::ObjectsArray<HolderAttachments> knownHolders;
|
||||
};
|
||||
|
||||
class DbInfo;
|
||||
friend class DbInfo;
|
||||
|
||||
class DbInfo FB_FINAL : public Firebird::RefCntIface<Firebird::IDbCryptInfoImpl<DbInfo, Firebird::CheckStatusWrapper>>
|
||||
{
|
||||
public:
|
||||
DbInfo(CryptoManager* cm)
|
||||
: cryptoManager(cm)
|
||||
{ }
|
||||
|
||||
void destroy()
|
||||
{
|
||||
cryptoManager = NULL;
|
||||
}
|
||||
|
||||
// IDbCryptInfo implementation
|
||||
const char* getDatabaseFullPath(Firebird::CheckStatusWrapper* status);
|
||||
|
||||
int release()
|
||||
{
|
||||
if (--refCounter != 0)
|
||||
return 1;
|
||||
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
CryptoManager* cryptoManager;
|
||||
};
|
||||
|
||||
static int blockingAstChangeCryptState(void*);
|
||||
void blockingAstChangeCryptState();
|
||||
|
||||
@ -383,6 +414,7 @@ private:
|
||||
ULONG currentPage;
|
||||
Firebird::Mutex pluginLoadMtx, cryptThreadMtx;
|
||||
KeyHolderPlugins keyHolderPlugins;
|
||||
Firebird::RefPtr<DbInfo> dbInfo;
|
||||
Thread::Handle cryptThreadId;
|
||||
Firebird::IDbCryptPlugin* cryptPlugin;
|
||||
Database& dbb;
|
||||
|
Loading…
Reference in New Issue
Block a user