summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorKaren Lahey <karina@lindenlab.com>2009-10-15 16:52:03 -0700
committerKaren Lahey <karina@lindenlab.com>2009-10-15 16:52:03 -0700
commit73e86b0bed548b2aaba8d92837e562d6d753808a (patch)
treeee77d1f79fee430bb64c61d89988a0cb07ecf257 /indra
parent7ab41a8a815968e274ebbfc459328be40cf5479a (diff)
MAC Address Change no longer causes viewer to die cr:Roxie
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/lluuid.cpp161
-rw-r--r--indra/newview/llappviewer.cpp14
-rw-r--r--indra/newview/llsecapi.cpp22
-rw-r--r--indra/newview/llsecapi.h12
-rw-r--r--indra/newview/llsechandler_basic.cpp30
-rw-r--r--indra/newview/llsechandler_basic.h2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml12
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp5
8 files changed, 182 insertions, 76 deletions
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index bcbae06ec5..152223d524 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -36,6 +36,8 @@
# undef WIN32_LEAN_AND_MEAN
# include <winsock2.h>
# include <windows.h>
+# pragma comment(lib, "IPHLPAPI.lib")
+# include <iphlpapi.h>
#endif
#include "lldefs.h"
@@ -452,67 +454,104 @@ static void get_random_bytes(void *buf, int nbytes)
return;
}
-#if LL_WINDOWS
-typedef struct _ASTAT_
-{
- ADAPTER_STATUS adapt;
- NAME_BUFFER NameBuff [30];
-}ASTAT, * PASTAT;
-
-// static
-S32 LLUUID::getNodeID(unsigned char * node_id)
-{
- ASTAT Adapter;
- NCB Ncb;
- UCHAR uRetCode;
- LANA_ENUM lenum;
- int i;
- int retval = 0;
-
- memset( &Ncb, 0, sizeof(Ncb) );
- Ncb.ncb_command = NCBENUM;
- Ncb.ncb_buffer = (UCHAR *)&lenum;
- Ncb.ncb_length = sizeof(lenum);
- uRetCode = Netbios( &Ncb );
- // printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
-
- for(i=0; i < lenum.length ;i++)
- {
- memset( &Ncb, 0, sizeof(Ncb) );
- Ncb.ncb_command = NCBRESET;
- Ncb.ncb_lana_num = lenum.lana[i];
-
- uRetCode = Netbios( &Ncb );
- // printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
- // lenum.lana[i], uRetCode );
-
- memset( &Ncb, 0, sizeof (Ncb) );
- Ncb.ncb_command = NCBASTAT;
- Ncb.ncb_lana_num = lenum.lana[i];
-
- strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */
- Ncb.ncb_buffer = (unsigned char *)&Adapter;
- Ncb.ncb_length = sizeof(Adapter);
-
- uRetCode = Netbios( &Ncb );
-// printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
-// lenum.lana[i], uRetCode );
- if ( uRetCode == 0 )
- {
-// printf( "The Ethernet Number on LANA %d is: %02x%02x%02x%02x%02x%02x\n",
-// lenum.lana[i],
-// Adapter.adapt.adapter_address[0],
-// Adapter.adapt.adapter_address[1],
-// Adapter.adapt.adapter_address[2],
-// Adapter.adapt.adapter_address[3],
-// Adapter.adapt.adapter_address[4],
-// Adapter.adapt.adapter_address[5] );
- memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */
- retval = 1;
-
- }
- }
- return retval;
+#if LL_WINDOWS
+// Code copied from http://msdn.microsoft.com/en-us/library/aa365939(VS.85).aspx
+// This code grabs the first hardware address, rather than the first interface.
+// Using a VPN can cause the first returned interface to be changed.
+
+#define MALLOC(x)HeapAlloc(GetProcessHeap(),0,(x))
+#define FREE(x) HeapFree(GetProcessHeap(),0,(x))
+const S32 MAC_ADDRESS_BYTES=6;
+
+
+// static
+S32 LLUUID::getNodeID(unsigned char *node_id)
+{
+
+ // Declare and initialize variables.
+ DWORD dwSize = 0;
+ DWORD dwRetVal = 0;
+ int i;
+
+/* variables used for GetIfTable and GetIfEntry */
+ MIB_IFTABLE *pIfTable;
+ MIB_IFROW *pIfRow;
+
+ // Allocate memory for our pointers.
+ pIfTable = (MIB_IFTABLE *) MALLOC(sizeof (MIB_IFTABLE));
+ if (pIfTable == NULL)
+ {
+ printf("Error allocating memory needed to call GetIfTable\n");
+ return 0;
+ }
+
+ // Before calling GetIfEntry, we call GetIfTable to make
+ // sure there are entries to get and retrieve the interface index.
+
+ // Make an initial call to GetIfTable to get the
+ // necessary size into dwSize
+ if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
+ FREE(pIfTable);
+ pIfTable = (MIB_IFTABLE *) MALLOC(dwSize);
+ if (pIfTable == NULL)
+ {
+ printf("Error allocating memory\n");
+ return 0;
+ }
+ }
+ // Make a second call to GetIfTable to get the actual
+ // data we want.
+ if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR)
+ {
+ if (pIfTable->dwNumEntries > 0)
+ {
+ pIfRow = (MIB_IFROW *) MALLOC(sizeof (MIB_IFROW));
+ if (pIfRow == NULL)
+ {
+ printf("Error allocating memory\n");
+ if (pIfTable != NULL)
+ {
+ FREE(pIfTable);
+ pIfTable = NULL;
+ }
+ return 0;
+ }
+
+ int limit = MAC_ADDRESS_BYTES;
+ memcpy(node_id, "\0\0\0\0\0\0", limit); // zero out array of bytes
+ for (i = 0; i < (int) pIfTable->dwNumEntries; i++)
+ {
+ pIfRow->dwIndex = pIfTable->table[i].dwIndex;
+ if ((dwRetVal = GetIfEntry(pIfRow)) == NO_ERROR)
+ {
+ switch (pIfRow->dwType)
+ {
+ case IF_TYPE_ETHERNET_CSMACD:
+ case IF_TYPE_IEEE80211:
+ limit = min((int) pIfRow->dwPhysAddrLen, limit);
+ if (pIfRow->dwPhysAddrLen == 0)
+ break;
+ memcpy(node_id, (UCHAR *)&pIfRow->bPhysAddr[0], limit); // just incase the PhysAddr is not the expected MAC_Address size
+ FREE(pIfTable);
+ return 1; //return first hardware device found.
+ break;
+
+ case IF_TYPE_OTHER:
+ case IF_TYPE_PPP:
+ case IF_TYPE_SOFTWARE_LOOPBACK:
+ case IF_TYPE_ISO88025_TOKENRING:
+ case IF_TYPE_IEEE1394:
+ case IF_TYPE_ATM:
+ case IF_TYPE_TUNNEL:
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ FREE(pIfTable);
+ return 0;
}
#elif LL_DARWIN
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 187038ab15..c2f8487aa9 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -620,8 +620,6 @@ bool LLAppViewer::init()
LLCurl::initClass();
initThreads();
- initializeSecHandler();
- LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
writeSystemInfo();
// Build a string representing the current version number.
@@ -862,6 +860,7 @@ bool LLAppViewer::init()
}
}
+
// save the graphics card
gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
@@ -872,6 +871,17 @@ bool LLAppViewer::init()
gSimFrames = (F32)gFrameCount;
LLViewerJoystick::getInstance()->init(false);
+
+ try {
+ initializeSecHandler();
+ }
+ catch (LLProtectedDataException ex)
+ {
+ LLNotificationsUtil::add("CorruptedProtectedDataStore");
+ }
+ LLHTTPClient::setCertVerifyCallback(secapiSSLCertVerifyCallback);
+
+
gGLActive = FALSE;
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp
index a928b4580e..ba343f5387 100644
--- a/indra/newview/llsecapi.cpp
+++ b/indra/newview/llsecapi.cpp
@@ -50,11 +50,33 @@ void initializeSecHandler()
OpenSSL_add_all_digests();
gHandlerMap[BASIC_SECHANDLER] = new LLSecAPIBasicHandler();
+
// Currently, we only have the Basic handler, so we can point the main sechandler
// pointer to the basic handler. Later, we'll create a wrapper handler that
// selects the appropriate sechandler as needed, for instance choosing the
// mac keyring handler, with fallback to the basic sechandler
gSecAPIHandler = gHandlerMap[BASIC_SECHANDLER];
+
+ // initialize all SecAPIHandlers
+ LLProtectedDataException ex = LLProtectedDataException("");
+ std::map<std::string, LLPointer<LLSecAPIHandler> >::const_iterator itr;
+ for(itr = gHandlerMap.begin(); itr != gHandlerMap.end(); ++itr)
+ {
+ LLPointer<LLSecAPIHandler> handler = (*itr).second;
+ try
+ {
+ handler->init();
+ }
+ catch (LLProtectedDataException e)
+ {
+ ex = e;
+ }
+ }
+ if (ex.getMessage().length() > 0 ) // an exception was thrown.
+ {
+ throw ex;
+ }
+
}
// start using a given security api handler. If the string is empty
// the default is used
diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h
index d3fb3c4c07..b11563ef62 100644
--- a/indra/newview/llsecapi.h
+++ b/indra/newview/llsecapi.h
@@ -47,7 +47,7 @@
#define CERT_ISSUER_NAME "issuer_name"
#define CERT_NAME_CN "commonName"
-#define CERT_SUBJECT_NAME_STRING "subject_name_string"
+#define CERT_SUBJECT_NAME_STRING "subject_name_string"
#define CERT_ISSUER_NAME_STRING "issuer_name_string"
#define CERT_SERIAL_NUMBER "serial_number"
@@ -118,9 +118,10 @@ class LLProtectedDataException
public:
LLProtectedDataException(const char *msg)
{
- llerrs << "Certificate Error: " << msg << llendl;
- mMsg = std::string(msg);
+ LL_WARNS("SECAPI") << "Protected Data Error: " << (std::string)msg << LL_ENDL;
+ mMsg = (std::string)msg;
}
+ std::string getMessage() { return mMsg; }
protected:
std::string mMsg;
};
@@ -421,13 +422,18 @@ class LLSecAPIHandler : public LLRefCount
{
public:
+
LLSecAPIHandler() {}
virtual ~LLSecAPIHandler() {}
+ // initialize the SecAPIHandler
+ virtual void init() {};
+
// instantiate a certificate from a pem string
virtual LLPointer<LLCertificate> getCertificate(const std::string& pem_cert)=0;
+
// instiate a certificate from an openssl X509 structure
virtual LLPointer<LLCertificate> getCertificate(X509* openssl_cert)=0;
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 097cc395d7..1453506b0d 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -1028,20 +1028,29 @@ LLSecAPIBasicHandler::LLSecAPIBasicHandler(const std::string& protected_data_fil
mProtectedDataFilename = protected_data_file;
mProtectedDataMap = LLSD::emptyMap();
mLegacyPasswordPath = legacy_password_path;
- _readProtectedData();
+
}
LLSecAPIBasicHandler::LLSecAPIBasicHandler()
{
- mProtectedDataFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
- "bin_conf.dat");
- mLegacyPasswordPath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "password.dat");
+}
+
+void LLSecAPIBasicHandler::init()
+{
+ if (mProtectedDataFilename.length() == 0)
+ {
+ mProtectedDataFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
+ "bin_conf.dat");
+ }
+ if (mLegacyPasswordPath.length() == 0)
+ {
+ mLegacyPasswordPath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "password.dat");
+ }
mProtectedDataMap = LLSD::emptyMap();
mProtectedDataFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"bin_conf.dat");
- _readProtectedData();
std::string store_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
"CA.pem");
@@ -1051,8 +1060,6 @@ LLSecAPIBasicHandler::LLSecAPIBasicHandler()
// will reduce that risk.
// by using a user file, modifications will be limited to one user if
// we read-only the main file
-
-
if (!LLFile::isfile(store_file))
{
@@ -1071,8 +1078,9 @@ LLSecAPIBasicHandler::LLSecAPIBasicHandler()
}
LL_INFOS("SECAPI") << "Loading certificate store from " << store_file << LL_ENDL;
mStore = new LLBasicCertificateStore(store_file);
+ _readProtectedData(); // initialize mProtectedDataMap
+ // may throw LLProtectedDataException if saved datamap is not decryptable
}
-
LLSecAPIBasicHandler::~LLSecAPIBasicHandler()
{
_writeProtectedData();
@@ -1084,6 +1092,7 @@ void LLSecAPIBasicHandler::_readProtectedData()
LLPointer<LLSDParser> parser = new LLSDXMLParser();
llifstream protected_data_stream(mProtectedDataFilename.c_str(),
llifstream::binary);
+
if (!protected_data_stream.fail()) {
int offset;
U8 salt[STORE_SALT_SIZE];
@@ -1099,7 +1108,7 @@ void LLSecAPIBasicHandler::_readProtectedData()
offset = 0;
if (protected_data_stream.gcount() < STORE_SALT_SIZE)
{
- throw LLProtectedDataException("Corrupt Protected Data Store1");
+ throw LLProtectedDataException("Config file too short.");
}
cipher.decrypt(salt, STORE_SALT_SIZE);
@@ -1139,7 +1148,7 @@ void LLSecAPIBasicHandler::_readProtectedData()
if (parser->parse(parse_stream, mProtectedDataMap,
LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
{
- throw LLProtectedDataException("Corrupt Protected Data Store");
+ throw LLProtectedDataException("Config file cannot be decrypted.");
}
}
}
@@ -1254,6 +1263,7 @@ LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const st
LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type,
const std::string& data_id)
{
+
if (mProtectedDataMap.has(data_type) &&
mProtectedDataMap[data_type].isMap() &&
mProtectedDataMap[data_type].has(data_id))
diff --git a/indra/newview/llsechandler_basic.h b/indra/newview/llsechandler_basic.h
index e041322260..4bbb73f062 100644
--- a/indra/newview/llsechandler_basic.h
+++ b/indra/newview/llsechandler_basic.h
@@ -221,6 +221,8 @@ public:
const std::string& legacy_password_path);
LLSecAPIBasicHandler();
+ void init();
+
virtual ~LLSecAPIBasicHandler();
// instantiate a certificate from a pem string
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d177cfce7d..333f5d3d2a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1358,6 +1358,18 @@ Unable to encode file: [FILE]
<notification
icon="alertmodal.tga"
+ name="CorruptedProtectedDataStore"
+ type="alertmodal">
+ We are unable to read your protected data so it is being reset.
+ This may happen when you change network setup.
+
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="CorruptResourceFile"
type="alertmodal">
Corrupt resource file: [FILE]
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index f52ebc198d..3e4e8c5b3e 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -340,6 +340,7 @@ namespace tut
LLPointer<LLSecAPIBasicHandler> handler = new LLSecAPIBasicHandler("sechandler_settings.tmp",
"test_password.dat");
+ handler.init();
// data retrieval for existing data
LLSD data = handler->getProtectedData("test_data_type", "test_data_id");
@@ -397,6 +398,7 @@ namespace tut
// cause a 'write' by using 'LLPointer' to delete then instantiate a handler
handler = NULL;
handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat");
+ handler.init();
data = handler->getProtectedData("test_data_type1", "test_data_id");
ensure_equals("verify datatype stored data3a", (std::string)data["store_data3"], "test_store_data3");
@@ -411,6 +413,7 @@ namespace tut
// cause a 'write'
handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat");
+ handler.init();
data = handler->getProtectedData("test_data_type1", "test_data_id");
ensure("not found", data.isUndefined());
@@ -419,6 +422,7 @@ namespace tut
LLFile::remove("sechandler_settings.tmp");
handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat");
+ handler.init();
data = handler->getProtectedData("test_data_type1", "test_data_id");
ensure("not found", data.isUndefined());
handler = NULL;
@@ -431,6 +435,7 @@ namespace tut
void sechandler_basic_test_object::test<3>()
{
LLPointer<LLSecAPIBasicHandler> handler = new LLSecAPIBasicHandler("sechandler_settings.tmp", "test_password.dat");
+ handler.init();
LLSD my_id = LLSD::emptyMap();
LLSD my_authenticator = LLSD::emptyMap();