| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /*
- * PROGRAM: Firebird samples.
- * MODULE: CryptKeyHolder.cpp
- * DESCRIPTION: Sample of how key holder 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 "../interfaces/ifaceExamples.h"
- namespace
- {
- IMaster* master = NULL;
- class PluginModule : public IPluginModuleImpl<PluginModule, CheckStatusWrapper>
- {
- public:
- PluginModule()
- : pluginManager(NULL)
- { }
- ~PluginModule()
- {
- if (pluginManager)
- {
- pluginManager->unregisterModule(this);
- doClean();
- }
- }
- void registerMe(IPluginManager* m)
- {
- pluginManager = m;
- pluginManager->registerModule(this);
- }
- void doClean()
- {
- pluginManager = NULL;
- }
- void threadDetach() {}
- private:
- IPluginManager* pluginManager;
- };
- class CryptKeyHolder : public IKeyHolderPluginImpl<CryptKeyHolder, CheckStatusWrapper>
- {
- public:
- explicit CryptKeyHolder(IPluginConfig* cnf) throw()
- : callbackInterface(this), named(NULL), tempStatus(master->getStatus()),
- config(cnf), key(0), owner(NULL)
- {
- config->addRef();
- }
- ~CryptKeyHolder()
- {
- config->release();
- tempStatus.dispose();
- }
- // IKeyHolderPlugin implementation
- int keyCallback(CheckStatusWrapper* status, ICryptKeyCallback* callback);
- ICryptKeyCallback* keyHandle(CheckStatusWrapper* status, const char* keyName);
- ICryptKeyCallback* chainHandle(CheckStatusWrapper* status);
- int release()
- {
- if (--refCounter == 0)
- {
- delete this;
- return 0;
- }
- return 1;
- }
- void addRef()
- {
- ++refCounter;
- }
- void setOwner(Firebird::IReferenceCounted* o)
- {
- owner = o;
- }
- IReferenceCounted* getOwner()
- {
- return owner;
- }
- ISC_UCHAR getKey()
- {
- if (!key)
- keyCallback(&tempStatus, NULL);
- return key;
- }
- FB_BOOLEAN useOnlyOwnKeys(CheckStatusWrapper* status)
- {
- IConfigEntry* e = getEntry(status, "OnlyOwnKey");
- if (!e)
- return FB_TRUE; // safe default
- FB_BOOLEAN rc = e->getBoolValue();
- e->release();
- return rc;
- }
- private:
- class CallbackInterface : public ICryptKeyCallbackImpl<CallbackInterface, CheckStatusWrapper>
- {
- public:
- explicit CallbackInterface(CryptKeyHolder* p)
- : holder(p)
- { }
- unsigned int callback(unsigned int, const void*, unsigned int length, void* buffer)
- {
- ISC_UCHAR k = holder->getKey();
- if (!k)
- {
- return 0;
- }
- if (length > 0 && buffer)
- {
- memcpy(buffer, &k, 1);
- }
- return 1;
- }
- private:
- CryptKeyHolder* holder;
- };
- class NamedCallback : public ICryptKeyCallbackImpl<NamedCallback, CheckStatusWrapper>
- {
- public:
- NamedCallback(NamedCallback* n, const char* nm, ISC_UCHAR k)
- : next(n), key(k)
- {
- strncpy(name, nm, sizeof(name));
- name[sizeof(name) - 1] = 0;
- }
- unsigned int callback(unsigned int, const void*, unsigned int length, void* buffer)
- {
- memcpy(buffer, &key, 1);
- return 1;
- }
- ~NamedCallback()
- {
- delete next;
- }
- char name[32];
- NamedCallback* next;
- ISC_UCHAR key;
- };
- CallbackInterface callbackInterface;
- NamedCallback *named;
- CheckStatusWrapper tempStatus;
- IPluginConfig* config;
- ISC_UCHAR key;
- FbSampleAtomic refCounter;
- IReferenceCounted* owner;
- IConfigEntry* getEntry(CheckStatusWrapper* status, const char* entryName);
- };
- IConfigEntry* CryptKeyHolder::getEntry(CheckStatusWrapper* status, const char* entryName)
- {
- IConfig* def = config->getDefaultConfig(status);
- if (status->getState() & Firebird::IStatus::STATE_ERRORS)
- return NULL;
- IConfigEntry* confEntry = def->find(status, entryName);
- def->release();
- if (status->getState() & Firebird::IStatus::STATE_ERRORS)
- return NULL;
- return confEntry;
- }
- int CryptKeyHolder::keyCallback(CheckStatusWrapper* status, ICryptKeyCallback* callback)
- {
- if (key != 0)
- return 1;
- IConfigEntry* confEntry = getEntry(status, "Auto");
- if (confEntry)
- {
- FB_BOOLEAN b = confEntry->getBoolValue();
- confEntry->release();
- if (b)
- {
- confEntry = getEntry(status, "Key");
- if (confEntry)
- {
- key = confEntry->getIntValue();
- confEntry->release();
- }
- else
- key = 0x5a;
- return 1;
- }
- }
- if (callback && callback->callback(0, NULL, 1, &key) != 1)
- {
- key = 0;
- return 0;
- }
- return 1;
- }
- ICryptKeyCallback* CryptKeyHolder::keyHandle(CheckStatusWrapper* status, const char* keyName)
- {
- if (keyName[0] == 0)
- return &callbackInterface;
- for (NamedCallback* n = named; n; n = n->next)
- {
- if (strcmp(keyName, n->name) == 0)
- return n;
- }
- char kn[40];
- strcpy(kn, "Key");
- strncat(kn, keyName, sizeof(kn) - 3 - 1);
- kn[sizeof(kn) - 1] = 0;
- IConfigEntry* confEntry = getEntry(status, kn);
- if (confEntry)
- {
- int k = confEntry->getIntValue();
- confEntry->release();
- if (k > 0 && k < 256)
- {
- named = new NamedCallback(named, keyName, static_cast<ISC_UCHAR>(k));
- return named;
- }
- }
- return NULL;
- }
- ICryptKeyCallback* CryptKeyHolder::chainHandle(CheckStatusWrapper* status)
- {
- return &callbackInterface;
- }
- class Factory : public IPluginFactoryImpl<Factory, CheckStatusWrapper>
- {
- public:
- IPluginBase* createPlugin(CheckStatusWrapper* status, IPluginConfig* factoryParameter)
- {
- CryptKeyHolder* p = new CryptKeyHolder(factoryParameter);
- p->addRef();
- return p;
- }
- };
- PluginModule module;
- Factory factory;
- } // anonymous namespace
- extern "C" FB_DLL_EXPORT void FB_PLUGIN_ENTRY_POINT(IMaster* m)
- {
- master = m;
- IPluginManager* pluginManager = master->getPluginManager();
- module.registerMe(pluginManager);
- pluginManager->registerPluginFactory(IPluginManager::TYPE_KEY_HOLDER, "fbSampleKeyHolder",
- &factory);
- }
|