mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 06:03:02 +01:00
Fixed CORE-5082: Server does not validate correctness of user/password pair provided in EXECUTE STATEMENT operator
This commit is contained in:
parent
315332944b
commit
eacbf41269
@ -67,17 +67,17 @@ public:
|
||||
getPlugin();
|
||||
}
|
||||
|
||||
bool hasData()
|
||||
bool hasData() const
|
||||
{
|
||||
return currentPlugin;
|
||||
}
|
||||
|
||||
const char* name()
|
||||
const char* name() const
|
||||
{
|
||||
return hasData() ? pluginSet->getName() : NULL;
|
||||
}
|
||||
|
||||
P* plugin()
|
||||
P* plugin() const
|
||||
{
|
||||
return currentPlugin;
|
||||
}
|
||||
|
@ -119,4 +119,61 @@ int setGsecCode(int code, int operation)
|
||||
return GsecMsg17;
|
||||
}
|
||||
|
||||
void parseList(ParsedList& parsed, PathName list)
|
||||
{
|
||||
list.alltrim(" \t");
|
||||
parsed.clear();
|
||||
const char* sep = " \t,;";
|
||||
|
||||
for(;;)
|
||||
{
|
||||
PathName::size_type p = list.find_first_of(sep);
|
||||
if (p == PathName::npos)
|
||||
{
|
||||
if (list.hasData())
|
||||
{
|
||||
parsed.push(list);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
parsed.push(list.substr(0, p));
|
||||
list = list.substr(p + 1);
|
||||
list.ltrim(" \t,;");
|
||||
}
|
||||
}
|
||||
|
||||
void makeList(PathName& list, const ParsedList& parsed)
|
||||
{
|
||||
fb_assert(parsed.hasData());
|
||||
list = parsed[0];
|
||||
for (unsigned i = 1; i < parsed.getCount(); ++i)
|
||||
{
|
||||
list += ' ';
|
||||
list += parsed[i];
|
||||
}
|
||||
}
|
||||
|
||||
void mergeLists(PathName& list, const PathName& serverList, const PathName& clientList)
|
||||
{
|
||||
ParsedList onClient, onServer, merged;
|
||||
parseList(onClient, clientList);
|
||||
parseList(onServer, serverList);
|
||||
|
||||
// do not expect too long lists, therefore use double loop
|
||||
for (unsigned c = 0; c < onClient.getCount(); ++c)
|
||||
{
|
||||
for (unsigned s = 0; s < onServer.getCount(); ++s)
|
||||
{
|
||||
if (onClient[c] == onServer[s])
|
||||
{
|
||||
merged.push(onClient[c]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
makeList(list, merged);
|
||||
}
|
||||
|
||||
} // namespace Auth
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "../common/classes/GetPlugins.h"
|
||||
#include "../common/classes/array.h"
|
||||
#include "../common/classes/MetaName.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
|
||||
namespace Auth {
|
||||
|
||||
@ -263,6 +264,13 @@ public:
|
||||
|
||||
int setGsecCode(int code, int operation);
|
||||
|
||||
// tools to operate lists of security-related plugins
|
||||
typedef Firebird::ObjectsArray<Firebird::PathName> ParsedList;
|
||||
void parseList(ParsedList& parsed, Firebird::PathName list);
|
||||
void makeList(Firebird::PathName& list, const ParsedList& parsed);
|
||||
void mergeLists(Firebird::PathName& list, const Firebird::PathName& serverList,
|
||||
const Firebird::PathName& clientList);
|
||||
|
||||
} // namespace Auth
|
||||
|
||||
#endif // UTILITIES_SECUR_PROTO_H
|
||||
|
@ -41,7 +41,10 @@
|
||||
#include "../evl_proto.h"
|
||||
#include "../intl_proto.h"
|
||||
#include "../mov_proto.h"
|
||||
|
||||
#include "../common/isc_f_proto.h"
|
||||
#include "../common/db_alias.h"
|
||||
#include "../common/isc_proto.h"
|
||||
#include "../common/Auth.h"
|
||||
|
||||
using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
@ -112,12 +115,13 @@ Connection* Manager::getConnection(thread_db* tdbb, const string& dataSource,
|
||||
|
||||
// dataSource : registered data source name
|
||||
// or connection string : provider::database
|
||||
string prvName, dbName;
|
||||
string prvName;
|
||||
PathName dbName;
|
||||
|
||||
if (dataSource.isEmpty())
|
||||
{
|
||||
prvName = INTERNAL_PROVIDER_NAME;
|
||||
dbName = tdbb->getDatabase()->dbb_database_name.c_str();
|
||||
dbName = tdbb->getDatabase()->dbb_database_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -125,7 +129,7 @@ Connection* Manager::getConnection(thread_db* tdbb, const string& dataSource,
|
||||
if (pos != string::npos)
|
||||
{
|
||||
prvName = dataSource.substr(0, pos);
|
||||
dbName = dataSource.substr(pos + 2);
|
||||
dbName = dataSource.substr(pos + 2).ToPathName();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -134,7 +138,7 @@ Connection* Manager::getConnection(thread_db* tdbb, const string& dataSource,
|
||||
|
||||
// if not found - treat dataSource as Firebird's connection string
|
||||
prvName = FIREBIRD_PROVIDER_NAME;
|
||||
dbName = dataSource;
|
||||
dbName = dataSource.ToPathName();
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +178,7 @@ Provider::~Provider()
|
||||
clearConnections(tdbb);
|
||||
}
|
||||
|
||||
Connection* Provider::getConnection(thread_db* tdbb, const string& dbName,
|
||||
Connection* Provider::getConnection(thread_db* tdbb, const PathName& dbName,
|
||||
const string& user, const string& pwd, const string& role, TraScope tra_scope)
|
||||
{
|
||||
const Jrd::Attachment* attachment = tdbb->getAttachment();
|
||||
@ -311,7 +315,7 @@ Connection::~Connection()
|
||||
}
|
||||
|
||||
void Connection::generateDPB(thread_db* tdbb, ClumpletWriter& dpb,
|
||||
const string& user, const string& pwd, const string& role) const
|
||||
const string& user, const string& pwd, const string& role, const PathName& file) const
|
||||
{
|
||||
dpb.reset(isc_dpb_version1);
|
||||
|
||||
@ -334,6 +338,8 @@ void Connection::generateDPB(thread_db* tdbb, ClumpletWriter& dpb,
|
||||
if (!role.isEmpty()) {
|
||||
dpb.insertString(isc_dpb_sql_role_name, role);
|
||||
}
|
||||
|
||||
validatePassword(tdbb, file, dpb);
|
||||
}
|
||||
|
||||
CharSet* const cs = INTL_charset_lookup(tdbb, attachment->att_charset);
|
||||
@ -344,14 +350,14 @@ void Connection::generateDPB(thread_db* tdbb, ClumpletWriter& dpb,
|
||||
// remote network address???
|
||||
}
|
||||
|
||||
bool Connection::isSameDatabase(thread_db* tdbb, const string& dbName,
|
||||
bool Connection::isSameDatabase(thread_db* tdbb, const PathName& dbName,
|
||||
const string& user, const string& pwd, const string& role) const
|
||||
{
|
||||
if (m_dbName != dbName)
|
||||
return false;
|
||||
|
||||
ClumpletWriter dpb(ClumpletReader::dpbList, MAX_DPB_SIZE);
|
||||
generateDPB(tdbb, dpb, user, pwd, role);
|
||||
generateDPB(tdbb, dpb, user, pwd, role, dbName);
|
||||
|
||||
return m_dpb.simpleCompare(dpb);
|
||||
}
|
||||
@ -1631,4 +1637,245 @@ EngineCallbackGuard::~EngineCallbackGuard()
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class DummyCryptKey FB_FINAL :
|
||||
public Firebird::AutoIface<Firebird::ICryptKeyImpl<DummyCryptKey, Firebird::CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
// ICryptKey implementation
|
||||
void setSymmetric(Firebird::CheckStatusWrapper* status, const char* type, unsigned keyLength, const void* key)
|
||||
{ }
|
||||
void setAsymmetric(Firebird::CheckStatusWrapper* status, const char* type, unsigned encryptKeyLength,
|
||||
const void* encryptKey, unsigned decryptKeyLength, const void* decryptKey)
|
||||
{ }
|
||||
const void* getEncryptKey(unsigned* length)
|
||||
{
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
const void* getDecryptKey(unsigned* length)
|
||||
{
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class SBlock;
|
||||
|
||||
class CBlock FB_FINAL : public RefCntIface<IClientBlockImpl<CBlock, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
CBlock(const string& p_login, const string& p_password)
|
||||
: login(p_login), password(p_password)
|
||||
{ }
|
||||
|
||||
// Firebird::IClientBlock implementation
|
||||
int release()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* getLogin()
|
||||
{
|
||||
return login.c_str();
|
||||
}
|
||||
|
||||
const char* getPassword()
|
||||
{
|
||||
return password.c_str();
|
||||
}
|
||||
|
||||
const unsigned char* getData(unsigned int* length)
|
||||
{
|
||||
*length = data.getCount();
|
||||
return data.begin();
|
||||
}
|
||||
|
||||
void putData(CheckStatusWrapper* status, unsigned int length, const void* d);
|
||||
|
||||
Firebird::ICryptKey* newKey(Firebird::CheckStatusWrapper* status)
|
||||
{
|
||||
return &dummyCryptKey;
|
||||
}
|
||||
|
||||
private:
|
||||
const string& login;
|
||||
const string& password;
|
||||
DummyCryptKey dummyCryptKey;
|
||||
UCharBuffer data;
|
||||
|
||||
friend class SBlock;
|
||||
SBlock* sBlock;
|
||||
};
|
||||
|
||||
class SBlock FB_FINAL : public AutoIface<IServerBlockImpl<SBlock, CheckStatusWrapper> >
|
||||
{
|
||||
public:
|
||||
explicit SBlock(CBlock* par)
|
||||
: cBlock(par)
|
||||
{
|
||||
cBlock->sBlock = this;
|
||||
}
|
||||
|
||||
// Firebird::IServerBlock implementation
|
||||
const char* getLogin()
|
||||
{
|
||||
return cBlock->getLogin();
|
||||
}
|
||||
|
||||
const unsigned char* getData(unsigned int* length)
|
||||
{
|
||||
*length = data.getCount();
|
||||
return data.begin();
|
||||
}
|
||||
|
||||
void putData(CheckStatusWrapper* status, unsigned int length, const void* d);
|
||||
|
||||
Firebird::ICryptKey* newKey(Firebird::CheckStatusWrapper* status)
|
||||
{
|
||||
return &dummyCryptKey;
|
||||
}
|
||||
|
||||
private:
|
||||
DummyCryptKey dummyCryptKey;
|
||||
UCharBuffer data;
|
||||
|
||||
friend class CBlock;
|
||||
CBlock* cBlock;
|
||||
};
|
||||
|
||||
void CBlock::putData(CheckStatusWrapper* status, unsigned int length, const void* d)
|
||||
{
|
||||
void* to = sBlock->data.getBuffer(length);
|
||||
memcpy(to, d, length);
|
||||
}
|
||||
|
||||
void SBlock::putData(CheckStatusWrapper* status, unsigned int length, const void* d)
|
||||
{
|
||||
void* to = cBlock->data.getBuffer(length);
|
||||
memcpy(to, d, length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Connection::validatePassword(thread_db* tdbb, const PathName& file, ClumpletWriter& dpb)
|
||||
{
|
||||
// Peliminary checks - should we really validate password ourself
|
||||
if (!dpb.find(isc_dpb_user_name)) // check for user name presence
|
||||
return;
|
||||
if (ISC_check_if_remote(file, false)) // check for remote connection
|
||||
return;
|
||||
UserId* usr = tdbb->getAttachment()->att_user;
|
||||
if (!usr->usr_auth_block.hasData()) // check for embedded attachment
|
||||
return;
|
||||
|
||||
Arg::Gds loginError(isc_login_error);
|
||||
|
||||
// Build list of client/server plugins
|
||||
RefPtr<Config> config;
|
||||
PathName list;
|
||||
expandDatabaseName(file, list /* usused value */, &config);
|
||||
PathName serverList = config->getPlugins(IPluginManager::TYPE_AUTH_SERVER);
|
||||
PathName clientList = config->getPlugins(IPluginManager::TYPE_AUTH_CLIENT);
|
||||
Auth::mergeLists(list, serverList, clientList);
|
||||
if (!list.hasData())
|
||||
{
|
||||
Arg::Gds noPlugins(isc_random);
|
||||
noPlugins << "No matching client/server authentication plugins configured for execute statement in embedded datasource";
|
||||
iscLogStatus(NULL, noPlugins.value());
|
||||
|
||||
#ifdef DEV_BUILD
|
||||
loginError << noPlugins;
|
||||
#endif
|
||||
loginError.raise();
|
||||
}
|
||||
|
||||
// Analyze DPB
|
||||
string login;
|
||||
if (dpb.find(isc_dpb_user_name))
|
||||
{
|
||||
dpb.getString(login);
|
||||
fb_utils::dpbItemUpper(login);
|
||||
}
|
||||
string password;
|
||||
if (dpb.find(isc_dpb_password))
|
||||
dpb.getString(password);
|
||||
|
||||
// Try each plugin from the merged list
|
||||
for (GetPlugins<IClient> client(IPluginManager::TYPE_AUTH_CLIENT, config, list.c_str());
|
||||
client.hasData(); client.next())
|
||||
{
|
||||
GetPlugins<IServer> server(IPluginManager::TYPE_AUTH_SERVER, config, client.name());
|
||||
if (!server.hasData())
|
||||
continue;
|
||||
|
||||
CBlock cBlock(login, password);
|
||||
SBlock sBlock(&cBlock);
|
||||
Auth::WriterImplementation writer;
|
||||
writer.setPlugin(client.name());
|
||||
|
||||
const int MAXLIMIT = 100;
|
||||
for (int limit = 0; limit < MAXLIMIT; ++limit) // avoid endless AUTH_MORE_DATA loop
|
||||
{
|
||||
LocalStatus ls;
|
||||
CheckStatusWrapper s(&ls);
|
||||
ISC_STATUS code = isc_login;
|
||||
|
||||
switch(client.plugin()->authenticate(&s, &cBlock))
|
||||
{
|
||||
case IAuth::AUTH_SUCCESS:
|
||||
case IAuth::AUTH_MORE_DATA:
|
||||
break;
|
||||
|
||||
case IAuth::AUTH_CONTINUE:
|
||||
limit = MAXLIMIT;
|
||||
continue;
|
||||
|
||||
case IAuth::AUTH_FAILED:
|
||||
if (s.getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
{
|
||||
iscLogStatus("Authentication failed, client plugin:", &s);
|
||||
code = isc_login_error;
|
||||
}
|
||||
(Arg::Gds(code)
|
||||
#ifdef DEV_BUILD
|
||||
<< Arg::StatusVector(&s)
|
||||
#endif
|
||||
).raise();
|
||||
break; // compiler silencer
|
||||
}
|
||||
|
||||
switch(server.plugin()->authenticate(&s, &sBlock, &writer))
|
||||
{
|
||||
case IAuth::AUTH_SUCCESS:
|
||||
dpb.deleteWithTag(isc_dpb_user_name);
|
||||
dpb.deleteWithTag(isc_dpb_password);
|
||||
writer.store(&dpb, isc_dpb_auth_block);
|
||||
return;
|
||||
|
||||
case IAuth::AUTH_CONTINUE:
|
||||
limit = MAXLIMIT;
|
||||
continue;
|
||||
|
||||
case IAuth::AUTH_MORE_DATA:
|
||||
break;
|
||||
|
||||
case IAuth::AUTH_FAILED:
|
||||
if (s.getState() & Firebird::IStatus::STATE_ERRORS)
|
||||
{
|
||||
iscLogStatus("Authentication faled, server plugin:", &s);
|
||||
code = isc_login_error;
|
||||
}
|
||||
(Arg::Gds(code)
|
||||
#ifdef DEV_BUILD
|
||||
<< Arg::StatusVector(&s)
|
||||
#endif
|
||||
).raise();
|
||||
break; // compiler silencer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Arg::Gds(isc_login).raise();
|
||||
}
|
||||
} // namespace EDS
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
virtual ~Provider();
|
||||
|
||||
// return existing or create new Connection
|
||||
virtual Connection* getConnection(Jrd::thread_db* tdbb, const Firebird::string& dbName,
|
||||
virtual Connection* getConnection(Jrd::thread_db* tdbb, const Firebird::PathName& dbName,
|
||||
const Firebird::string& user, const Firebird::string& pwd, const Firebird::string& role,
|
||||
TraScope tra_scope);
|
||||
|
||||
@ -155,7 +155,7 @@ public:
|
||||
|
||||
Provider* getProvider() { return &m_provider; }
|
||||
|
||||
virtual void attach(Jrd::thread_db* tdbb, const Firebird::string& dbName,
|
||||
virtual void attach(Jrd::thread_db* tdbb, const Firebird::PathName& dbName,
|
||||
const Firebird::string& user, const Firebird::string& pwd,
|
||||
const Firebird::string& role) = 0;
|
||||
virtual void detach(Jrd::thread_db* tdbb);
|
||||
@ -172,7 +172,7 @@ public:
|
||||
|
||||
virtual bool isConnected() const = 0;
|
||||
|
||||
virtual bool isSameDatabase(Jrd::thread_db* tdbb, const Firebird::string& dbName,
|
||||
virtual bool isSameDatabase(Jrd::thread_db* tdbb, const Firebird::PathName& dbName,
|
||||
const Firebird::string& user, const Firebird::string& pwd,
|
||||
const Firebird::string& role) const;
|
||||
|
||||
@ -186,7 +186,7 @@ public:
|
||||
|
||||
const Firebird::string getDataSourceName() const
|
||||
{
|
||||
return m_provider.getName() + "::" + m_dbName;
|
||||
return m_provider.getName() + "::" + m_dbName.ToString();
|
||||
}
|
||||
|
||||
// Get error description from provider and put it with additional context
|
||||
@ -215,7 +215,9 @@ public:
|
||||
protected:
|
||||
void generateDPB(Jrd::thread_db* tdbb, Firebird::ClumpletWriter& dpb,
|
||||
const Firebird::string& user, const Firebird::string& pwd,
|
||||
const Firebird::string& role) const;
|
||||
const Firebird::string& role, const Firebird::PathName& file) const;
|
||||
static void validatePassword(Jrd::thread_db* tdbb, const Firebird::PathName& file,
|
||||
Firebird::ClumpletWriter& dpb);
|
||||
|
||||
virtual Transaction* doCreateTransaction() = 0;
|
||||
virtual Statement* doCreateStatement() = 0;
|
||||
@ -229,7 +231,7 @@ protected:
|
||||
Firebird::Mutex m_mutex;
|
||||
|
||||
Provider& m_provider;
|
||||
Firebird::string m_dbName;
|
||||
Firebird::PathName m_dbName;
|
||||
Firebird::ClumpletWriter m_dpb;
|
||||
|
||||
Firebird::Array<Transaction*> m_transactions;
|
||||
|
@ -134,7 +134,7 @@ private:
|
||||
FbStatusVector *v;
|
||||
};
|
||||
|
||||
void InternalConnection::attach(thread_db* tdbb, const string& dbName,
|
||||
void InternalConnection::attach(thread_db* tdbb, const PathName& dbName,
|
||||
const string& user, const string& pwd,
|
||||
const string& role)
|
||||
{
|
||||
@ -157,7 +157,7 @@ void InternalConnection::attach(thread_db* tdbb, const string& dbName,
|
||||
{
|
||||
m_isCurrent = false;
|
||||
m_dbName = dbb->dbb_database_name.c_str();
|
||||
generateDPB(tdbb, m_dpb, user, pwd, role);
|
||||
generateDPB(tdbb, m_dpb, user, pwd, role, dbName);
|
||||
|
||||
FbLocalStatus status;
|
||||
|
||||
@ -238,7 +238,7 @@ bool InternalConnection::isAvailable(thread_db* tdbb, TraScope /*traScope*/) con
|
||||
(m_isCurrent && (tdbb->getAttachment() == m_attachment->getHandle()));
|
||||
}
|
||||
|
||||
bool InternalConnection::isSameDatabase(thread_db* tdbb, const string& dbName,
|
||||
bool InternalConnection::isSameDatabase(thread_db* tdbb, const PathName& dbName,
|
||||
const string& user, const string& pwd,
|
||||
const string& role) const
|
||||
{
|
||||
|
@ -63,7 +63,7 @@ protected:
|
||||
virtual ~InternalConnection();
|
||||
|
||||
public:
|
||||
virtual void attach(Jrd::thread_db* tdbb, const Firebird::string& dbName,
|
||||
virtual void attach(Jrd::thread_db* tdbb, const Firebird::PathName& dbName,
|
||||
const Firebird::string& user, const Firebird::string& pwd,
|
||||
const Firebird::string& role);
|
||||
|
||||
@ -73,7 +73,7 @@ public:
|
||||
|
||||
virtual bool isConnected() const { return (m_attachment != 0); }
|
||||
|
||||
virtual bool isSameDatabase(Jrd::thread_db* tdbb, const Firebird::string& dbName,
|
||||
virtual bool isSameDatabase(Jrd::thread_db* tdbb, const Firebird::PathName& dbName,
|
||||
const Firebird::string& user, const Firebird::string& pwd,
|
||||
const Firebird::string& role) const;
|
||||
|
||||
|
@ -110,11 +110,11 @@ IscConnection::~IscConnection()
|
||||
{
|
||||
}
|
||||
|
||||
void IscConnection::attach(thread_db* tdbb, const string& dbName, const string& user,
|
||||
void IscConnection::attach(thread_db* tdbb, const PathName& dbName, const string& user,
|
||||
const string& pwd, const string& role)
|
||||
{
|
||||
m_dbName = dbName;
|
||||
generateDPB(tdbb, m_dpb, user, pwd, role);
|
||||
generateDPB(tdbb, m_dpb, user, pwd, role, dbName);
|
||||
|
||||
FbLocalStatus status;
|
||||
{
|
||||
|
@ -510,7 +510,7 @@ protected:
|
||||
public:
|
||||
FB_API_HANDLE& getAPIHandle() { return m_handle; }
|
||||
|
||||
virtual void attach(Jrd::thread_db* tdbb, const Firebird::string& dbName,
|
||||
virtual void attach(Jrd::thread_db* tdbb, const Firebird::PathName& dbName,
|
||||
const Firebird::string& user, const Firebird::string& pwd,
|
||||
const Firebird::string& role);
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "../common/classes/fb_string.h"
|
||||
#include "../common/config/config.h"
|
||||
#include "../common/classes/RefCounted.h"
|
||||
#include "../common/classes/objects_array.h"
|
||||
#include "../common/security.h"
|
||||
#include "../common/xdr.h"
|
||||
#include "../remote/protocol.h"
|
||||
|
||||
@ -38,7 +38,7 @@ namespace Firebird
|
||||
|
||||
namespace Remote
|
||||
{
|
||||
typedef Firebird::ObjectsArray<Firebird::PathName> ParsedList;
|
||||
typedef Auth::ParsedList ParsedList;
|
||||
}
|
||||
|
||||
struct rem_port;
|
||||
@ -63,12 +63,20 @@ bool_t REMOTE_getbytes (XDR*, SCHAR*, u_int);
|
||||
LegacyPlugin REMOTE_legacy_auth(const char* nm, int protocol);
|
||||
Firebird::RefPtr<Config> REMOTE_get_config(const Firebird::PathName* dbName,
|
||||
const Firebird::string* dpb_config = NULL);
|
||||
void REMOTE_parseList(Remote::ParsedList&, Firebird::PathName);
|
||||
void REMOTE_makeList(Firebird::PathName& list, const Remote::ParsedList& parsed);
|
||||
void REMOTE_check_response(Firebird::IStatus* warning, Rdb* rdb, PACKET* packet, bool checkKeys = false);
|
||||
bool REMOTE_inflate(rem_port*, PacketReceive*, UCHAR*, SSHORT, SSHORT*);
|
||||
bool REMOTE_deflate(XDR*, ProtoWrite*, PacketSend*, bool flash);
|
||||
|
||||
static inline void REMOTE_parseList(Remote::ParsedList& parsed, const Firebird::PathName& list)
|
||||
{
|
||||
Auth::parseList(parsed, list);
|
||||
}
|
||||
|
||||
static inline void REMOTE_makeList(Firebird::PathName& list, const Remote::ParsedList& parsed)
|
||||
{
|
||||
Auth::makeList(list, parsed);
|
||||
}
|
||||
|
||||
extern signed char wcCompatible[3][3];
|
||||
|
||||
#define HANDSHAKE_DEBUG(A)
|
||||
|
@ -986,23 +986,8 @@ void ClntAuthBlock::resetClnt(const Firebird::PathName* fileName, const CSTRING*
|
||||
Firebird::PathName final;
|
||||
if (serverPluginList.hasData())
|
||||
{
|
||||
Remote::ParsedList onClient, fromServer, merged;
|
||||
REMOTE_parseList(onClient, pluginList);
|
||||
REMOTE_parseList(fromServer, serverPluginList);
|
||||
|
||||
for (unsigned c = 0; c < onClient.getCount(); ++c)
|
||||
{
|
||||
// do not expect too long lists, therefore use double loop
|
||||
for (unsigned s = 0; s < fromServer.getCount(); ++s)
|
||||
{
|
||||
if (onClient[c] == fromServer[s])
|
||||
{
|
||||
merged.push(onClient[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (merged.getCount() == 0)
|
||||
Auth::mergeLists(final, serverPluginList, pluginList);
|
||||
if (final.length() == 0)
|
||||
{
|
||||
HANDSHAKE_DEBUG(fprintf(stderr, "Cli: No matching plugins on client\n"));
|
||||
(Firebird::Arg::Gds(isc_login)
|
||||
@ -1011,8 +996,6 @@ void ClntAuthBlock::resetClnt(const Firebird::PathName* fileName, const CSTRING*
|
||||
#endif
|
||||
).raise();
|
||||
}
|
||||
|
||||
REMOTE_makeList(final, merged);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1051,42 +1034,6 @@ Firebird::RefPtr<Config> REMOTE_get_config(const Firebird::PathName* dbName,
|
||||
return config;
|
||||
}
|
||||
|
||||
void REMOTE_parseList(Remote::ParsedList& parsed, Firebird::PathName list)
|
||||
{
|
||||
list.alltrim(" \t");
|
||||
parsed.clear();
|
||||
const char* sep = " \t,;";
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Firebird::PathName::size_type p = list.find_first_of(sep);
|
||||
if (p == Firebird::PathName::npos)
|
||||
{
|
||||
if (list.hasData())
|
||||
{
|
||||
parsed.push(list);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
parsed.push(list.substr(0, p));
|
||||
list = list.substr(p + 1);
|
||||
list.ltrim(" \t,;");
|
||||
}
|
||||
}
|
||||
|
||||
void REMOTE_makeList(Firebird::PathName& list, const Remote::ParsedList& parsed)
|
||||
{
|
||||
fb_assert(parsed.hasData());
|
||||
//list.erase();
|
||||
list = parsed[0];
|
||||
for (unsigned i = 1; i < parsed.getCount(); ++i)
|
||||
{
|
||||
list += ' ';
|
||||
list += parsed[i];
|
||||
}
|
||||
}
|
||||
|
||||
void REMOTE_check_response(Firebird::IStatus* warning, Rdb* rdb, PACKET* packet, bool checkKeys)
|
||||
{
|
||||
/**************************************
|
||||
|
Loading…
Reference in New Issue
Block a user