GPResult gpiPeerGetSig( GPConnection * connection, GPIPeer * peer ) { GPIOperation * operation; // Start a get info operation to get the sig. ///////////////////////////////////////////// CHECK_RESULT(gpiAddOperation(connection, GPI_GET_INFO, NULL, &operation, GP_NON_BLOCKING, NULL, NULL)); // Send the get info. ///////////////////// CHECK_RESULT(gpiSendGetInfo(connection, peer->profile, operation->id)); // Set the state. ///////////////// peer->state = GPI_PEER_GETTING_SIG; return GP_NO_ERROR; }
GPResult gpiProcessConnect( GPConnection * connection, GPIOperation * operation, const char * input ) { char buffer[512]; char check[33]; char uniquenick[GP_UNIQUENICK_LEN]; GPIConnectData * data; GPIConnection * iconnection = (GPIConnection*)*connection; GPICallback callback; GPIProfile * profile; char userBuffer[GP_NICK_LEN + GP_EMAIL_LEN]; char partnerBuffer[11]; char * user; // Check for an error. ////////////////////// if(gpiCheckForError(connection, input, GPIFalse)) { // Is this a deleted profile? ///////////////////////////// if((iconnection->errorCode == GP_LOGIN_PROFILE_DELETED) && iconnection->profileid) { // Remove this profile object. ////////////////////////////// gpiRemoveProfileByID(connection, iconnection->profileid); // If we have the profileid/userid cached, lose them. ///////////////////////////////////////////////////// iconnection->userid = 0; iconnection->profileid = 0; } // Check for creating an existing profile. ////////////////////////////////////////// else if(iconnection->errorCode == GP_NEWUSER_BAD_NICK) { // Store the pid. ///////////////// if(gpiValueForKey(input, "\\pid\\", buffer, sizeof(buffer))) iconnection->profileid = atoi(buffer); } // Call the callbacks. ////////////////////// CallbackFatalError(connection, GP_SERVER_ERROR, iconnection->errorCode, iconnection->errorString); } // Get a pointer to the data. ///////////////////////////// data = (GPIConnectData*)operation->data; switch(operation->state) { case GPI_CONNECTING: // This should be \lc\1. //////////////////////// if(strncmp(input, "\\lc\\1", 5) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the server challenge. //////////////////////////// if(!gpiValueForKey(input, "\\challenge\\", data->serverChallenge, sizeof(data->serverChallenge))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Check if this is a new user. /////////////////////////////// if(data->newuser) { // Send a new user message. /////////////////////////// CHECK_RESULT(gpiSendNewuser(connection, data)); // Update the operation's state. //////////////////////////////// operation->state = GPI_REQUESTING; } else { // Send a login message. //////////////////////// CHECK_RESULT(gpiSendLogin(connection, data)); // Update the operation's state. //////////////////////////////// operation->state = GPI_LOGIN; } break; case GPI_REQUESTING: // This should be \nur\. //////////////////////// if(strncmp(input, "\\nur\\", 5) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the userid. ////////////////// if(!gpiValueForKey(input, "\\userid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->userid = atoi(buffer); // Get the profileid. ///////////////////// if(!gpiValueForKey(input, "\\profileid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->profileid = atoi(buffer); // Send a login request. //////////////////////// CHECK_RESULT(gpiSendLogin(connection, data)); // Update the operation's state. //////////////////////////////// operation->state = GPI_LOGIN; break; case GPI_LOGIN: // This should be \lc\2. //////////////////////// if(strncmp(input, "\\lc\\2", 5) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexpected data was received from the server."); // Get the sesskey. /////////////////// if(!gpiValueForKey(input, "\\sesskey\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->sessKey = atoi(buffer); // Get the userid. ////////////////// if(!gpiValueForKey(input, "\\userid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->userid = atoi(buffer); // Get the profileid. ///////////////////// if(!gpiValueForKey(input, "\\profileid\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); iconnection->profileid = atoi(buffer); // Get the uniquenick. ////////////////////// if(!gpiValueForKey(input, "\\uniquenick\\", uniquenick, sizeof(uniquenick))) uniquenick[0] = '\0'; // Get the loginticket. ////////////////////// if(!gpiValueForKey(input, "\\lt\\", iconnection->loginTicket, sizeof(iconnection->loginTicket))) iconnection->loginTicket[0] = '\0'; // Construct the user. ////////////////////// if(iconnection->partnerID != GP_PARTNERID_GAMESPY) { sprintf(partnerBuffer, "%d@", iconnection->partnerID); } else { // GS ID's do not stash the partner ID in the auth challenge to support legacy clients. strcpy(partnerBuffer, ""); } if(data->authtoken[0]) user = data->authtoken; else if(iconnection->uniquenick[0]) { sprintf(userBuffer, "%s%s", partnerBuffer, iconnection->uniquenick); user = userBuffer; } else { sprintf(userBuffer, "%s%s@%s", partnerBuffer, iconnection->nick, iconnection->email); user = userBuffer; } // Construct the check. /////////////////////// sprintf(buffer, "%s%s%s%s%s%s", data->passwordHash, " ", user, data->serverChallenge, data->userChallenge, data->passwordHash); MD5Digest((unsigned char *)buffer, strlen(buffer), check); // Get the proof. ///////////////// if(!gpiValueForKey(input, "\\proof\\", buffer, sizeof(buffer))) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_PARSE, "Unexepected data was received from the server."); // Check the server authentication. /////////////////////////////////// if(memcmp(check, buffer, 32) != 0) CallbackFatalError(connection, GP_NETWORK_ERROR, GP_LOGIN_SERVER_AUTH_FAILED, "Could not authenticate server."); // Add the local profile to the list. ///////////////////////////////////// if(iconnection->infoCaching) { profile = gpiProfileListAdd(connection, iconnection->profileid); profile->profileId = iconnection->profileid; profile->userId = iconnection->userid; } // Set the connect state. ///////////////////////// iconnection->connectState = GPI_CONNECTED; // Call the connect-response callback. ////////////////////////////////////// callback = operation->callback; if(callback.callback != NULL) { GPConnectResponseArg * arg; arg = (GPConnectResponseArg *)gsimalloc(sizeof(GPConnectResponseArg)); if(arg == NULL) Error(connection, GP_MEMORY_ERROR, "Out of memory."); memset(arg, 0, sizeof(GPConnectResponseArg)); arg->profile = (GPProfile)iconnection->profileid; arg->result = GP_NO_ERROR; #ifndef GSI_UNICODE strzcpy(arg->uniquenick, uniquenick, GP_UNIQUENICK_LEN); #else UTF8ToUCS2StringLen(uniquenick, arg->uniquenick, GP_UNIQUENICK_LEN); #endif CHECK_RESULT(gpiAddCallback(connection, callback, arg, operation, 0)); } // This operation is complete. ////////////////////////////// gpiRemoveOperation(connection, operation); // Get the local profile's info. //////////////////////////////// #if 0 gpiAddOperation(connection, GPI_GET_INFO, NULL, &operation, GP_NON_BLOCKING, NULL, NULL); gpiSendGetInfo(connection, iconnection->profileid, operation->id); #endif #ifdef _PS3 // We just connected, so setup buddy sync && start NP init // For future, we can limit syncs by setting flags to turn on/off here ////////////////////////////////////////////////////////////////////// iconnection->npPerformBuddySync = gsi_true; iconnection->npPerformBlockSync = gsi_true; iconnection->loginTime = current_time(); if (!iconnection->npInitialized) gpiInitializeNpBasic(connection); #endif break; default: break; } return GP_NO_ERROR; }