diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/llstartup.cpp | 199 |
1 files changed, 193 insertions, 6 deletions
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 08e12ce..dcaa249 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp | |||
@@ -76,6 +76,7 @@ | |||
76 | #include "llstring.h" | 76 | #include "llstring.h" |
77 | #include "lluserrelations.h" | 77 | #include "lluserrelations.h" |
78 | #include "llvfs.h" | 78 | #include "llvfs.h" |
79 | #include "llxorcipher.h" // saved password, MAC address | ||
79 | #include "message.h" | 80 | #include "message.h" |
80 | #include "v3math.h" | 81 | #include "v3math.h" |
81 | 82 | ||
@@ -216,6 +217,10 @@ | |||
216 | #include "hippogridmanager.h" | 217 | #include "hippogridmanager.h" |
217 | #include "hippolimits.h" | 218 | #include "hippolimits.h" |
218 | 219 | ||
220 | #if USE_OTR // [$PLOTR$] | ||
221 | #include "otr_wrapper.h" | ||
222 | #endif // USE_OTR // [/$PLOTR$] | ||
223 | |||
219 | #include "lggautocorrect.h" | 224 | #include "lggautocorrect.h" |
220 | // | 225 | // |
221 | // exported globals | 226 | // exported globals |
@@ -261,6 +266,7 @@ bool LLStartUp::sLoginFailed = false; | |||
261 | 266 | ||
262 | void login_show(); | 267 | void login_show(); |
263 | void login_callback(S32 option, void* userdata); | 268 | void login_callback(S32 option, void* userdata); |
269 | bool is_hex_string(U8* str, S32 len); | ||
264 | void show_first_run_dialog(); | 270 | void show_first_run_dialog(); |
265 | bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); | 271 | bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); |
266 | void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); | 272 | void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); |
@@ -1004,8 +1010,9 @@ bool idle_startup() | |||
1004 | gDebugInfo["LoginName"] = firstname + " " + lastname; | 1010 | gDebugInfo["LoginName"] = firstname + " " + lastname; |
1005 | 1011 | ||
1006 | // create necessary directories | 1012 | // create necessary directories |
1007 | gDirUtilp->setLindenUserDir(gHippoGridManager->getCurrentGridNick(), firstname, lastname); | 1013 | // *FIX: these mkdir's should error check |
1008 | LLFile::mkdir(gDirUtilp->getLindenUserDir()); | 1014 | gDirUtilp->setViewerUserDir(gHippoGridManager->getCurrentGridNick(), firstname, lastname); |
1015 | LLFile::mkdir(gDirUtilp->getViewerUserDir()); | ||
1009 | } | 1016 | } |
1010 | else | 1017 | else |
1011 | { | 1018 | { |
@@ -1289,7 +1296,7 @@ bool idle_startup() | |||
1289 | 1296 | ||
1290 | char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ | 1297 | char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */ |
1291 | LLMD5 hashed_mac; | 1298 | LLMD5 hashed_mac; |
1292 | hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES ); | 1299 | hashed_mac.update( (const unsigned char*) "012345", MAC_ADDRESS_BYTES ); // Nope, LL ain't getting our MAC, and meta7 does not need it. |
1293 | hashed_mac.finalize(); | 1300 | hashed_mac.finalize(); |
1294 | hashed_mac.hex_digest(hashed_mac_string); | 1301 | hashed_mac.hex_digest(hashed_mac_string); |
1295 | 1302 | ||
@@ -2542,7 +2549,7 @@ bool idle_startup() | |||
2542 | } | 2549 | } |
2543 | } | 2550 | } |
2544 | // Either we want to show tutorial because this is the first login | 2551 | // Either we want to show tutorial because this is the first login |
2545 | // to a Linden Help Island or the user quit with the tutorial | 2552 | // to a grid Help Island or the user quit with the tutorial |
2546 | // visible. JC | 2553 | // visible. JC |
2547 | if (show_hud | 2554 | if (show_hud |
2548 | || gSavedSettings.getBOOL("ShowTutorial")) | 2555 | || gSavedSettings.getBOOL("ShowTutorial")) |
@@ -2914,6 +2921,9 @@ bool idle_startup() | |||
2914 | } | 2921 | } |
2915 | 2922 | ||
2916 | LLFirstUse::ClientTags(); | 2923 | LLFirstUse::ClientTags(); |
2924 | #if USE_OTR // [$PLOTR$] | ||
2925 | LLFirstUse::EmeraldOTR(); | ||
2926 | #endif // USE_OTR // [/$PLOTR$] | ||
2917 | 2927 | ||
2918 | // Add login location to teleport history 'teleported-into' | 2928 | // Add login location to teleport history 'teleported-into' |
2919 | LLVector3 agent_pos=gAgent.getPositionAgent(); | 2929 | LLVector3 agent_pos=gAgent.getPositionAgent(); |
@@ -2950,7 +2960,11 @@ bool idle_startup() | |||
2950 | { | 2960 | { |
2951 | gAgent.requestEnterGodMode(); | 2961 | gAgent.requestEnterGodMode(); |
2952 | } | 2962 | } |
2953 | 2963 | ||
2964 | #if USE_OTR // [$PLOTR$] | ||
2965 | OTR_Wrapper::init(); | ||
2966 | #endif // USE_OTR // [/$PLOTR$] | ||
2967 | |||
2954 | // Start automatic replay if the flag is set. | 2968 | // Start automatic replay if the flag is set. |
2955 | if (gSavedSettings.getBOOL("StatsAutoRun")) | 2969 | if (gSavedSettings.getBOOL("StatsAutoRun")) |
2956 | { | 2970 | { |
@@ -3112,6 +3126,179 @@ void login_callback(S32 option, void *userdata) | |||
3112 | } | 3126 | } |
3113 | 3127 | ||
3114 | 3128 | ||
3129 | // static | ||
3130 | std::string LLStartUp::loadPasswordFromDisk() | ||
3131 | { | ||
3132 | // Only load password if we also intend to save it (otherwise the user | ||
3133 | // wonders what we're doing behind his back). JC | ||
3134 | BOOL remember_password = gSavedSettings.getBOOL("RememberPassword"); | ||
3135 | if (!remember_password) | ||
3136 | { | ||
3137 | return std::string(""); | ||
3138 | } | ||
3139 | |||
3140 | std::string hashed_password(""); | ||
3141 | |||
3142 | // Look for legacy "marker" password from settings.ini | ||
3143 | hashed_password = gSavedSettings.getString("Marker"); | ||
3144 | if (!hashed_password.empty()) | ||
3145 | { | ||
3146 | // Stomp the Marker entry. | ||
3147 | gSavedSettings.setString("Marker", ""); | ||
3148 | |||
3149 | // Return that password. | ||
3150 | return hashed_password; | ||
3151 | } | ||
3152 | |||
3153 | // UUID is 16 bytes, written into ASCII is 32 characters | ||
3154 | // without trailing \0 | ||
3155 | const S32 HASHED_LENGTH = 32; | ||
3156 | |||
3157 | std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, | ||
3158 | "password.dat"); | ||
3159 | LLFILE* fp = LLFile::fopen(filepath, "rb"); /* Flawfinder: ignore */ | ||
3160 | if (!fp) | ||
3161 | { | ||
3162 | #if LL_DARWIN | ||
3163 | UInt32 passwordLength; | ||
3164 | char *passwordData; | ||
3165 | OSStatus stat = SecKeychainFindGenericPassword(NULL, 10, "meta-impy", 0, NULL, &passwordLength, (void**)&passwordData, NULL); | ||
3166 | if (stat == noErr) | ||
3167 | { | ||
3168 | if (passwordLength == HASHED_LENGTH) | ||
3169 | hashed_password.assign(passwordData, HASHED_LENGTH); | ||
3170 | SecKeychainItemFreeContent(NULL, passwordData); | ||
3171 | } | ||
3172 | #endif | ||
3173 | return hashed_password; | ||
3174 | } | ||
3175 | |||
3176 | U8 buffer[HASHED_LENGTH+1]; | ||
3177 | |||
3178 | if (1 != fread(buffer, HASHED_LENGTH, 1, fp)) | ||
3179 | { | ||
3180 | return hashed_password; | ||
3181 | } | ||
3182 | |||
3183 | fclose(fp); | ||
3184 | |||
3185 | // Decipher with MAC address | ||
3186 | LLXORCipher cipher(gMACAddress, 6); // The one and only legitimate use of the users MAC. | ||
3187 | cipher.decrypt(buffer, HASHED_LENGTH); | ||
3188 | |||
3189 | buffer[HASHED_LENGTH] = '\0'; | ||
3190 | |||
3191 | // Check to see if the mac address generated a bad hashed | ||
3192 | // password. It should be a hex-string or else the mac adress has | ||
3193 | // changed. This is a security feature to make sure that if you | ||
3194 | // get someone's password.dat file, you cannot hack their account. | ||
3195 | if(is_hex_string(buffer, HASHED_LENGTH)) | ||
3196 | { | ||
3197 | hashed_password.assign((char*)buffer); | ||
3198 | } | ||
3199 | #if LL_DARWIN | ||
3200 | // we're migrating to the keychain | ||
3201 | LLFile::remove(filepath); | ||
3202 | #endif | ||
3203 | |||
3204 | return hashed_password; | ||
3205 | } | ||
3206 | |||
3207 | |||
3208 | // static | ||
3209 | void LLStartUp::savePasswordToDisk(const std::string& hashed_password) | ||
3210 | { | ||
3211 | #if LL_DARWIN | ||
3212 | SecKeychainItemRef keychainItem; | ||
3213 | OSStatus status = SecKeychainFindGenericPassword(NULL, 10, "meta-impy", 0, NULL, NULL, NULL, &keychainItem); | ||
3214 | if (status == noErr) | ||
3215 | { | ||
3216 | SecKeychainItemModifyAttributesAndData(keychainItem, NULL, hashed_password.length(), hashed_password.c_str()); | ||
3217 | CFRelease(keychainItem); | ||
3218 | } | ||
3219 | else | ||
3220 | { | ||
3221 | SecKeychainAddGenericPassword(NULL, 10, "meta-impy", 0, NULL, hashed_password.length(), hashed_password.c_str(), NULL); | ||
3222 | } | ||
3223 | #else | ||
3224 | std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, | ||
3225 | "password.dat"); | ||
3226 | LLFILE* fp = LLFile::fopen(filepath, "wb"); /* Flawfinder: ignore */ | ||
3227 | if (!fp) | ||
3228 | { | ||
3229 | return; | ||
3230 | } | ||
3231 | |||
3232 | // Encipher with MAC address | ||
3233 | const S32 HASHED_LENGTH = 32; | ||
3234 | U8 buffer[HASHED_LENGTH+1]; | ||
3235 | |||
3236 | LLStringUtil::copy((char*)buffer, hashed_password.c_str(), HASHED_LENGTH+1); | ||
3237 | |||
3238 | LLXORCipher cipher(gMACAddress, 6); // The one and only legitimate use of the users MAC. | ||
3239 | cipher.encrypt(buffer, HASHED_LENGTH); | ||
3240 | |||
3241 | if (fwrite(buffer, HASHED_LENGTH, 1, fp) != 1) | ||
3242 | { | ||
3243 | LL_WARNS("AppInit") << "Short write" << LL_ENDL; | ||
3244 | } | ||
3245 | |||
3246 | fclose(fp); | ||
3247 | #endif | ||
3248 | } | ||
3249 | |||
3250 | |||
3251 | // static | ||
3252 | void LLStartUp::deletePasswordFromDisk() | ||
3253 | { | ||
3254 | #if LL_DARWIN | ||
3255 | SecKeychainItemRef keychainItem; | ||
3256 | OSStatus status = SecKeychainFindGenericPassword(NULL, 10, "meta-impy", 0, NULL, NULL, NULL, &keychainItem); | ||
3257 | if (status == noErr) | ||
3258 | { | ||
3259 | SecKeychainItemDelete(keychainItem); | ||
3260 | CFRelease(keychainItem); | ||
3261 | } | ||
3262 | #endif | ||
3263 | std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, | ||
3264 | "password.dat"); | ||
3265 | LLFile::remove(filepath); | ||
3266 | } | ||
3267 | |||
3268 | bool is_hex_string(U8* str, S32 len) | ||
3269 | { | ||
3270 | bool rv = true; | ||
3271 | U8* c = str; | ||
3272 | while(rv && len--) | ||
3273 | { | ||
3274 | switch(*c) | ||
3275 | { | ||
3276 | case '0': | ||
3277 | case '1': | ||
3278 | case '2': | ||
3279 | case '3': | ||
3280 | case '4': | ||
3281 | case '5': | ||
3282 | case '6': | ||
3283 | case '7': | ||
3284 | case '8': | ||
3285 | case '9': | ||
3286 | case 'a': | ||
3287 | case 'b': | ||
3288 | case 'c': | ||
3289 | case 'd': | ||
3290 | case 'e': | ||
3291 | case 'f': | ||
3292 | ++c; | ||
3293 | break; | ||
3294 | default: | ||
3295 | rv = false; | ||
3296 | break; | ||
3297 | } | ||
3298 | } | ||
3299 | return rv; | ||
3300 | } | ||
3301 | |||
3115 | void show_first_run_dialog() | 3302 | void show_first_run_dialog() |
3116 | { | 3303 | { |
3117 | LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback); | 3304 | LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback); |
@@ -3697,7 +3884,7 @@ void init_start_screen(S32 location_id) | |||
3697 | 3884 | ||
3698 | LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL; | 3885 | LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL; |
3699 | 3886 | ||
3700 | std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); | 3887 | std::string temp_str = gDirUtilp->getViewerUserDir() + gDirUtilp->getDirDelimiter(); |
3701 | 3888 | ||
3702 | if ((S32)START_LOCATION_ID_LAST == location_id) | 3889 | if ((S32)START_LOCATION_ID_LAST == location_id) |
3703 | { | 3890 | { |