// Message retrieved from Payload bool OTPayload::GetMessage(OTMessage & theMessage) const { // validate checksum uint32_t lSize = GetSize(); uint32_t lIndex = lSize-2; // the index to where the NULL terminator SHOULD be if they // sent us a string like they were supposed to. (A contract.) // (nSize-1 would be the location of the checksum at the end.) if (0 == lSize) return false; if (IsChecksumValid((OT_BYTE*)GetPointer(), (uint32_t)lSize)) { // We add the null-terminator ourselves at this point, for security reasons, // since we will process the data, after this point, as a string. ((OT_BYTE *)GetPointer())[lIndex] = 0; theMessage.Release(); // Why is this safe, where I cast the Payload data pointer as // a char * and tell the string to set itself from that? // Because (1) I just validated the checksum, and // (2) There place where the NULL should be, I set to 0, by hand, // just above 2 lines. So when this set operation occurs, the // farthest it will go is to that 0. theMessage.m_strRawFile.Set((const char *)GetPointer()); return true; } else { OTLog::Error("Invalid Checksum in OTPayload::GetMessage\n"); return false; } }
// Envelope retrieved from payload. bool OTPayload::GetEnvelope(OTEnvelope & theEnvelope) const { // validate checksum uint32_t lSize = GetSize(); uint32_t lIndex = lSize-2; // the index to where the NULL terminator SHOULD be if they // sent us a base64-encoded string, containing an encrypted message. (which we expect...) // (lSize-1 would be the location of the checksum at the end.) if (0 == lSize) return false; if (IsChecksumValid((OT_BYTE*)GetPointer(), (uint32_t)lSize)) { // We add the null-terminator ourselves at this point, for security reasons, // since we will process the data, soon after this function, as a string. ((OT_BYTE *)GetPointer())[lIndex] = 0; theEnvelope.m_dataContents.Release(); OTASCIIArmor theArmor; // Why is this safe, where I cast the Payload data pointer as // a char * and tell the data object to set itself from that? // Because (1) I just validated the checksum, and // (2) There place where the NULL should be, I set to 0, by hand, // just above 2 lines. So when this set operation occurs, the // farthest it will go is to that 0. theArmor.Set((const char *)GetPointer()); // Todo NOTE: If I ever want to process bookends here instead of assuming they aren't there, // IT'S VERY EASY!! All I have to do is call theArmor.LoadFromString instead of theArmor.Set. // Now the ascii-armored string that was sent across is decoded back to binary into the // Envelope object. theEnvelope.SetAsciiArmoredData(theArmor); return true; } else { OTLog::Error("Invalid Checksum in OTPayload::GetEnvelope\n"); return false; } }
// If a valid header is received, this function gets called. // The job of this function is to creae the message, read it, and add it to m_listIn. // ...and also, if there are unexpected bytes, to flush them in anticipation of the // next valid message. void OTClientConnection::ProcessMessage(u_header & theCMD) { bool bSuccess = false; OTMessage * pMsg = NULL; if ( theCMD.fields.type_id == CMD_TYPE_1 ) { OTLog::Output(2, "Received a Type 1 Command...\n"); if( IsChecksumValid( theCMD.buf, OT_CMD_HEADER_SIZE ) ) { OTLog::Output(2, "Checksum is valid! Processing payload.\n"); pMsg = new OTMessage; if (ProcessType1Cmd(theCMD, *pMsg )) { AddToInputList(*pMsg); bSuccess = true; } else { delete pMsg; pMsg = NULL; } } else { //gDebugLog.Write("Invalid checksum - Type 1 Command"); OTLog::vError("Invalid checksum - Type 1 Command, header size: %d\n", OT_CMD_HEADER_SIZE); } } else { //gDebugLog.Write("Unknown command type"); int nCommandType = theCMD.fields.type_id; OTLog::vError("Unknown command type: %d\n", nCommandType); } // I added this for error correction. In the event that there are errors, // just clean out whatever is in the pipe and throw it away. // Should probably send an Error message back, as well. if (bSuccess == false) { int err = 0, nread = 0; // char buffer[1024]; int sizeJunkData = 1024; while (1) { // err = SFSocketRead(m_pSocket, buffer, sizeJunkData); if (err > 0) nread += err; #ifdef _WIN32 if (0 == err || SOCKET_ERROR == err) // 0 means disconnect. error means error. >0 means bytes read. #else if (err <= 0) #endif break; } OTLog::vError("Transmission error--%d bytes flushed.\n", nread); // we are buffering data from the pipe now, so if we flush the pipe, we // should flush the buffer too. m_Buffer.Release(); } else { // TODO still need to process the commands and send the replies somewhere... //if (bSuccess = theServer.ProcessUserCommand(theMessage, theReply)) //{ // OTLog::vOutput(4, "Successfully processed user command: %s\n", theMessage.m_strCommand.Get()); // ProcessReply(ssl, theReply); // } // else // { // OTLog::vError("Unable to process user command in XML, or missing payload, in ProcessMessage.\n"); // } } }