This commit is contained in:
Beeks
2010-08-22 15:14:30 -04:00
parent 88cf144936
commit 5ce4286fd7
164 changed files with 31303 additions and 22286 deletions

View File

@@ -550,76 +550,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fak
S32 receive_size = 0;
do
{
// <edit>
// Expire old canary entries
F64 now = LLTimer::getElapsedSeconds();
std::map<U32, LLNetCanary::entry>::iterator canary_entry_iter;
std::map<U32, LLNetCanary::entry>::iterator canary_entry_end = mCanaryEntries.end();
for( canary_entry_iter = mCanaryEntries.begin();
canary_entry_iter != mCanaryEntries.end(); )
{
if( ((*canary_entry_iter).second.time + 30.0f) < now)
{
llinfos << "Expiring ban on " << (*canary_entry_iter).second.name << " message, " << (*canary_entry_iter).second.points << " points" << llendl;
mCanaryEntries.erase(canary_entry_iter++);
}
else
{
canary_entry_iter++;
}
}
if(!faked_message && mSpoofProtectionLevel > 1)
{
// Canaries receive
std::vector<LLNetCanary*>::iterator canary_iter = mCanaries.begin();
std::vector<LLNetCanary*>::iterator canary_end = mCanaries.end();
for( ; canary_iter != canary_end; ++canary_iter)
{
U8* canary_buffer = (*canary_iter)->mBuffer;
S32 len = receive_packet((*canary_iter)->mSocket, (char*)canary_buffer);
if(len)
{
//llinfos << "canary received " << len << " bytes on port " << (*canary_iter)->mPort << llendl;
zeroCodeExpand(&canary_buffer, &len);
if(len < 7) continue; // too short to be an slmsg
LLNetCanary::entry entry;
entry.message = 0;
if(canary_buffer[6] != 0xFF) // High XX
entry.message = canary_buffer[6];
else if((len >= 8) && (canary_buffer[7] != 0xFF)) // Medium FFXX
entry.message = (255 << 8) | canary_buffer[7];
else if((len >= 10) && (canary_buffer[7] == 0xFF)) // Low FFFFXXXX
{
U16 message_id_U16 = 0;
memcpy(&message_id_U16, &canary_buffer[8], 2);
message_id_U16 = ntohs(message_id_U16);
entry.message = 0xFFFF0000 | message_id_U16;
}
else continue; // not an slmsg
if(mCanaryEntries.find(entry.message) == mCanaryEntries.end())
{
// brand new entry
LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers, entry.message);
entry.name = temp ? temp->mName : "Invalid";
entry.points = 1;
entry.time = now;
mCanaryEntries[entry.message] = entry;
if(mSpoofProtectionLevel == 2)
llinfos << "Temporarily banning a " << entry.name << " message" << llendl;
}
else
{
// strike two, three...
mCanaryEntries[entry.message].points++;
mCanaryEntries[entry.message].time = now;
if((mSpoofProtectionLevel > 2) && (mCanaryEntries[entry.message].points == 2))
llinfos << "Temporarily banning a " << mCanaryEntries[entry.message].name << " message" << llendl;
}
}
}
}
// </edit>
clearReceiveState();
BOOL recv_reliable = FALSE;
@@ -646,12 +576,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fak
// If you want to dump all received packets into SecondLife.log, uncomment this
//dumpPacketToLog();
// <edit>
if(mTrueReceiveSize && receive_size > (S32) LL_MINIMUM_VALID_PACKET_SIZE && !faked_message)
{
LLMessageLog::log(mLastSender, LLHost(16777343, mPort), buffer, mTrueReceiveSize);
}
// </edit>
if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
@@ -695,61 +619,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fak
// process the message as normal
mIncomingCompressedSize = zeroCodeExpand(&buffer, &receive_size);
mCurrentRecvPacketID = ntohl(*((U32*)(&buffer[1])));
// <edit>
BOOL spoofed_packet = FALSE;
if(!faked_message && mSpoofProtectionLevel > 0)
{
S32 len = receive_size;
U32 message = 0;
if(buffer[6] != 0xFF) // High XX
message = buffer[6];
else if((len >= 8) && (buffer[7] != 0xFF)) // Medium FFXX
message = (255 << 8) | buffer[7];
else if((len >= 10) && (buffer[7] == 0xFF)) // Low FFFFXXXX
{
U16 message_id_U16 = 0;
memcpy(&message_id_U16, &buffer[8], 2);
message_id_U16 = ntohs(message_id_U16);
message = 0xFFFF0000 | message_id_U16;
}
if(!mCurrentRecvPacketID)
{
LL_WARNS("Messaging") << "CODE DONKEY_A" << llendl;
if(mSpoofDroppedCallback)
{
LLNetCanary::entry entry;
LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers, message);
entry.name = temp ? temp->mName : "Invalid";
entry.message = message;
entry.time = now;
entry.points = 1;
mSpoofDroppedCallback(entry);
}
spoofed_packet = TRUE;
valid_packet = FALSE;
}
else if((mSpoofProtectionLevel > 1) && (receive_size >= 7))
{
if(mCanaryEntries.find(message) != mCanaryEntries.end())
{
if(
(mSpoofProtectionLevel == 2) ||
(mCanaryEntries[message].points > 1)
)
{
LL_WARNS("Messaging") << "Dropped probably spoofed " << mCanaryEntries[message].name << " packet, " << mCanaryEntries[message].points << " points" << llendl;
if(mSpoofDroppedCallback)
{
mSpoofDroppedCallback(mCanaryEntries[message]);
}
spoofed_packet = TRUE;
valid_packet = FALSE;
break;
}
}
}
} // mSpoofProtectionLevel
// </edit>
host = getSender();
const bool resetPacketId = true;
@@ -832,9 +702,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fak
// But we don't want to acknowledge UseCircuitCode until the circuit is
// available, which is why the acknowledgement test is done above. JC
bool trusted = cdp && cdp->getTrusted();
// <edit>
if(!spoofed_packet)
// </edit>
valid_packet = mTemplateMessageReader->validateMessage(
buffer,
receive_size,
@@ -2850,9 +2718,6 @@ void end_messaging_system(bool print_summary)
LLTransferTargetVFile::updateQueue(true); // shutdown LLTransferTargetVFile
if (gMessageSystem)
{
// <edit>
gMessageSystem->stopSpoofProtection();
// </edit>
gMessageSystem->stopLogging();
if (print_summary)
@@ -4216,154 +4081,10 @@ const LLHost& LLMessageSystem::getSender() const
LLHTTPRegistration<LLHTTPNodeAdapter<LLTrustedMessageService> >
gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>");
// <edit>
void LLMessageSystem::startSpoofProtection(U32 level)
{
if(!mPort)
{
llwarns << "listen port is 0!!!" << llendl;
}
mSpoofProtectionLevel = level;
mCanaries.clear();
mCanaryEntries.clear();
// Make canaries
std::string canary_info("");
if(mSpoofProtectionLevel > 2) // 3 or greater
{
// FULL CANARY POWER
int rPort = 768 + ll_rand(32);
if(mPort < rPort) rPort = mPort - 16;
if(rPort < 1) rPort = 1;
while(rPort < 65536)
{
if(rPort != mPort)
{
LLNetCanary* canary = new LLNetCanary(rPort);
if(canary->mGood)
{
mCanaries.push_back(canary);
canary_info.append(llformat(" %d", canary->mPort));
}
else
delete canary;
}
int dist = llabs(mPort - rPort);
if(dist > 4096)
rPort += ll_rand(2048) + 2048;
else if(dist > 2048)
rPort += ll_rand(1024) + 1024;
else if(dist > 1024)
rPort += ll_rand(512) + 512;
else if(dist > 512)
rPort += ll_rand(256) + 256;
else if(dist > 128)
rPort += ll_rand(64) + 64;
else if(dist > 16)
rPort += ll_rand(8) + 8;
else
rPort += 4;
}
}
else if(mSpoofProtectionLevel == 2)
{
// Minimal canaries
for(int o = -32; o <= 32; o += 8)
{
int rPort = mPort + o;
if(rPort != mPort)
{
LLNetCanary* canary = new LLNetCanary(rPort);
if(canary->mGood)
{
mCanaries.push_back(canary);
canary_info.append(llformat(" %d", canary->mPort));
}
else
delete canary;
}
}
}
if(mCanaries.size())
{
llinfos << "level " << mSpoofProtectionLevel << ", " << mCanaries.size() << " canaries: " << canary_info << llendl;
}
else
{
llinfos << "level " << mSpoofProtectionLevel << ", no canaries" << llendl;
}
}
void LLMessageSystem::stopSpoofProtection()
{
llinfos << "cleaning up" << llendl;
// Shut down canaries
std::vector<LLNetCanary*>::iterator canary_iter = mCanaries.begin();
std::vector<LLNetCanary*>::iterator canary_end = mCanaries.end();
for( ; canary_iter != canary_end; ++canary_iter)
{
LLNetCanary* canary = (*canary_iter);
delete canary;
}
mCanaries.clear();
// Empty canary entries
mCanaryEntries.clear();
}
void LLMessageSystem::setSpoofDroppedCallback(void (*callback)(LLNetCanary::entry))
{
mSpoofDroppedCallback = callback;
}
// Copypasta from LLTemplateMessageReader
BOOL LLMessageSystem::decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template )
{
const U8* header = buffer + LL_PACKET_ID_SIZE;
if (buffer_size <= 0) return FALSE;
U32 num = 0;
if (header[0] != 255)
{
// high frequency message
num = header[0];
}
else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255))
{
// medium frequency message
num = (255 << 8) | header[1];
}
else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255))
{
// low frequency message
U16 message_id_U16 = 0;
// I think this check busts the message system.
// it appears that if there is a NULL in the message #, it won't copy it....
// what was the goal?
//if(header[2])
memcpy(&message_id_U16, &header[2], 2);
// dependant on endian-ness:
// U32 temp = (255 << 24) | (255 << 16) | header[2];
// independant of endian-ness:
message_id_U16 = ntohs(message_id_U16);
num = 0xFFFF0000 | message_id_U16;
}
else // bogus packet received (too short)
{
return(FALSE);
}
LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num);
if (temp)
{
*msg_template = temp;
}
else
{
return(FALSE);
}
return(TRUE);
}
// </edit