This logic had a bug in the past that had been introduced by r8886 and
accidentally fixed when introducing multi-account support in r9420. The bug was
that rcon_password being empty led to the empty password being accepted in some
cases, as there was never any explicit logic to handle that in rcon - it was
more "accidentally" rejected by a packet formatting check which does not apply
to srcon as the empty password wouldn't be empty over the wire.
In other words: DP builds from [r8886, r9419] had a serious vulnerability and
the only workaround is to always have rcon_password set.
The check added here will complain and reject in case the calling code for some
reason no longer prevents empty passwords from being accepted.
Also adding comments to the new logic explaining how it prevents the empty
password from being accepted.
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12334
d7cf8633-e32d-0410-b094-
e92efae38249
char mdfourbuf[16];
long t1, t2;
char mdfourbuf[16];
long t1, t2;
+ if (!password[0]) {
+ Con_Print("^4LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
+ return false;
+ }
+
t1 = (long) time(NULL);
t2 = strtol(s, NULL, 0);
if(abs(t1 - t2) > rcon_secure_maxdiff.integer)
t1 = (long) time(NULL);
t2 = strtol(s, NULL, 0);
if(abs(t1 - t2) > rcon_secure_maxdiff.integer)
char mdfourbuf[16];
int i;
char mdfourbuf[16];
int i;
+ if (!password[0]) {
+ Con_Print("^4LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
+ return false;
+ }
+
if(slen < (int)(sizeof(challenges[0].string)) - 1)
return false;
if(slen < (int)(sizeof(challenges[0].string)) - 1)
return false;
static qboolean plaintext_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
{
static qboolean plaintext_matching(lhnetaddress_t *peeraddress, const char *password, const char *hash, const char *s, int slen)
{
+ if (!password[0]) {
+ Con_Print("^4LOGIC ERROR: RCon_Authenticate should never call the comparator with an empty password. Please report.\n");
+ return false;
+ }
+
return !strcmp(password, hash);
}
return !strcmp(password, hash);
}
{
have_usernames = true;
strlcpy(buf, userpass_start, ((size_t)(userpass_end-userpass_start) >= sizeof(buf)) ? (int)(sizeof(buf)) : (int)(userpass_end-userpass_start+1));
{
have_usernames = true;
strlcpy(buf, userpass_start, ((size_t)(userpass_end-userpass_start) >= sizeof(buf)) ? (int)(sizeof(buf)) : (int)(userpass_end-userpass_start+1));
+ if(buf[0]) // Ignore empty entries due to leading/duplicate space.
if(comparator(peeraddress, buf, password, cs, cslen))
goto allow;
userpass_start = userpass_end + 1;
}
if(comparator(peeraddress, buf, password, cs, cslen))
goto allow;
userpass_start = userpass_end + 1;
}
+ if(userpass_start[0]) // Ignore empty trailing entry due to trailing space or password not set.
{
userpass_end = userpass_start + strlen(userpass_start);
if(comparator(peeraddress, userpass_start, password, cs, cslen))
{
userpass_end = userpass_start + strlen(userpass_start);
if(comparator(peeraddress, userpass_start, password, cs, cslen))
{
have_usernames = true;
strlcpy(buf, userpass_start, ((size_t)(userpass_end-userpass_start) >= sizeof(buf)) ? (int)(sizeof(buf)) : (int)(userpass_end-userpass_start+1));
{
have_usernames = true;
strlcpy(buf, userpass_start, ((size_t)(userpass_end-userpass_start) >= sizeof(buf)) ? (int)(sizeof(buf)) : (int)(userpass_end-userpass_start+1));
+ if(buf[0]) // Ignore empty entries due to leading/duplicate space.
if(comparator(peeraddress, buf, password, cs, cslen))
goto check;
userpass_start = userpass_end + 1;
}
if(comparator(peeraddress, buf, password, cs, cslen))
goto check;
userpass_start = userpass_end + 1;
}
+ if(userpass_start[0]) // Ignore empty trailing entry due to trailing space or password not set.
{
userpass_end = userpass_start + strlen(userpass_start);
if(comparator(peeraddress, userpass_start, password, cs, cslen))
{
userpass_end = userpass_start + strlen(userpass_start);
if(comparator(peeraddress, userpass_start, password, cs, cslen))