mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 21:23:04 +01:00
d513daa574
Errors and warnings are processed in IStatus independently. Completion code is moved away from IStatus and returned directly by appropriate functions. Replaced isSuccess() with more generic function getStatus(), which sets appropriate bits in returned value when errors/warnings are present. Also use same style when returning bytes' array and it's length in different interfaces.
293 lines
5.2 KiB
C++
293 lines
5.2 KiB
C++
/*
|
|
* PROGRAM: Firebird samples.
|
|
* MODULE: DbCrypt.cpp
|
|
* DESCRIPTION: Sample of how diskcrypt may be written.
|
|
*
|
|
* The contents of this file are subject to the Initial
|
|
* Developer's Public License Version 1.0 (the "License");
|
|
* you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
|
|
*
|
|
* Software distributed under the License is distributed AS IS,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing rights
|
|
* and limitations under the License.
|
|
*
|
|
* The Original Code was created by Alex Peshkov
|
|
* for the Firebird Open Source RDBMS project.
|
|
*
|
|
* Copyright (c) 2012 Alex Peshkov <peshkoff at mail.ru>
|
|
* and all contributors signed below.
|
|
*
|
|
* All Rights Reserved.
|
|
* Contributor(s): ______________________________________.
|
|
*/
|
|
|
|
#include "firebird.h"
|
|
#include "firebird/Crypt.h"
|
|
|
|
#include "../common/classes/fb_atomic.h"
|
|
|
|
using namespace Firebird;
|
|
|
|
namespace
|
|
{
|
|
|
|
IMaster* master = NULL;
|
|
IPluginManager* pluginManager = NULL;
|
|
|
|
class PluginModule : public IPluginModule
|
|
{
|
|
public:
|
|
PluginModule()
|
|
: flag(false)
|
|
{ }
|
|
|
|
void registerMe()
|
|
{
|
|
pluginManager->registerModule(this);
|
|
flag = true;
|
|
}
|
|
|
|
~PluginModule()
|
|
{
|
|
if (flag)
|
|
{
|
|
pluginManager->unregisterModule(this);
|
|
doClean();
|
|
}
|
|
}
|
|
|
|
int FB_CARG getVersion()
|
|
{
|
|
return FB_PLUGIN_MODULE_VERSION;
|
|
}
|
|
|
|
IPluginModule* FB_CARG getModule()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
void FB_CARG doClean()
|
|
{
|
|
flag = false;
|
|
}
|
|
|
|
private:
|
|
bool flag;
|
|
};
|
|
|
|
PluginModule module;
|
|
|
|
class DbCrypt : public IDbCryptPlugin
|
|
{
|
|
public:
|
|
explicit DbCrypt(IPluginConfig* cnf)
|
|
: config(cnf), key(0), owner(NULL)
|
|
{
|
|
config->addRef();
|
|
}
|
|
|
|
~DbCrypt()
|
|
{
|
|
config->release();
|
|
}
|
|
|
|
// ICryptPlugin implementation
|
|
void FB_CARG encrypt(IStatus* status, unsigned int length, const void* from, void* to);
|
|
void FB_CARG decrypt(IStatus* status, unsigned int length, const void* from, void* to);
|
|
void FB_CARG setKey(IStatus* status, unsigned int length, IKeyHolderPlugin** sources);
|
|
|
|
int FB_CARG release()
|
|
{
|
|
if (--refCounter == 0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void FB_CARG addRef()
|
|
{
|
|
++refCounter;
|
|
}
|
|
|
|
int FB_CARG getVersion()
|
|
{
|
|
return FB_DBCRYPT_PLUGIN_VERSION;
|
|
}
|
|
|
|
IPluginModule* FB_CARG getModule()
|
|
{
|
|
return &module;
|
|
}
|
|
|
|
void FB_CARG setOwner(IRefCounted* o)
|
|
{
|
|
owner = o;
|
|
}
|
|
|
|
IRefCounted* FB_CARG getOwner()
|
|
{
|
|
return owner;
|
|
}
|
|
|
|
private:
|
|
IPluginConfig* config;
|
|
UCHAR key;
|
|
|
|
AtomicCounter refCounter;
|
|
IRefCounted* owner;
|
|
|
|
void noKeyError(IStatus* status);
|
|
};
|
|
|
|
void DbCrypt::noKeyError(IStatus* status)
|
|
{
|
|
ISC_STATUS_ARRAY vector;
|
|
vector[0] = isc_arg_gds;
|
|
vector[1] = isc_random;
|
|
vector[2] = isc_arg_string;
|
|
vector[3] = (ISC_STATUS)"Key not set";
|
|
vector[4] = isc_arg_end;
|
|
status->setErrors(vector);
|
|
}
|
|
|
|
void FB_CARG DbCrypt::encrypt(IStatus* status, unsigned int length, const void* from, void* to)
|
|
{
|
|
status->init();
|
|
|
|
if (!key)
|
|
{
|
|
noKeyError(status);
|
|
return;
|
|
}
|
|
|
|
const UCHAR* f = static_cast<const UCHAR*>(from);
|
|
UCHAR* t = static_cast<UCHAR*>(to);
|
|
|
|
while (length--)
|
|
{
|
|
*t++ = (*f++) ^ key;
|
|
}
|
|
}
|
|
|
|
void FB_CARG DbCrypt::decrypt(IStatus* status, unsigned int length, const void* from, void* to)
|
|
{
|
|
status->init();
|
|
|
|
if (!key)
|
|
{
|
|
noKeyError(status);
|
|
return;
|
|
}
|
|
|
|
const UCHAR* f = static_cast<const UCHAR*>(from);
|
|
UCHAR* t = static_cast<UCHAR*>(to);
|
|
|
|
while (length--)
|
|
{
|
|
*t++ = (*f++) ^ key;
|
|
}
|
|
}
|
|
|
|
void FB_CARG DbCrypt::setKey(IStatus* status, unsigned int length, IKeyHolderPlugin** sources)
|
|
{
|
|
status->init();
|
|
|
|
if (key != 0)
|
|
return;
|
|
|
|
IConfig* def = config->getDefaultConfig(status);
|
|
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
|
|
return;
|
|
|
|
IConfigEntry* confEntry = def->find(status, "Auto");
|
|
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
|
|
{
|
|
def->release();
|
|
return;
|
|
}
|
|
|
|
if (confEntry)
|
|
{
|
|
char v = *(confEntry->getValue());
|
|
confEntry->release();
|
|
if (v == '1' || v == 'y' || v == 'Y' || v == 't' || v == 'T')
|
|
{
|
|
confEntry = def->find(status, "Value");
|
|
def->release();
|
|
if (confEntry)
|
|
{
|
|
v = confEntry->getIntValue();
|
|
confEntry->release();
|
|
if (v)
|
|
{
|
|
key = v;
|
|
return;
|
|
}
|
|
}
|
|
key = 0x5a;
|
|
return;
|
|
}
|
|
def->release();
|
|
}
|
|
|
|
for (unsigned n = 0; n < length; ++n)
|
|
{
|
|
ICryptKeyCallback* callback = sources[n]->keyHandle(status, "sample");
|
|
if (status->getStatus() & Firebird::IStatus::FB_HAS_ERRORS)
|
|
return;
|
|
|
|
if (callback && callback->callback(0, NULL, 1, &key) == 1)
|
|
return;
|
|
}
|
|
|
|
key = 0;
|
|
noKeyError(status);
|
|
}
|
|
|
|
class Factory : public IPluginFactory
|
|
{
|
|
public:
|
|
int FB_CARG getVersion()
|
|
{
|
|
return FB_PLUGIN_FACTORY_VERSION;
|
|
}
|
|
|
|
IPluginModule* FB_CARG getModule()
|
|
{
|
|
return &module;
|
|
}
|
|
|
|
IPluginBase* FB_CARG createPlugin(IStatus* status, IPluginConfig* factoryParameter)
|
|
{
|
|
try
|
|
{
|
|
DbCrypt* p = new DbCrypt(factoryParameter);
|
|
p->addRef();
|
|
return p;
|
|
}
|
|
catch (const Exception& ex)
|
|
{
|
|
ex.stuffException(status);
|
|
}
|
|
return NULL;
|
|
}
|
|
};
|
|
|
|
Factory factory;
|
|
|
|
} // anonymous namespace
|
|
|
|
extern "C" void FB_PLUGIN_ENTRY_POINT(IMaster* m)
|
|
{
|
|
master = m;
|
|
pluginManager = master->getPluginManager();
|
|
|
|
module.registerMe();
|
|
pluginManager->registerPluginFactory(PluginType::DbCrypt, "DbCrypt_example", &factory);
|
|
}
|