PluginReceiveResult TwoWayAuthentication::OnHashedNonceAndPassword(Packet *packet) { RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); char remoteHashedNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; unsigned short requestId; bsIn.Read(requestId); RakNet::RakString passwordIdentifier; bsIn.Read(passwordIdentifier); bsIn.ReadAlignedBytes((unsigned char *) remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); // Look up used nonce from requestId char usedNonce[TWO_WAY_AUTHENTICATION_NONCE_LENGTH]; if (nonceGenerator.GetNonceById(usedNonce, requestId, packet, true)==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; DataStructures::HashIndex skhi = passwords.GetIndexOf(passwordIdentifier.C_String()); if (skhi.IsInvalid()==false) { char hashedThisNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; Hash(usedNonce, passwords.ItemAtIndex(skhi), hashedThisNonceAndPw); if (memcmp(hashedThisNonceAndPw, remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH)==0) { // Pass RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS); bsOut.WriteAlignedBytes((const unsigned char*) usedNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); bsOut.WriteAlignedBytes((const unsigned char*) remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); bsOut.Write(passwordIdentifier); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); // Incoming success, modify packet header to tell user PushToUser(ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS, passwordIdentifier, packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } // Incoming failure, modify arrived packet header to tell user packet->data[0]=(MessageID) ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE; RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE); bsOut.WriteAlignedBytes((const unsigned char*) usedNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); bsOut.WriteAlignedBytes((const unsigned char*) remoteHashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); bsOut.Write(passwordIdentifier); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); return RR_CONTINUE_PROCESSING; }
void RPC3::SendError(SystemAddress target, unsigned char errorCode, const char *functionName) { RakNet::BitStream bs; bs.Write((MessageID)ID_RPC_REMOTE_ERROR); bs.Write(errorCode); bs.WriteAlignedBytes((const unsigned char*) functionName,(const unsigned int) strlen(functionName)+1); SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false); }
void CloudClient::Post(CloudKey *cloudKey, const unsigned char *data, uint32_t dataLengthBytes, RakNetGUID systemIdentifier) { RakAssert(cloudKey); RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_CLOUD_POST_REQUEST); cloudKey->Serialize(true,&bsOut); if (data==0) dataLengthBytes=0; bsOut.Write(dataLengthBytes); if (dataLengthBytes>0) bsOut.WriteAlignedBytes((const unsigned char*) data, dataLengthBytes); SendUnified(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemIdentifier, false); }
void TwoWayAuthentication::OnNonceRequest(Packet *packet) { RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); char nonce[TWO_WAY_AUTHENTICATION_NONCE_LENGTH]; unsigned short requestId; nonceGenerator.GetNonce(nonce,&requestId,packet); RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_NEGOTIATION); bsOut.Write((MessageID)ID_NONCE_REPLY); bsOut.Write(requestId); bsOut.WriteAlignedBytes((const unsigned char*) nonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); }
void TwoWayAuthentication::OnNonceReply(Packet *packet) { RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)*2); char thierNonce[TWO_WAY_AUTHENTICATION_NONCE_LENGTH]; unsigned short requestId; bsIn.Read(requestId); bsIn.ReadAlignedBytes((unsigned char *) thierNonce,TWO_WAY_AUTHENTICATION_NONCE_LENGTH); // Lookup one of the negotiations for this guid/system address AddressOrGUID aog(packet); unsigned int i; for (i=0; i < outgoingChallenges.Size(); i++) { if (outgoingChallenges[i].remoteSystem==aog && outgoingChallenges[i].sentHash==false) { outgoingChallenges[i].sentHash=true; // Get the password for this identifier DataStructures::HashIndex skhi = passwords.GetIndexOf(outgoingChallenges[i].identifier.C_String()); if (skhi.IsInvalid()==false) { RakNet::RakString password = passwords.ItemAtIndex(skhi); // Hash their nonce with password and reply char hashedNonceAndPw[HASHED_NONCE_AND_PW_LENGTH]; Hash(thierNonce, password, hashedNonceAndPw); // Send RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_TWO_WAY_AUTHENTICATION_NEGOTIATION); bsOut.Write((MessageID)ID_HASHED_NONCE_AND_PASSWORD); bsOut.Write(requestId); bsOut.Write(outgoingChallenges[i].identifier); // Identifier helps the other system lookup the password quickly. bsOut.WriteAlignedBytes((const unsigned char*) hashedNonceAndPw,HASHED_NONCE_AND_PW_LENGTH); SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet,false); } return; } } }
bool RPC3::SendCallOrSignal(RakString uniqueIdentifier, char parameterCount, RakNet::BitStream *serializedParameters, bool isCall) { SystemAddress systemAddr; // unsigned int outerIndex; // unsigned int innerIndex; if (uniqueIdentifier.IsEmpty()) return false; RakNet::BitStream bs; if (outgoingTimestamp!=0) { bs.Write((MessageID)ID_TIMESTAMP); bs.Write(outgoingTimestamp); } bs.Write((MessageID)ID_AUTO_RPC_CALL); bs.Write(parameterCount); if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID && isCall) { bs.Write(true); bs.Write(outgoingNetworkID); } else { bs.Write(false); } bs.Write(isCall); // This is so the call SetWriteOffset works bs.AlignWriteToByteBoundary(); BitSize_t writeOffset = bs.GetWriteOffset(); if (outgoingBroadcast) { unsigned systemIndex; for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++) { systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex); if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress) { // if (GetRemoteFunctionIndex(systemAddr, uniqueIdentifier, &outerIndex, &innerIndex, isCall)) // { // // Write a number to identify the function if possible, for faster lookup and less bandwidth // bs.Write(true); // if (isCall) // bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); // else // bs.WriteCompressed(remoteSlots[outerIndex]->operator [](innerIndex).functionIndex); // } // else // { // bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); // } bs.WriteCompressed(serializedParameters->GetNumberOfBitsUsed()); bs.WriteAlignedBytes((const unsigned char*) serializedParameters->GetData(), serializedParameters->GetNumberOfBytesUsed()); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); // Start writing again after ID_AUTO_RPC_CALL bs.SetWriteOffset(writeOffset); } } } else { systemAddr = outgoingSystemAddress; if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS) { // if (GetRemoteFunctionIndex(systemAddr, uniqueIdentifier, &outerIndex, &innerIndex, isCall)) // { // // Write a number to identify the function if possible, for faster lookup and less bandwidth // bs.Write(true); // if (isCall) // bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); // else // bs.WriteCompressed(remoteSlots[outerIndex]->operator [](innerIndex).functionIndex); // } // else // { // bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); // } bs.WriteCompressed(serializedParameters->GetNumberOfBitsUsed()); bs.WriteAlignedBytes((const unsigned char*) serializedParameters->GetData(), serializedParameters->GetNumberOfBytesUsed()); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); } else return false; } return true; }
void AutoRPC::OnRPCUnknownRemoteIndex(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes, RakNetTime timestamp) { char inputStack[ARPC_MAX_STACK_SIZE]; NetworkID networkId; bool hasNetworkId=false; unsigned int functionIndex; unsigned int bytesOnStack; int numberOfBitsUsed; char parameterCount; bool hasParameterCount=false; RakNet::BitStream extraData; RakNet::BitStream bs(data,lengthInBytes,false); bs.Read(hasParameterCount); if (hasParameterCount) bs.Read(parameterCount); bs.ReadCompressed(functionIndex); bs.ReadCompressed(numberOfBitsUsed); extraData.AddBitsAndReallocate(numberOfBitsUsed); bs.ReadBits(extraData.GetData(), numberOfBitsUsed, false); extraData.SetWriteOffset(numberOfBitsUsed); bs.Read(hasNetworkId); if (hasNetworkId) bs.Read(networkId); bs.ReadCompressed(bytesOnStack); bs.ReadAlignedBytes((unsigned char*) inputStack, bytesOnStack); unsigned outerIndex; if (remoteFunctions.Has(systemAddress)) { outerIndex = remoteFunctions.GetIndexAtKey(systemAddress); DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[outerIndex]; unsigned i; for (i=0; i < theList->Size(); i++) { if (theList->operator [](i).functionIndex==functionIndex) { RakNet::BitStream out; // Recover by resending the RPC with the function identifier string this time if (timestamp!=0) { out.Write((MessageID)ID_TIMESTAMP); out.Write(timestamp); } out.Write((MessageID)ID_AUTO_RPC_CALL); if (parameterCount>=0) { out.Write(true); out.Write(parameterCount); } else { out.Write(false); } out.WriteCompressed(numberOfBitsUsed); out.Write(&extraData); out.Write(hasNetworkId); if (hasNetworkId) out.Write(networkId); out.AlignWriteToByteBoundary(); out.Write(false); stringCompressor->EncodeString(theList->operator [](i).identifier.uniqueIdentifier, 512, &out, 0); out.WriteCompressed(bytesOnStack); out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack); SendUnified(&out, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddress, false); return; } } } // Failed to recover, inform the user Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)); RakNet::BitStream bs2(p->data, sizeof(MessageID)+sizeof(unsigned char), false); bs2.SetWriteOffset(0); bs2.Write((MessageID)ID_RPC_REMOTE_ERROR); bs2.Write((unsigned char)RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED); stringCompressor->EncodeString("",256,&bs,0); p->systemAddress=systemAddress; rakPeerInterface->PushBackPacket(p, false); }
bool AutoRPC::SendCall(const char *uniqueIdentifier, const char *stack, unsigned int bytesOnStack, char parameterCount) { SystemAddress systemAddr; RPCIdentifier identifier; unsigned int outerIndex; unsigned int innerIndex; if (uniqueIdentifier==0) return false; identifier.uniqueIdentifier=(char*) uniqueIdentifier; identifier.isObjectMember=(outgoingNetworkID!=UNASSIGNED_NETWORK_ID); RakNet::BitStream bs; if (outgoingTimestamp!=0) { bs.Write((MessageID)ID_TIMESTAMP); bs.Write(outgoingTimestamp); } bs.Write((MessageID)ID_AUTO_RPC_CALL); if (parameterCount>=0) { bs.Write(true); bs.Write(parameterCount); } else { bs.Write(false); } bs.WriteCompressed(outgoingExtraData.GetNumberOfBitsUsed()); bs.Write(&outgoingExtraData); if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID) { bs.Write(true); bs.Write(outgoingNetworkID); } else { bs.Write(false); } // This is so the call SetWriteOffset works bs.AlignWriteToByteBoundary(); BitSize_t writeOffset = bs.GetWriteOffset(); SystemAddress outgoingSystemAddress; if (outgoingSystemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID) outgoingSystemAddress = rakPeerInterface->GetSystemAddressFromGuid(outgoingSystemIdentifier.rakNetGuid); else outgoingSystemAddress = outgoingSystemIdentifier.systemAddress; if (outgoingBroadcast) { unsigned systemIndex; for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++) { systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex); if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress) { if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex)) { // Write a number to identify the function if possible, for faster lookup and less bandwidth bs.Write(true); bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); } else { bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); } bs.WriteCompressed(bytesOnStack); bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); // Start writing again after ID_AUTO_RPC_CALL bs.SetWriteOffset(writeOffset); } } } else { systemAddr = outgoingSystemAddress; if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS) { if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex)) { // Write a number to identify the function if possible, for faster lookup and less bandwidth bs.Write(true); bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex); } else { bs.Write(false); stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0); } bs.WriteCompressed(bytesOnStack); bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack); SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false); } else return false; } return true; }