HRESULT CTestMessageHandler::ValidateMappedAddress(CStunMessageReader& reader, const CSocketAddress& addrClient) { HRESULT hr = S_OK; StunTransactionId transid; CSocketAddress mappedaddr; CRefCountedBuffer spBuffer; Chk(reader.GetStream().GetBuffer(&spBuffer)); reader.GetTransactionId(&transid); //ChkA(reader.GetAttributeByType(STUN_ATTRIBUTE_XORMAPPEDADDRESS, &attrib)); //ChkA(GetXorMappedAddress(spBuffer->GetData()+attrib.offset, attrib.size, transid, &mappedaddr)); reader.GetXorMappedAddress(&mappedaddr); ChkIfA(false == addrClient.IsSameIP_and_Port(mappedaddr), E_FAIL); //ChkA(reader.GetAttributeByType(STUN_ATTRIBUTE_MAPPEDADDRESS, &attrib)); //ChkA(GetMappedAddress(spBuffer->GetData()+attrib.offset, attrib.size, &mappedaddr)); reader.GetMappedAddress(&mappedaddr); ChkIfA(false == addrClient.IsSameIP_and_Port(mappedaddr), E_FAIL); Cleanup: return hr; }
HRESULT CTestMessageHandler::ValidateMappedAddress(CStunMessageReader& reader, const CSocketAddress& addrExpected, bool fLegacyOnly) { HRESULT hr = S_OK; CSocketAddress addrMapped; CSocketAddress addrXorMapped; HRESULT hrResult; hrResult = reader.GetXorMappedAddress(&addrXorMapped); if (SUCCEEDED(hrResult)) { ChkIfA(false == addrExpected.IsSameIP_and_Port(addrXorMapped), E_FAIL); ChkIfA(fLegacyOnly, E_FAIL); // legacy responses should not include XOR mapped } else { ChkIfA(fLegacyOnly==false, E_FAIL); // non-legacy responses should include XOR Mapped address } ChkA(reader.GetMappedAddress(&addrMapped)); ChkIfA(false == addrExpected.IsSameIP_and_Port(addrMapped), E_FAIL); Cleanup: return hr; }
HRESULT CBasicBindingTest::ProcessResponse(CRefCountedBuffer& spMsg, CSocketAddress& addrRemote, CSocketAddress& addrLocal) { HRESULT hr = S_OK; CStunMessageReader reader; CSocketAddress addrMapped; CSocketAddress addrOther; bool fHasOtherAddress = false; // todo - figure out a way to make buffering TCP fragments work Chk(BasicReaderValidation(spMsg, reader)); hr = reader.GetXorMappedAddress(&addrMapped); if (FAILED(hr)) { hr = reader.GetMappedAddress(&addrMapped); } Chk(hr); // again drop the message if we can't parse the binding response fHasOtherAddress = SUCCEEDED(reader.GetOtherAddress(&addrOther)); // ok, we got a response. So we are done _fCompleted = true; _pResults->fBindingTestSuccess = true; _pResults->fIsDirect = addrLocal.IsSameIP_and_Port(addrMapped); _pResults->addrLocal = addrLocal; _pResults->addrMapped = addrMapped; _pResults->fHasOtherAddress = fHasOtherAddress; if (fHasOtherAddress) { _pResults->addrAA = addrOther; _pResults->addrPA = _pConfig->addrServer; _pResults->addrPA.SetPort(addrOther.GetPort()); _pResults->addrAP = addrOther; _pResults->addrAP.SetPort(_pConfig->addrServer.GetPort()); if (Logging::GetLogLevel() >= LL_DEBUG) { char sz[100]; addrOther.ToStringBuffer(sz, 100); Logging::LogMsg(LL_DEBUG, "Other address is %s\n",sz); } } Cleanup: return hr; }
// test long-credential authentication HRESULT CTestMessageHandler::Test4() { HRESULT hr=S_OK; CStunMessageBuilder builder1, builder2; CStunMessageReader readerResponse; CSocketAddress addrMapped; uint16_t errorcode = 0; char szNonce[MAX_STUN_AUTH_STRING_SIZE+1]; char szRealm[MAX_STUN_AUTH_STRING_SIZE+1]; // ----------------------------------------------------------------------- // simulate a user making a request with no message integrity attribute (or username, or realm) InitBindingRequest(builder1); builder1.FixLengthField(); ChkA(SendHelper(builder1, &readerResponse, _spAuthLong)); Chk(readerResponse.GetErrorCode(&errorcode)); ChkIfA(readerResponse.GetMessageClass() != ::StunMsgClassFailureResponse, E_UNEXPECTED); ChkIf(errorcode != ::STUN_ERROR_UNAUTHORIZED, E_UNEXPECTED); readerResponse.GetStringAttributeByType(STUN_ATTRIBUTE_REALM, szRealm, ARRAYSIZE(szRealm)); readerResponse.GetStringAttributeByType(STUN_ATTRIBUTE_NONCE, szNonce, ARRAYSIZE(szNonce)); // -------------------------------------------------------------------------------- // now simulate the follow-up request readerResponse.Reset(); InitBindingRequest(builder2); builder2.AddNonce(szNonce); builder2.AddRealm(szRealm); builder2.AddUserName("AuthorizedUser"); builder2.AddMessageIntegrityLongTerm("AuthorizedUser", szRealm, "password"); builder2.FixLengthField(); ChkA(SendHelper(builder2, &readerResponse, _spAuthLong)); ChkIfA(readerResponse.GetMessageClass() != ::StunMsgClassSuccessResponse, E_UNEXPECTED); // should have a mapped address ChkA(readerResponse.GetMappedAddress(&addrMapped)); // and the message integrity field should be valid ChkA(readerResponse.ValidateMessageIntegrityLong("AuthorizedUser", szRealm, "password")); Cleanup: return hr; }
HRESULT CBehaviorTest::ProcessResponse(CRefCountedBuffer& spMsg, CSocketAddress& addrRemote, CSocketAddress& addrLocal) { HRESULT hr = S_OK; CStunMessageReader reader; CSocketAddress addrMapped; Chk(BasicReaderValidation(spMsg, reader)); hr = reader.GetXorMappedAddress(&addrMapped); if (FAILED(hr)) { hr = reader.GetMappedAddress(&addrMapped); } Chk(hr); // again drop the message if we can't parse the binding response _fCompleted = true; if (_fIsTest3) { _pResults->addrMappingAA = addrMapped; _pResults->fBehaviorTestSuccess = true; if (addrMapped.IsSameIP_and_Port(_pResults->addrMappingAP)) { _pResults->behavior = ::AddressDependentMapping; } else { _pResults->behavior = ::AddressAndPortDependentMapping; } } else { _pResults->addrMappingAP = addrMapped; if (addrMapped.IsSameIP_and_Port(_pResults->addrMapped)) { _pResults->fBehaviorTestSuccess = true; _pResults->behavior = ::EndpointIndependentMapping; } } Cleanup: return hr; }
// The goal of this test is to just validate that we can create a message from CStunMessageBuilder and have it's output parsed correctly by CStunMessageReader // Also helps validate CSocketAddress HRESULT CTestBuilder::Test1() { HRESULT hr = S_OK; CStunMessageBuilder builder; CStunMessageReader reader; StunAttribute attrib; CRefCountedBuffer spBuffer; CRefCountedBuffer spBufferReader; CSocketAddress addrValidate(0,0); StunTransactionId transid = {}; uint32_t ipvalidate = 0; CSocketAddress addr(0x7f000001, 9999); CSocketAddress addrOrigin(0xAABBCCDD, 8888); CSocketAddress addrOther(0x11223344, 7777); ChkA(builder.AddBindingRequestHeader()); ChkA(builder.AddRandomTransactionId(&transid)); ChkA(builder.AddStringAttribute(STUN_ATTRIBUTE_SOFTWARE, "FOOBAR")); ChkA(builder.AddMappedAddress(addr)); ChkA(builder.AddXorMappedAddress(addr)); ChkA(builder.AddOtherAddress(addrOther)); ChkA(builder.AddResponseOriginAddress(addrOrigin)); ChkA(builder.AddFingerprintAttribute()); ChkA(builder.GetResult(&spBuffer)); ChkIfA(CStunMessageReader::BodyValidated != reader.AddBytes(spBuffer->GetData(), spBuffer->GetSize()), E_FAIL); ChkIfA(reader.HasFingerprintAttribute() == false, E_FAIL); ChkIfA(reader.IsFingerprintAttributeValid() == false, E_FAIL); ChkIfA(reader.GetMessageClass() != StunMsgClassRequest, E_FAIL); ChkIfA(reader.GetMessageType() != StunMsgTypeBinding, E_FAIL); ChkA(reader.GetBuffer(&spBufferReader)); ChkA(reader.GetAttributeByType(STUN_ATTRIBUTE_SOFTWARE, &attrib)); ChkIfA(attrib.attributeType != STUN_ATTRIBUTE_SOFTWARE, E_FAIL); ChkIfA(0 != ::strncmp("FOOBAR", (const char*)(spBufferReader->GetData() + attrib.offset), attrib.size), E_FAIL); ChkA(reader.GetXorMappedAddress(&addrValidate)); ChkIf(addrValidate.IsSameIP_and_Port(addr) == false, E_FAIL); ChkIfA(addrValidate.GetIPLength() != 4, E_FAIL); addrValidate = CSocketAddress(0,0); ChkA(reader.GetMappedAddress(&addrValidate)); ChkIfA(addrValidate.GetPort() != 9999, E_FAIL); ChkIfA(addrValidate.GetIPLength() != 4, E_FAIL); ChkIfA(4 != addrValidate.GetIP(&ipvalidate, 4), E_FAIL); ChkIfA(ipvalidate != 0x7f000001, E_FAIL); addrValidate = CSocketAddress(0,0); ipvalidate = 0; reader.GetOtherAddress(&addrValidate); ChkIfA(addrValidate.GetPort() != 7777, E_FAIL); ChkIfA(addrValidate.GetIPLength() != 4, E_FAIL); ChkIfA(4 != addrValidate.GetIP(&ipvalidate, 4), E_FAIL); ChkIf(ipvalidate != 0x11223344, E_FAIL); Cleanup: return hr; }