diff options
Diffstat (limited to 'linden/indra/llmessage')
-rw-r--r-- | linden/indra/llmessage/llares.cpp | 11 | ||||
-rw-r--r-- | linden/indra/llmessage/llares.h | 4 | ||||
-rw-r--r-- | linden/indra/llmessage/llhttpclient.cpp | 4 | ||||
-rw-r--r-- | linden/indra/llmessage/llmessagetemplate.h | 8 | ||||
-rw-r--r-- | linden/indra/llmessage/llmessagetemplateparser.cpp | 4 | ||||
-rw-r--r-- | linden/indra/llmessage/lltemplatemessagebuilder.cpp | 1 | ||||
-rw-r--r-- | linden/indra/llmessage/lltemplatemessagereader.cpp | 6 | ||||
-rw-r--r-- | linden/indra/llmessage/lltemplatemessagereader.h | 3 | ||||
-rw-r--r-- | linden/indra/llmessage/llurlrequest.cpp | 84 | ||||
-rw-r--r-- | linden/indra/llmessage/llurlrequest.h | 5 | ||||
-rw-r--r-- | linden/indra/llmessage/llxfermanager.cpp | 119 | ||||
-rw-r--r-- | linden/indra/llmessage/llxfermanager.h | 16 | ||||
-rw-r--r-- | linden/indra/llmessage/message.cpp | 10 |
13 files changed, 228 insertions, 47 deletions
diff --git a/linden/indra/llmessage/llares.cpp b/linden/indra/llmessage/llares.cpp index 5a310b3..7f573d2 100644 --- a/linden/indra/llmessage/llares.cpp +++ b/linden/indra/llmessage/llares.cpp | |||
@@ -100,9 +100,16 @@ void LLAres::QueryResponder::queryError(int code) | |||
100 | << LLAres::strerror(code) << llendl; | 100 | << LLAres::strerror(code) << llendl; |
101 | } | 101 | } |
102 | 102 | ||
103 | LLAres::LLAres() | 103 | LLAres::LLAres() : |
104 | chan_(NULL), mInitSuccess(false) | ||
104 | { | 105 | { |
105 | ares_init(&chan_); | 106 | if (ares_init(&chan_) != ARES_SUCCESS) |
107 | { | ||
108 | llwarns << "Could not succesfully initialize ares!" << llendl; | ||
109 | return; | ||
110 | } | ||
111 | |||
112 | mInitSuccess = true; | ||
106 | } | 113 | } |
107 | 114 | ||
108 | LLAres::~LLAres() | 115 | LLAres::~LLAres() |
diff --git a/linden/indra/llmessage/llares.h b/linden/indra/llmessage/llares.h index 5d72170..17f6085 100644 --- a/linden/indra/llmessage/llares.h +++ b/linden/indra/llmessage/llares.h | |||
@@ -437,9 +437,11 @@ public: | |||
437 | */ | 437 | */ |
438 | static const char *strerror(int code); | 438 | static const char *strerror(int code); |
439 | 439 | ||
440 | bool isInitialized(void) { return mInitSuccess; } | ||
441 | |||
440 | protected: | 442 | protected: |
441 | ares_channel chan_; | 443 | ares_channel chan_; |
442 | 444 | bool mInitSuccess; | |
443 | }; | 445 | }; |
444 | 446 | ||
445 | /** | 447 | /** |
diff --git a/linden/indra/llmessage/llhttpclient.cpp b/linden/indra/llmessage/llhttpclient.cpp index caeaee1..fc2612f 100644 --- a/linden/indra/llmessage/llhttpclient.cpp +++ b/linden/indra/llmessage/llhttpclient.cpp | |||
@@ -56,7 +56,7 @@ namespace | |||
56 | { | 56 | { |
57 | public: | 57 | public: |
58 | LLHTTPClientURLAdaptor(LLCurl::ResponderPtr responder) | 58 | LLHTTPClientURLAdaptor(LLCurl::ResponderPtr responder) |
59 | : mResponder(responder), mStatus(499), | 59 | : LLURLRequestComplete(), mResponder(responder), mStatus(499), |
60 | mReason("LLURLRequest complete w/no status") | 60 | mReason("LLURLRequest complete w/no status") |
61 | { | 61 | { |
62 | } | 62 | } |
@@ -67,6 +67,8 @@ namespace | |||
67 | 67 | ||
68 | virtual void httpStatus(U32 status, const std::string& reason) | 68 | virtual void httpStatus(U32 status, const std::string& reason) |
69 | { | 69 | { |
70 | LLURLRequestComplete::httpStatus(status,reason); | ||
71 | |||
70 | mStatus = status; | 72 | mStatus = status; |
71 | mReason = reason; | 73 | mReason = reason; |
72 | } | 74 | } |
diff --git a/linden/indra/llmessage/llmessagetemplate.h b/linden/indra/llmessage/llmessagetemplate.h index f92c4b7..716c618 100644 --- a/linden/indra/llmessage/llmessagetemplate.h +++ b/linden/indra/llmessage/llmessagetemplate.h | |||
@@ -265,6 +265,7 @@ enum EMsgDeprecation | |||
265 | { | 265 | { |
266 | MD_NOTDEPRECATED, | 266 | MD_NOTDEPRECATED, |
267 | MD_UDPDEPRECATED, | 267 | MD_UDPDEPRECATED, |
268 | MD_UDPBLACKLISTED, | ||
268 | MD_DEPRECATED | 269 | MD_DEPRECATED |
269 | }; | 270 | }; |
270 | 271 | ||
@@ -299,7 +300,7 @@ public: | |||
299 | ~LLMessageTemplate() | 300 | ~LLMessageTemplate() |
300 | { | 301 | { |
301 | for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePointer()); | 302 | for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePointer()); |
302 | } | 303 | } |
303 | 304 | ||
304 | void addBlock(LLMessageBlock *blockp) | 305 | void addBlock(LLMessageBlock *blockp) |
305 | { | 306 | { |
@@ -380,6 +381,11 @@ public: | |||
380 | return trustedSource ? mBanFromTrusted : mBanFromUntrusted; | 381 | return trustedSource ? mBanFromTrusted : mBanFromUntrusted; |
381 | } | 382 | } |
382 | 383 | ||
384 | bool isUdpBanned() const | ||
385 | { | ||
386 | return mDeprecation == MD_UDPBLACKLISTED; | ||
387 | } | ||
388 | |||
383 | friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg); | 389 | friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg); |
384 | 390 | ||
385 | const LLMessageBlock* getBlock(char* name) const | 391 | const LLMessageBlock* getBlock(char* name) const |
diff --git a/linden/indra/llmessage/llmessagetemplateparser.cpp b/linden/indra/llmessage/llmessagetemplateparser.cpp index d6adba8..9f6eeca 100644 --- a/linden/indra/llmessage/llmessagetemplateparser.cpp +++ b/linden/indra/llmessage/llmessagetemplateparser.cpp | |||
@@ -525,6 +525,10 @@ LLMessageTemplate * LLTemplateParser::parseMessage(LLTemplateTokenizer & tokens) | |||
525 | { | 525 | { |
526 | templatep->setDeprecation(MD_UDPDEPRECATED); | 526 | templatep->setDeprecation(MD_UDPDEPRECATED); |
527 | } | 527 | } |
528 | else if (tokens.want("UDPBlackListed")) | ||
529 | { | ||
530 | templatep->setDeprecation(MD_UDPBLACKLISTED); | ||
531 | } | ||
528 | else if (tokens.want("NotDeprecated")) | 532 | else if (tokens.want("NotDeprecated")) |
529 | { | 533 | { |
530 | // this is the default value, but it can't hurt to set it twice | 534 | // this is the default value, but it can't hurt to set it twice |
diff --git a/linden/indra/llmessage/lltemplatemessagebuilder.cpp b/linden/indra/llmessage/lltemplatemessagebuilder.cpp index cd06c07..6d3ff8f 100644 --- a/linden/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/linden/indra/llmessage/lltemplatemessagebuilder.cpp | |||
@@ -60,7 +60,6 @@ LLTemplateMessageBuilder::~LLTemplateMessageBuilder() | |||
60 | mCurrentSMessageData = NULL; | 60 | mCurrentSMessageData = NULL; |
61 | } | 61 | } |
62 | 62 | ||
63 | |||
64 | // virtual | 63 | // virtual |
65 | void LLTemplateMessageBuilder::newMessage(const char *name) | 64 | void LLTemplateMessageBuilder::newMessage(const char *name) |
66 | { | 65 | { |
diff --git a/linden/indra/llmessage/lltemplatemessagereader.cpp b/linden/indra/llmessage/lltemplatemessagereader.cpp index f5da14b..2c457e8 100644 --- a/linden/indra/llmessage/lltemplatemessagereader.cpp +++ b/linden/indra/llmessage/lltemplatemessagereader.cpp | |||
@@ -791,12 +791,16 @@ bool LLTemplateMessageReader::isTrusted() const | |||
791 | return mCurrentRMessageTemplate->getTrust() == MT_TRUST; | 791 | return mCurrentRMessageTemplate->getTrust() == MT_TRUST; |
792 | } | 792 | } |
793 | 793 | ||
794 | //virtual | ||
795 | bool LLTemplateMessageReader::isBanned(bool trustedSource) const | 794 | bool LLTemplateMessageReader::isBanned(bool trustedSource) const |
796 | { | 795 | { |
797 | return mCurrentRMessageTemplate->isBanned(trustedSource); | 796 | return mCurrentRMessageTemplate->isBanned(trustedSource); |
798 | } | 797 | } |
799 | 798 | ||
799 | bool LLTemplateMessageReader::isUdpBanned() const | ||
800 | { | ||
801 | return mCurrentRMessageTemplate->isUdpBanned(); | ||
802 | } | ||
803 | |||
800 | //virtual | 804 | //virtual |
801 | void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const | 805 | void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const |
802 | { | 806 | { |
diff --git a/linden/indra/llmessage/lltemplatemessagereader.h b/linden/indra/llmessage/lltemplatemessagereader.h index 98f41ae..ff124f3 100644 --- a/linden/indra/llmessage/lltemplatemessagereader.h +++ b/linden/indra/llmessage/lltemplatemessagereader.h | |||
@@ -109,7 +109,8 @@ public: | |||
109 | 109 | ||
110 | bool isTrusted() const; | 110 | bool isTrusted() const; |
111 | bool isBanned(bool trusted_source) const; | 111 | bool isBanned(bool trusted_source) const; |
112 | 112 | bool isUdpBanned() const; | |
113 | |||
113 | private: | 114 | private: |
114 | 115 | ||
115 | void getData(const char *blockname, const char *varname, void *datap, | 116 | void getData(const char *blockname, const char *varname, void *datap, |
diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index 42f3f04..ee62798 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp | |||
@@ -461,26 +461,62 @@ size_t LLURLRequest::upCallback( | |||
461 | 461 | ||
462 | static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) | 462 | static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) |
463 | { | 463 | { |
464 | const char* headerLine = (const char*)data; | 464 | const char* header_line = (const char*)data; |
465 | size_t headerLen = size * nmemb; | 465 | size_t header_len = size * nmemb; |
466 | LLURLRequestComplete* complete = (LLURLRequestComplete*)user; | 466 | LLURLRequestComplete* complete = (LLURLRequestComplete*)user; |
467 | 467 | ||
468 | if (!complete || !header_line) | ||
469 | { | ||
470 | return header_len; | ||
471 | } | ||
472 | |||
468 | // *TODO: This should be a utility in llstring.h: isascii() | 473 | // *TODO: This should be a utility in llstring.h: isascii() |
469 | for (size_t i = 0; i < headerLen; ++i) | 474 | for (size_t i = 0; i < header_len; ++i) |
475 | { | ||
476 | if (header_line[i] < 0) | ||
477 | { | ||
478 | return header_len; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | std::string header(header_line, header_len); | ||
483 | |||
484 | // Per HTTP spec the first header line must be the status line. | ||
485 | if (!complete->haveHTTPStatus()) | ||
470 | { | 486 | { |
471 | if (headerLine[i] < 0) | 487 | if (header.substr(0,5) == "HTTP/") |
472 | { | 488 | { |
473 | return headerLen; | 489 | std::string::iterator end = header.end(); |
490 | std::string::iterator pos1 = std::find(header.begin(), end, ' '); | ||
491 | if (pos1 != end) ++pos1; | ||
492 | std::string::iterator pos2 = std::find(pos1, end, ' '); | ||
493 | if (pos2 != end) ++pos2; | ||
494 | std::string::iterator pos3 = std::find(pos2, end, '\r'); | ||
495 | |||
496 | std::string version(header.begin(), pos1); | ||
497 | std::string status(pos1, pos2); | ||
498 | std::string reason(pos2, pos3); | ||
499 | |||
500 | int statusCode = atoi(status.c_str()); | ||
501 | if (statusCode >= 300 && statusCode < 400) | ||
502 | { | ||
503 | // This is a redirect, ignore it and all headers | ||
504 | // until we find a normal status code. | ||
505 | } | ||
506 | else if (statusCode > 0) | ||
507 | { | ||
508 | complete->httpStatus((U32)statusCode, reason); | ||
509 | } | ||
474 | } | 510 | } |
511 | return header_len; | ||
475 | } | 512 | } |
476 | 513 | ||
477 | size_t sep; | 514 | std::string::iterator sep = std::find(header.begin(),header.end(),':'); |
478 | for (sep = 0; sep < headerLen && headerLine[sep] != ':'; ++sep) { } | ||
479 | 515 | ||
480 | if (sep < headerLen && complete) | 516 | if (sep != header.end()) |
481 | { | 517 | { |
482 | std::string key(headerLine, sep); | 518 | std::string key(header.begin(), sep); |
483 | std::string value(headerLine + sep + 1, headerLen - sep - 1); | 519 | std::string value(sep + 1, header.end()); |
484 | 520 | ||
485 | key = utf8str_tolower(utf8str_trim(key)); | 521 | key = utf8str_tolower(utf8str_trim(key)); |
486 | value = utf8str_trim(value); | 522 | value = utf8str_trim(value); |
@@ -489,30 +525,14 @@ static size_t headerCallback(void* data, size_t size, size_t nmemb, void* user) | |||
489 | } | 525 | } |
490 | else | 526 | else |
491 | { | 527 | { |
492 | std::string s(headerLine, headerLen); | 528 | LLStringUtil::trim(header); |
493 | 529 | if (!header.empty()) | |
494 | std::string::iterator end = s.end(); | ||
495 | std::string::iterator pos1 = std::find(s.begin(), end, ' '); | ||
496 | if (pos1 != end) ++pos1; | ||
497 | std::string::iterator pos2 = std::find(pos1, end, ' '); | ||
498 | if (pos2 != end) ++pos2; | ||
499 | std::string::iterator pos3 = std::find(pos2, end, '\r'); | ||
500 | |||
501 | std::string version(s.begin(), pos1); | ||
502 | std::string status(pos1, pos2); | ||
503 | std::string reason(pos2, pos3); | ||
504 | |||
505 | int statusCode = atoi(status.c_str()); | ||
506 | if (statusCode > 0) | ||
507 | { | 530 | { |
508 | if (complete) | 531 | llwarns << "Unable to parse header: " << header << llendl; |
509 | { | ||
510 | complete->httpStatus((U32)statusCode, reason); | ||
511 | } | ||
512 | } | 532 | } |
513 | } | 533 | } |
514 | 534 | ||
515 | return headerLen; | 535 | return header_len; |
516 | } | 536 | } |
517 | 537 | ||
518 | /** | 538 | /** |
@@ -553,7 +573,8 @@ LLIOPipe::EStatus LLContextURLExtractor::process_impl( | |||
553 | * LLURLRequestComplete | 573 | * LLURLRequestComplete |
554 | */ | 574 | */ |
555 | LLURLRequestComplete::LLURLRequestComplete() : | 575 | LLURLRequestComplete::LLURLRequestComplete() : |
556 | mRequestStatus(LLIOPipe::STATUS_ERROR) | 576 | mRequestStatus(LLIOPipe::STATUS_ERROR), |
577 | mHaveHTTPStatus(false) | ||
557 | { | 578 | { |
558 | LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); | 579 | LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); |
559 | } | 580 | } |
@@ -572,6 +593,7 @@ void LLURLRequestComplete::header(const std::string& header, const std::string& | |||
572 | //virtual | 593 | //virtual |
573 | void LLURLRequestComplete::httpStatus(U32 status, const std::string& reason) | 594 | void LLURLRequestComplete::httpStatus(U32 status, const std::string& reason) |
574 | { | 595 | { |
596 | mHaveHTTPStatus = true; | ||
575 | } | 597 | } |
576 | 598 | ||
577 | //virtual | 599 | //virtual |
diff --git a/linden/indra/llmessage/llurlrequest.h b/linden/indra/llmessage/llurlrequest.h index 888b962..f965dad 100644 --- a/linden/indra/llmessage/llurlrequest.h +++ b/linden/indra/llmessage/llurlrequest.h | |||
@@ -327,6 +327,9 @@ public: | |||
327 | LLURLRequestComplete(); | 327 | LLURLRequestComplete(); |
328 | virtual ~LLURLRequestComplete(); | 328 | virtual ~LLURLRequestComplete(); |
329 | 329 | ||
330 | // The first line of an http response must be the status line | ||
331 | // true if we have already parsed this line. | ||
332 | bool haveHTTPStatus() const { return mHaveHTTPStatus; } | ||
330 | protected: | 333 | protected: |
331 | /* @name LLIOPipe virtual implementations | 334 | /* @name LLIOPipe virtual implementations |
332 | */ | 335 | */ |
@@ -345,6 +348,8 @@ protected: | |||
345 | // value to note if we actually got the response. This value | 348 | // value to note if we actually got the response. This value |
346 | // depends on correct useage from the LLURLRequest instance. | 349 | // depends on correct useage from the LLURLRequest instance. |
347 | EStatus mRequestStatus; | 350 | EStatus mRequestStatus; |
351 | |||
352 | bool mHaveHTTPStatus; | ||
348 | }; | 353 | }; |
349 | 354 | ||
350 | 355 | ||
diff --git a/linden/indra/llmessage/llxfermanager.cpp b/linden/indra/llmessage/llxfermanager.cpp index f40612c..8173b7c 100644 --- a/linden/indra/llmessage/llxfermanager.cpp +++ b/linden/indra/llmessage/llxfermanager.cpp | |||
@@ -713,6 +713,78 @@ void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 pac | |||
713 | 713 | ||
714 | /////////////////////////////////////////////////////////// | 714 | /////////////////////////////////////////////////////////// |
715 | 715 | ||
716 | static bool find_and_remove(std::multiset<std::string>& files, | ||
717 | const std::string& filename) | ||
718 | { | ||
719 | std::multiset<std::string>::iterator ptr; | ||
720 | if ( (ptr = files.find(filename)) != files.end()) | ||
721 | { | ||
722 | //erase(filename) erases *all* entries with that key | ||
723 | files.erase(ptr); | ||
724 | return true; | ||
725 | } | ||
726 | return false; | ||
727 | } | ||
728 | |||
729 | void LLXferManager::expectFileForRequest(const std::string& filename) | ||
730 | { | ||
731 | mExpectedRequests.insert(filename); | ||
732 | } | ||
733 | |||
734 | bool LLXferManager::validateFileForRequest(const std::string& filename) | ||
735 | { | ||
736 | return find_and_remove(mExpectedRequests, filename); | ||
737 | } | ||
738 | |||
739 | void LLXferManager::expectFileForTransfer(const std::string& filename) | ||
740 | { | ||
741 | mExpectedTransfers.insert(filename); | ||
742 | } | ||
743 | |||
744 | bool LLXferManager::validateFileForTransfer(const std::string& filename) | ||
745 | { | ||
746 | return find_and_remove(mExpectedTransfers, filename); | ||
747 | } | ||
748 | |||
749 | static bool remove_prefix(std::string& filename, const std::string& prefix) | ||
750 | { | ||
751 | if (std::equal(prefix.begin(), prefix.end(), filename.begin())) | ||
752 | { | ||
753 | filename = filename.substr(prefix.length()); | ||
754 | return true; | ||
755 | } | ||
756 | return false; | ||
757 | } | ||
758 | |||
759 | static bool verify_cache_filename(const std::string& filename) | ||
760 | { | ||
761 | //NOTE: This routine is only used to check file names that our own | ||
762 | // code places in the cache directory. As such, it can be limited | ||
763 | // to this very restrictive file name pattern. It does not need to | ||
764 | // handle other characters. | ||
765 | |||
766 | size_t len = filename.size(); | ||
767 | //const boost::regex expr("[a-zA-Z0-9][-_.a-zA-Z0-9]<0,49>"); | ||
768 | if (len < 1 || len > 50) | ||
769 | { | ||
770 | return false; | ||
771 | } | ||
772 | for(unsigned i=0; i<len; ++i) | ||
773 | { | ||
774 | char c = filename[i]; | ||
775 | bool ok = isalnum(c); | ||
776 | if (!ok && i > 0) | ||
777 | { | ||
778 | ok = '_'==c || '-'==c || '.'==c; | ||
779 | } | ||
780 | if (!ok) | ||
781 | { | ||
782 | return false; | ||
783 | } | ||
784 | } | ||
785 | return true; | ||
786 | } | ||
787 | |||
716 | void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/) | 788 | void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/) |
717 | { | 789 | { |
718 | 790 | ||
@@ -734,16 +806,11 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user | |||
734 | 806 | ||
735 | mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename); | 807 | mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename); |
736 | 808 | ||
737 | U8 local_path_u8; | ||
738 | mesgsys->getU8("XferID", "FilePath", local_path_u8); | ||
739 | if( local_path_u8 < (U8)LL_PATH_LAST ) | ||
740 | { | 809 | { |
810 | U8 local_path_u8; | ||
811 | mesgsys->getU8("XferID", "FilePath", local_path_u8); | ||
741 | local_path = (ELLPath)local_path_u8; | 812 | local_path = (ELLPath)local_path_u8; |
742 | } | 813 | } |
743 | else | ||
744 | { | ||
745 | llwarns << "Invalid file path in LLXferManager::processFileRequest() " << (U32)local_path_u8 << llendl; | ||
746 | } | ||
747 | 814 | ||
748 | mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid); | 815 | mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid); |
749 | mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16); | 816 | mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16); |
@@ -782,6 +849,43 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user | |||
782 | } | 849 | } |
783 | else if (!local_filename.empty()) | 850 | else if (!local_filename.empty()) |
784 | { | 851 | { |
852 | // See DEV-21775 for detailed security issues | ||
853 | |||
854 | if (local_path == LL_PATH_NONE) | ||
855 | { | ||
856 | // this handles legacy simulators that are passing objects | ||
857 | // by giving a filename that explicitly names the cache directory | ||
858 | static const std::string legacy_cache_prefix = "data/"; | ||
859 | if (remove_prefix(local_filename, legacy_cache_prefix)) | ||
860 | { | ||
861 | local_path = LL_PATH_CACHE; | ||
862 | } | ||
863 | } | ||
864 | |||
865 | switch (local_path) | ||
866 | { | ||
867 | case LL_PATH_NONE: | ||
868 | if(!validateFileForTransfer(local_filename)) | ||
869 | { | ||
870 | llwarns << "SECURITY: Unapproved filename '" << local_filename << llendl; | ||
871 | return; | ||
872 | } | ||
873 | break; | ||
874 | |||
875 | case LL_PATH_CACHE: | ||
876 | if(!verify_cache_filename(local_filename)) | ||
877 | { | ||
878 | llwarns << "SECURITY: Illegal cache filename '" << local_filename << llendl; | ||
879 | return; | ||
880 | } | ||
881 | break; | ||
882 | |||
883 | default: | ||
884 | llwarns << "SECURITY: Restricted file dir enum: " << (U32)local_path << llendl; | ||
885 | return; | ||
886 | } | ||
887 | |||
888 | |||
785 | std::string expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename ); | 889 | std::string expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename ); |
786 | llinfos << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << llendl; | 890 | llinfos << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << llendl; |
787 | 891 | ||
@@ -861,6 +965,7 @@ void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user | |||
861 | } | 965 | } |
862 | } | 966 | } |
863 | 967 | ||
968 | |||
864 | /////////////////////////////////////////////////////////// | 969 | /////////////////////////////////////////////////////////// |
865 | 970 | ||
866 | void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*user_data*/) | 971 | void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*user_data*/) |
diff --git a/linden/indra/llmessage/llxfermanager.h b/linden/indra/llmessage/llxfermanager.h index 77f3f60..4bcf5de 100644 --- a/linden/indra/llmessage/llxfermanager.h +++ b/linden/indra/llmessage/llxfermanager.h | |||
@@ -108,6 +108,8 @@ class LLXferManager | |||
108 | // implementation methods | 108 | // implementation methods |
109 | virtual void startPendingDownloads(); | 109 | virtual void startPendingDownloads(); |
110 | virtual void addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority); | 110 | virtual void addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority); |
111 | std::multiset<std::string> mExpectedTransfers; // files that are authorized to transfer out | ||
112 | std::multiset<std::string> mExpectedRequests; // files that are authorized to be downloaded on top of | ||
111 | 113 | ||
112 | public: | 114 | public: |
113 | LLXferManager(LLVFS *vfs); | 115 | LLXferManager(LLVFS *vfs); |
@@ -168,6 +170,20 @@ class LLXferManager | |||
168 | const LLHost& remote_host, | 170 | const LLHost& remote_host, |
169 | void (*callback)(void**,S32,LLExtStat), void** user_data, | 171 | void (*callback)(void**,S32,LLExtStat), void** user_data, |
170 | BOOL is_priority = FALSE); | 172 | BOOL is_priority = FALSE); |
173 | /** | ||
174 | When arbitrary files are requested to be transfered (by giving a dir of LL_PATH_NONE) | ||
175 | they must be "expected", but having something pre-authorize them. This pair of functions | ||
176 | maintains a pre-authorized list. The first function adds something to the list, the second | ||
177 | checks if is authorized, removing it if so. In this way, a file is only authorized for | ||
178 | a single use. | ||
179 | */ | ||
180 | virtual void expectFileForTransfer(const std::string& filename); | ||
181 | virtual bool validateFileForTransfer(const std::string& filename); | ||
182 | /** | ||
183 | Same idea, but for the viewer about to call InitiateDownload to track what it requested. | ||
184 | */ | ||
185 | virtual void expectFileForRequest(const std::string& filename); | ||
186 | virtual bool validateFileForRequest(const std::string& filename); | ||
171 | 187 | ||
172 | /* | 188 | /* |
173 | // xfer request (may be memory or file) | 189 | // xfer request (may be memory or file) |
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index 27f9d12..b20731a 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp | |||
@@ -754,11 +754,19 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count ) | |||
754 | clearReceiveState(); | 754 | clearReceiveState(); |
755 | valid_packet = FALSE; | 755 | valid_packet = FALSE; |
756 | } | 756 | } |
757 | |||
758 | if( valid_packet && mTemplateMessageReader->isUdpBanned()) | ||
759 | { | ||
760 | llwarns << "Received UDP black listed message " | ||
761 | << mTemplateMessageReader->getMessageName() | ||
762 | << " from " << host << llendl; | ||
763 | clearReceiveState(); | ||
764 | valid_packet = FALSE; | ||
765 | } | ||
757 | 766 | ||
758 | if( valid_packet ) | 767 | if( valid_packet ) |
759 | { | 768 | { |
760 | logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); | 769 | logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); |
761 | |||
762 | valid_packet = mTemplateMessageReader->readMessage(buffer, host); | 770 | valid_packet = mTemplateMessageReader->readMessage(buffer, host); |
763 | } | 771 | } |
764 | 772 | ||