GPResult gpiPeerAddMessage( GPConnection * connection, GPIPeer * peer, int type, const char * message ) { GPIMessage gpiMessage; int len; GS_ASSERT(peer != NULL); GS_ASSERT(message != NULL); if (peer == NULL) return GP_NETWORK_ERROR; if (message == NULL) return GP_NETWORK_ERROR; // Get the length. ////////////////// len = (int)strlen(message); // Clear the message. ///////////////////// memset(&gpiMessage, 0, sizeof(GPIMessage)); // Copy the type. ///////////////// gpiMessage.type = type; // Copy the header to the buffer. ///////////////////////////////// CHECK_RESULT(gpiAppendStringToBuffer(connection, &gpiMessage.buffer, "\\m\\")); CHECK_RESULT(gpiAppendIntToBuffer(connection, &gpiMessage.buffer, type)); CHECK_RESULT(gpiAppendStringToBuffer(connection, &gpiMessage.buffer, "\\len\\")); CHECK_RESULT(gpiAppendIntToBuffer(connection, &gpiMessage.buffer, len)); CHECK_RESULT(gpiAppendStringToBuffer(connection, &gpiMessage.buffer, "\\msg\\\n")); // Copy the message to the buffer. ////////////////////////////////// gpiMessage.start = gpiMessage.buffer.len; CHECK_RESULT(gpiAppendStringToBufferLen(connection, &gpiMessage.buffer, message, len)); CHECK_RESULT(gpiAppendCharToBuffer(connection, &gpiMessage.buffer, '\0')); // Add it to the list. ////////////////////// ArrayAppend(peer->messages, &gpiMessage); // Reset the timeout. ///////////////////// peer->timeout = (time(NULL) + GPI_PEER_TIMEOUT); return GP_NO_ERROR; }
GPResult gpiAppendUShortToBuffer( GPConnection * connection, GPIBuffer * outputBuffer, unsigned short num) { char shortVal[8]; sprintf(shortVal, "%u", num); return gpiAppendStringToBuffer(connection, outputBuffer, shortVal); }
GPResult gpiAppendUIntToBuffer( GPConnection * connection, GPIBuffer * outputBuffer, unsigned int num ) { char intValue[16]; sprintf(intValue,"%u",num); return gpiAppendStringToBuffer(connection, outputBuffer, intValue); }
GPResult gpiSendServerBuddyMessage( GPConnection * connection, int profileid, int type, const char * message ) { char buffer[3501]; GPIConnection * iconnection = (GPIConnection*)*connection; // Copy the message into an internal buffer. //////////////////////////////////////////// strzcpy(buffer, message, sizeof(buffer)); // Setup the message. ///////////////////// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\bm\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, type); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sesskey\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\t\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, profileid); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\msg\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, buffer); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); return GP_NO_ERROR; }
//FUNCTIONS /////////// static GPResult gpiSendAuthBuddyRequest( GPConnection * connection, GPIProfile * profile ) { GPIConnection * iconnection = (GPIConnection*)*connection; // Send the auth. ///////////////// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\authadd\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sesskey\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\fromprofileid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, profile->profileId); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sig\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, profile->authSig); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); return GP_NO_ERROR; }
void gpiDisconnect( GPConnection * connection, GPIBool tellServer ) { GPIConnection * iconnection = (GPIConnection*)*connection; GPIPeer * peer; GPIPeer * delPeer; GPIBool connClosed; // Check if we're already disconnected. // PANTS|05.15.00 /////////////////////////////////////// if(iconnection->connectState == GPI_DISCONNECTED) return; // Skip most of this stuff if we never actually connected. // PANTS|05.16.00 ////////////////////////////////////////////////////////// if(iconnection->connectState != GPI_NOT_CONNECTED) { // Are we connected? //////////////////// if(tellServer && (iconnection->connectState == GPI_CONNECTED)) { // Send the disconnect. /////////////////////// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\logout\\\\sesskey\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); } // Always flush remaining messages. // PANTS|05.16.00 /////////////////////////////////// gpiSendFromBuffer(connection, iconnection->cmSocket, &iconnection->outputBuffer, &connClosed, GPITrue, "CM"); // Cleanup the connection. ////////////////////////// if(iconnection->cmSocket != INVALID_SOCKET) { shutdown(iconnection->cmSocket, 2); closesocket(iconnection->cmSocket); iconnection->cmSocket = INVALID_SOCKET; } if(/*iconnection->peerSocket != INVALID_SOCKET*/ gsUdpEngineIsInitialized()) { //shutdown(iconnection->peerSocket, 2); //closesocket(iconnection->peerSocket); //iconnection->peerSocket = INVALID_SOCKET; gsUdpEngineRemoveMsgHandler(iconnection->mHeader); if (gsUdpEngineNoMoreMsgHandlers() && gsUdpEngineNoApp()) gsUdpEngineShutdown(); } // We're disconnected. ////////////////////// iconnection->connectState = GPI_DISCONNECTED; // Don't keep the userid/profileid. /////////////////////////////////// iconnection->userid = 0; iconnection->profileid = 0; } // freeclear all the memory. /////////////////////// freeclear(iconnection->socketBuffer.buffer); freeclear(iconnection->inputBuffer); freeclear(iconnection->outputBuffer.buffer); freeclear(iconnection->updateproBuffer.buffer); freeclear(iconnection->updateuiBuffer.buffer); while(iconnection->operationList != NULL) gpiRemoveOperation(connection, iconnection->operationList); iconnection->operationList = NULL; for(peer = iconnection->peerList ; peer != NULL ; ) { delPeer = peer; peer = peer->pnext; gpiDestroyPeer(connection, delPeer); } iconnection->peerList = NULL; // Cleanup buddies. // This is not optimal - because we can't continue the mapping // after freeing a profile, we need to start it all over again. /////////////////////////////////////////////////////////////// while(!gpiProfileMap(connection, gpiDisconnectCleanupProfile, NULL)) { }; }
static GPResult gpiSendNewuser( GPConnection * connection, GPIConnectData * data ) { GPIConnection * iconnection = (GPIConnection*)*connection; size_t i; const int useAlternateEncoding = 1; // Encrypt the password (xor with random values) char passwordenc[GP_PASSWORDENC_LEN]; gpiEncodeString(iconnection->password, passwordenc); // Construct the outgoing message. ////////////////////////////////// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\newuser\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\email\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, iconnection->email); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\nick\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, iconnection->nick); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\passwordenc\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, passwordenc); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\productid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->productID); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\gamename\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, __GSIACGamename); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\namespaceid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->namespaceID); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\uniquenick\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, iconnection->uniquenick); if(data->cdkey[0]) { // Encrypt the cdkey (xor with random values) char cdkeyxor[GP_CDKEY_LEN]; char cdkeyenc[GP_CDKEYENC_LEN]; size_t cdkeylen = strlen(data->cdkey); Util_RandSeed((unsigned long)GP_XOR_SEED); for (i=0; i < cdkeylen; i++) { // XOR each character with the next rand char aRand = (char)Util_RandInt(0, 0xFF); cdkeyxor[i] = (char)(data->cdkey[i] ^ aRand); } cdkeyxor[i] = '\0'; // Base 64 it (printable chars only) B64Encode(cdkeyxor, cdkeyenc, (int)cdkeylen, useAlternateEncoding); //gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\cdkey\\"); //gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, data->cdkey); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\cdkeyenc\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, cdkeyenc); } gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\partnerid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->partnerID); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\id\\1"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); return GP_NO_ERROR; }
static GPResult gpiSendLogin( GPConnection * connection, GPIConnectData * data ) { char buffer[512]; char response[33]; GPIConnection * iconnection = (GPIConnection*)*connection; GPIProfile * profile; char * passphrase; char userBuffer[GP_NICK_LEN + GP_EMAIL_LEN]; char partnerBuffer[11]; char * user; // Construct the user challenge. //////////////////////////////// randomString(data->userChallenge, sizeof(data->userChallenge) - 1); // Hash the password. ///////////////////// if(data->partnerchallenge[0]) passphrase = data->partnerchallenge; else passphrase = iconnection->password; MD5Digest((unsigned char*)passphrase, strlen(passphrase), data->passwordHash); // 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 response. ////////////////////////// sprintf(buffer, "%s%s%s%s%s%s", data->passwordHash, " ", user, data->userChallenge, data->serverChallenge, data->passwordHash); MD5Digest((unsigned char *)buffer, strlen(buffer), response); // Check for an existing profile. ///////////////////////////////// if(iconnection->infoCaching) { gpiFindProfileByUser(connection, iconnection->nick, iconnection->email, &profile); if(profile != NULL) { // Get the userid and profileid. //////////////////////////////// iconnection->userid = profile->userId; iconnection->profileid = profile->profileId; } } // Construct the outgoing message. ////////////////////////////////// gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\login\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\challenge\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, data->userChallenge); if(data->authtoken[0]) { gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\authtoken\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, data->authtoken); } else if(iconnection->uniquenick[0]) { gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\uniquenick\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, iconnection->uniquenick); } else { gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\user\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, iconnection->nick); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "@"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, iconnection->email); } if(iconnection->userid != 0) { gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\userid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->userid); } if(iconnection->profileid != 0) { gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\profileid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->profileid); } gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\partnerid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->partnerID); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\response\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, response); if(iconnection->firewall == GP_FIREWALL) gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\firewall\\1"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\port\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->peerPort); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\productid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->productID); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\gamename\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, __GSIACGamename); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\namespaceid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->namespaceID); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sdkrevision\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, GPI_SDKREV); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\quiet\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->quietModeFlags); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\id\\1"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); return GP_NO_ERROR; }
GPResult gpiDeleteBuddy( GPConnection * connection, GPProfile profile, GPIBool sendServerRequest ) { GPIProfile * pProfile; GPIConnection * iconnection = (GPIConnection*)*connection; int index; // Get the profile object. ////////////////////////// if(!gpiGetProfile(connection, profile, &pProfile)) Error(connection, GP_PARAMETER_ERROR, "Invalid profile."); // Check that this is a buddy. ////////////////////////////// // Removed - 092404 BED - User could be a buddy even though we don't have the status //if(!pProfile->buddyStatus) // Error(connection, GP_PARAMETER_ERROR, "Profile not a buddy."); // Send the request. //////////////////// if (GPITrue == sendServerRequest) { gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\delbuddy\\"); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\sesskey\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, iconnection->sessKey); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\delprofileid\\"); gpiAppendIntToBuffer(connection, &iconnection->outputBuffer, pProfile->profileId); gpiAppendStringToBuffer(connection, &iconnection->outputBuffer, "\\final\\"); } // Need to fix up the buddy indexes. //////////////////////////////////// if (pProfile->buddyStatus) { index = pProfile->buddyStatus->buddyIndex; assert(index >= 0); freeclear(pProfile->buddyStatus->statusString); freeclear(pProfile->buddyStatus->locationString); freeclear(pProfile->buddyStatus); if(gpiCanFreeProfile(pProfile)) gpiRemoveProfile(connection, pProfile); iconnection->profileList.numBuddies--; assert(iconnection->profileList.numBuddies >= 0); #ifndef _PS2 gpiProfileMap(connection, gpiFixBuddyIndices, (void *)(unsigned long)index); #else gpiProfileMap(connection, gpiFixBuddyIndices, (void *)index); #endif } if (pProfile->buddyStatusInfo) { index = pProfile->buddyStatusInfo->buddyIndex; assert(index >= 0); freeclear(pProfile->buddyStatusInfo->richStatus); freeclear(pProfile->buddyStatusInfo->gameType); freeclear(pProfile->buddyStatusInfo->gameVariant); freeclear(pProfile->buddyStatusInfo->gameMapName); freeclear(pProfile->buddyStatusInfo); if (pProfile->buddyStatusInfo->extendedInfoKeys) { ArrayFree(pProfile->buddyStatusInfo->extendedInfoKeys); pProfile->buddyStatusInfo->extendedInfoKeys = NULL; } if(gpiCanFreeProfile(pProfile)) gpiRemoveProfile(connection, pProfile); iconnection->profileList.numBuddies--; assert(iconnection->profileList.numBuddies >= 0); #ifndef _PS2 gpiProfileMap(connection, gpiFixBuddyIndices, (void *)(unsigned long)index); #else gpiProfileMap(connection, gpiFixBuddyIndices, (void *)index); #endif } return GP_NO_ERROR; }
//FUNCTIONS /////////// static GPResult gpiProcessPeerInitiatingConnection( GPConnection * connection, GPIPeer * peer ) { GPIConnection * iconnection = (GPIConnection*)*connection; //int state; char * str = NULL; //int len; GPIBool connClosed; GPIProfile * pProfile; GPResult result; GSUdpPeerState aPeerState; GS_ASSERT(peer); if (!peer) return GP_NETWORK_ERROR; GS_ASSERT(peer->state != GPI_PEER_DISCONNECTED && peer->state != GPI_PEER_NOT_CONNECTED); if (peer->state == GPI_PEER_DISCONNECTED || peer->state == GPI_PEER_NOT_CONNECTED) return GP_NETWORK_ERROR; // Check the state. /////////////////// switch(peer->state) { case GPI_PEER_GETTING_SIG: // Do nothing - we're waiting for getinfo to get the sig. ///////////////////////////////////////////////////////// break; case GPI_PEER_GOT_SIG: { // Start the connect. ///////////////////// gsDebugFormat(GSIDebugCat_GP, GSIDebugType_State, GSIDebugLevel_Verbose, "Got the peer signature for profileid: %d\n", peer->profile); CHECK_RESULT(gpiPeerStartConnect(connection, peer)); break; } case GPI_PEER_CONNECTING: { // Check if the connect finished. ///////////////////////////////// /* CHECK_RESULT(gpiCheckSocketConnect(connection, peer->sock, &state)); if(state == GPI_DISCONNECTED) { Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer."); } */ gsUdpEngineGetPeerState(peer->ip, peer->port, &aPeerState); if(aPeerState == GS_UDP_PEER_CONNECTED) { GPIPeer * pcurr; GPIBool freePeerSig = GPITrue; // Get the profile object. ////////////////////////// if(!gpiGetProfile(connection, peer->profile, &pProfile)) Error(connection, GP_NETWORK_ERROR, "Error connecting to a peer."); // Send the auth. ///////////////// gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\auth\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\pid\\"); gpiAppendIntToBuffer(connection, &peer->outputBuffer, iconnection->profileid); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\nick\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, iconnection->nick); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\sig\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, pProfile->peerSig); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\"); // Are there any other peers still connecting? ////////////////////////////////////////////// for(pcurr = iconnection->peerList ; pcurr != NULL ; pcurr = pcurr->pnext) if((pcurr->profile == peer->profile) && (pcurr != peer)) if(pcurr->state <= GPI_PEER_CONNECTING) freePeerSig = GPIFalse; // freeclear it? /////////// if(freePeerSig) { freeclear(pProfile->peerSig); if(gpiCanFreeProfile(pProfile)) gpiRemoveProfile(connection, pProfile); } // Update the state. //////////////////// peer->state = GPI_PEER_WAITING; } break; } case GPI_PEER_WAITING: { // Check for a response. //////////////////////// //CHECK_RESULT(gpiRecvToBuffer(connection, peer->sock, &peer->inputBuffer, &len, &connClosed, "PR")); // Check for a final. ///////////////////// if (peer->inputBuffer.buffer) str = strstr(peer->inputBuffer.buffer, "\\final\\"); if(str != NULL) { str[0] = '\0'; str += 7; // Was it rejected? /////////////////// if(strncmp(peer->inputBuffer.buffer, "\\anack\\", 7) == 0) { // Rejected. //////////// peer->nackCount++; // Is this more than once? ////////////////////////// if(peer->nackCount > 1) { // we shouldn't reach this case unless there is a problem with // the server when getting a buddy's signature // Give up already. /////////////////// Error(connection, GP_NETWORK_ERROR, "Error getting buddy authorization."); } // Try getting the latest sig. ////////////////////////////// CHECK_RESULT(gpiPeerGetSig(connection, peer)); } else if(strncmp(peer->inputBuffer.buffer, "\\aack\\", 6) != 0) { // Unknown message. /////////////////// Error(connection, GP_NETWORK_ERROR, "Error parsing buddy message."); } // The connection has been established. /////////////////////////////////////// peer->state = GPI_PEER_CONNECTED; peer->inputBuffer.len = 0; } break; } // code should not reach here. default: break; } // Send stuff that needs to be sent. //////////////////////////////////// if(peer->outputBuffer.len > 0) { //result = gpiSendFromBuffer(connection, peer->sock, &peer->outputBuffer, &connClosed, GPITrue, "PR"); result = gpiSendBufferToPeer(connection, peer->ip, peer->port, &peer->outputBuffer, &connClosed, GPITrue); if(connClosed || (result != GP_NO_ERROR)) peer->state = GPI_PEER_DISCONNECTED; } return GP_NO_ERROR; }
static GPResult gpiProcessPeerAcceptingConnection( GPConnection * connection, GPIPeer * peer ) { GPIConnection * iconnection = (GPIConnection*)*connection; GSUdpPeerState aPeerState; char * str; //int len; GPIBool connClosed; char intValue[16]; int pid; char nick[GP_NICK_LEN]; char sig[33]; char sigCheck[33]; char buffer[256]; // Check the state. /////////////////// GS_ASSERT(peer->state == GPI_PEER_WAITING); if (peer->state != GPI_PEER_WAITING) return GP_NETWORK_ERROR; // Read any pending info. ///////////////////////// //CHECK_RESULT(gpiRecvToBuffer(connection, peer->sock, &peer->inputBuffer, &len, &connClosed, "PR")); gsUdpEngineGetPeerState(peer->ip, peer->port, &aPeerState); // Check for a closed connection. ///////////////////////////////// if(aPeerState == GS_UDP_PEER_CLOSED) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Check for a final. ///////////////////// str = strstr(peer->inputBuffer.buffer, "\\final\\"); if(str != NULL) { str[0] = '\0'; str += 7; // Is it an auth? ///////////////// if(strncmp(peer->inputBuffer.buffer, "\\auth\\", 6) == 0) { // Get the pid. /////////////// if(!gpiValueForKey(peer->inputBuffer.buffer, "\\pid\\", intValue, sizeof(intValue))) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } pid = atoi(intValue); // Get the nick. //////////////// if(!gpiValueForKey(peer->inputBuffer.buffer, "\\nick\\", nick, sizeof(nick))) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Get the sig. /////////////// if(!gpiValueForKey(peer->inputBuffer.buffer, "\\sig\\", sig, sizeof(sig))) { peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Compute what the sig should be. ////////////////////////////////// sprintf(buffer, "%s%d%d", iconnection->password, iconnection->profileid, pid); MD5Digest((unsigned char *)buffer, strlen(buffer), sigCheck); // Check the sig. ///////////////// if(strcmp(sig, sigCheck) != 0) { // Bad sig. /////////// gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\anack\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\"); gpiSendBufferToPeer(connection, peer->ip, peer->port, &peer->outputBuffer, &connClosed, GPITrue); peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Send an ack. /////////////// gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\aack\\"); gpiAppendStringToBuffer(connection, &peer->outputBuffer, "\\final\\"); peer->state = GPI_PEER_CONNECTED; peer->profile = (GPProfile)pid; } else { // Unrecognized command. //////////////////////// peer->state = GPI_PEER_DISCONNECTED; return GP_NO_ERROR; } // Update the buffer length. //////////////////////////// peer->inputBuffer.len = 0; } return GP_NO_ERROR; }