8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 17:23:03 +01:00

Merge pull request #8262 from FirebirdSQL/work/gh-8256

Make server to correctly handle case when accept() returns both success and data for client.
This commit is contained in:
Vlad Khorsun 2024-09-23 18:50:11 +03:00
parent 77cc0ba849
commit cc512a34e0
6 changed files with 30 additions and 7 deletions

View File

@ -367,7 +367,8 @@ bool AuthSspi::getLogin(string& login, bool& wh, GroupsList& grNames)
WinSspiServer::WinSspiServer(Firebird::IPluginConfig*)
: sspiData(getPool())
: sspiData(getPool()),
done(false)
{ }
int WinSspiServer::authenticate(Firebird::CheckStatusWrapper* status,
@ -376,17 +377,18 @@ int WinSspiServer::authenticate(Firebird::CheckStatusWrapper* status,
{
try
{
const bool wasActive = sspi.isActive();
sspiData.clear();
unsigned int length;
const unsigned char* bytes = sBlock->getData(&length);
sspiData.add(bytes, length);
if (done && !length && !sspi.isActive())
return AUTH_SUCCESS;
if (!sspi.accept(sspiData))
return AUTH_CONTINUE;
if (wasActive && !sspi.isActive())
if (!sspi.isActive())
{
bool wheel = false;
string login;
@ -445,7 +447,9 @@ int WinSspiServer::authenticate(Firebird::CheckStatusWrapper* status,
return AUTH_FAILED;
}
return AUTH_SUCCESS;
done = true;
if (sspiData.isEmpty())
return AUTH_SUCCESS;
}
sBlock->putData(status, sspiData.getCount(), sspiData.begin());
@ -456,7 +460,7 @@ int WinSspiServer::authenticate(Firebird::CheckStatusWrapper* status,
return AUTH_FAILED;
}
return AUTH_MORE_DATA;
return done ? AUTH_SUCCESS_WITH_DATA : AUTH_MORE_DATA;
}

View File

@ -124,6 +124,7 @@ public:
private:
AuthSspi::DataHolder sspiData;
AuthSspi sspi;
bool done;
};
class WinSspiClient :

View File

@ -769,6 +769,7 @@ interface Auth : PluginBase
const int AUTH_SUCCESS = 0;
const int AUTH_MORE_DATA = 1;
const int AUTH_CONTINUE = 2;
const int AUTH_SUCCESS_WITH_DATA = 3;
}
interface Writer : Versioned

View File

@ -3063,6 +3063,7 @@ namespace Firebird
static CLOOP_CONSTEXPR int AUTH_SUCCESS = 0;
static CLOOP_CONSTEXPR int AUTH_MORE_DATA = 1;
static CLOOP_CONSTEXPR int AUTH_CONTINUE = 2;
static CLOOP_CONSTEXPR int AUTH_SUCCESS_WITH_DATA = 3;
};
#define FIREBIRD_IWRITER_VERSION 2u

View File

@ -1971,6 +1971,7 @@ type
const AUTH_SUCCESS = Integer(0);
const AUTH_MORE_DATA = Integer(1);
const AUTH_CONTINUE = Integer(2);
const AUTH_SUCCESS_WITH_DATA = Integer(3);
end;

View File

@ -657,7 +657,10 @@ public:
}
// if we asked for more data but received nothing switch to next plugin
const bool forceNext = (flags & AUTH_CONTINUE) && (!authPort->port_srv_auth_block->hasDataForPlugin());
const bool forceNext = (flags & AUTH_CONTINUE) &&
(!authPort->port_srv_auth_block->hasDataForPlugin()) &&
(!authPort->port_srv_auth_block->authCompleted());
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: authenticate: ServerAuth calls plug %s\n",
forceNext ? "forced-NEXT" : authItr->name()));
int authResult = forceNext ? IAuth::AUTH_CONTINUE :
@ -686,6 +689,11 @@ public:
authServer = NULL;
continue;
case IAuth::AUTH_SUCCESS_WITH_DATA:
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: authenticate: success with data\n"));
fb_assert(!authPort->port_srv_auth_block->authCompleted());
// fall thru
case IAuth::AUTH_MORE_DATA:
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: authenticate: plugin wants more data\n"));
if (authPort->port_protocol < PROTOCOL_VERSION11)
@ -739,6 +747,13 @@ public:
if (send->p_acpt.p_acpt_type & pflag_compress)
authPort->port_flags |= PORT_compressed;
memset(&send->p_auth_cont, 0, sizeof send->p_auth_cont);
if (authResult == IAuth::AUTH_SUCCESS_WITH_DATA)
{
authPort->port_srv_auth_block->authCompleted(true);
HANDSHAKE_DEBUG(fprintf(stderr, "Srv: authenticate: success with data, completed\n"));
}
return false;
case IAuth::AUTH_FAILED: