Esempio n. 1
0
void AMFWriter::writeSimpleObject(const AMFSimpleObject& object) {
	beginObject();
	AbstractConfiguration::Keys keys;
	object.keys(keys);
	AbstractConfiguration::Keys::const_iterator it;
	for(it=keys.begin();it!=keys.end();++it) {
		string name = *it;
		int type = object.getInt(name+".type",-1);
		switch(type) {
			case AMF::Boolean:
				writeObjectProperty(name,object.getBool(name));
				break;
			case AMF::String:
				writeObjectProperty(name,object.getString(name));
				break;
			case AMF::Number:
				writeObjectProperty(name,object.getDouble(name));
				break;
			case AMF::Integer:
				writeObjectProperty(name,object.getInt(name));
				break;
			case AMF::Date: {
				Timestamp date((Timestamp::TimeVal)object.getDouble(name)*1000);
				writeObjectProperty(name,date);
				break;
			}
			case AMF::Null:
				writeObjectProperty(name);
				break;
			default:
				ERROR("Unknown AMFObject %d type",type);
		}
	}
	endObject();
}
Esempio n. 2
0
void Middle::packetHandler(PacketReader& packet) {
	if(!_pMiddleAesEncrypt) {
		DEBUG("500ms sleeping to wait target handshaking");
		Thread::sleep(500); // to wait the target handshake response
		manage();
	}

	// Middle to target
	PacketWriter& request = requester();

	UInt8 marker = packet.read8();
	request << marker;

	request << packet.read16();

	if((marker|0xF0) == 0xFD)
		request.write16(packet.read16()); // time echo

	int pos = request.position();

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;
	while(type!=0xFF) {
		UInt16 size = packet.read16();
		PacketReader content(packet.current(),size);

		PacketWriter out(request.begin()+request.position(),request.available()); // 3 for future type and size
		out.clear(3);

		if(type==0x10) {

			out.write8(content.read8());
			UInt32 idFlow = content.read7BitValue();out.write7BitValue(idFlow);
			UInt32 stage = content.read7BitValue();out.write7BitValue(stage);

			if(idFlow==0x02 && stage==0x01) {
				if(!_isPeer) {
				
					/// Replace NetConnection infos

					out.writeRaw(content.current(),14);content.next(14);

					// first string
					string tmp;
					content.readString16(tmp);out.writeString16(tmp);

					AMFWriter writer(out);
					writer.amf0Preference=true;
					AMFReader reader(content);
					writer.writeNumber(reader.readNumber()); // double
					
					AMFSimpleObject obj;
					reader.readSimpleObject(obj);
					
					/// Replace tcUrl
					if(obj.has("tcUrl"))
						obj.setString("tcUrl",_queryUrl);
					
					writer.writeSimpleObject(obj);

				} else {

					out.writeRaw(content.current(),3);content.next(3);
					UInt16 netGroupHeader = content.read16();out.write16(netGroupHeader);
					if(netGroupHeader==0x4752) {
						out.writeRaw(content.current(),71);content.next(71);
						
						Entities<Group>::Iterator it;
						for(it = _invoker.groups.begin();it!=_invoker.groups.end();++it) {
	
							Group& group = *it->second;						
			
							Group::Iterator itP;
							for(itP=group.begin();itP!=group.end();++itP) {
								if((**itP)==_target.id) {
									UInt8 result1[AES_KEY_SIZE];
									UInt8 result2[AES_KEY_SIZE];
									HMAC(EVP_sha256(),_sharedSecret,KEY_SIZE,&_targetNonce[0],_targetNonce.size(),result1,NULL);
									HMAC(EVP_sha256(),group.id,ID_SIZE,result1,AES_KEY_SIZE,result2,NULL);
									out.writeRaw(result2,AES_KEY_SIZE);content.next(AES_KEY_SIZE);
									out.writeRaw(content.current(),4);content.next(4);
									out.writeRaw(_target.peerId,ID_SIZE);content.next(ID_SIZE);
									break;
								}
							}
							if(itP!=group.end())
								break;

						}
						if(it==_invoker.groups.end())
							ERROR("Handshake NetGroup packet between peers without corresponding Group");
						
					}
				}
			}

		}  else if(type == 0x4C) {
			 kill();
		}  else if(type == 0x51) {
			//printf("%s\n",Util::FormatHex(content.current(),content.available()).c_str());
		}
		out.writeRaw(content.current(),content.available());

		packet.next(size);

		if(out.length()>=3) {
			request<<type;
			size = out.length()-3;
			request.write16(size);request.next(size);
		}


		type = packet.available()>0 ? packet.read8() : 0xFF;
	}

	if(request.length()>pos)
		sendToTarget();
}
Esempio n. 3
0
void Middle::packetHandler(PacketReader& packet) {
	if(!_pMiddleAesEncrypt)
		manage(); // to wait the target handshake response

	// Middle to target
	PacketWriter& request = requester();

	UInt8 marker = packet.read8();
	request << marker;

	request << packet.read16();

	if((marker|0xF0) == 0xFD)
		request.write16(packet.read16()); // time echo

	int pos = request.position();

	UInt8 type = packet.available()>0 ? packet.read8() : 0xFF;
	while(type!=0xFF) {
		UInt16 size = packet.read16();
		PacketReader content(packet.current(),size);

		PacketWriter out(request.begin()+request.position(),request.available()); // 3 for future type and size
		out.clear(3);

		if(type==0x10) {

			out.write8(content.read8());
			UInt64 idFlow = content.read7BitLongValue();out.write7BitLongValue(idFlow);
			UInt64 stage = content.read7BitLongValue();out.write7BitLongValue(stage);

			if(idFlow==0x02 && stage==0x01) {
				if(!_isPeer) {
				
					/// Replace NetConnection infos

					out.writeRaw(content.current(),14);content.next(14);

					// first string
					string tmp;
					content.readString16(tmp);out.writeString16(tmp);

					AMFWriter writer(out);
					writer.amf0Preference=true;
					AMFReader reader(content);
					writer.writeNumber(reader.readNumber()); // double
					
					AMFSimpleObject obj;
					reader.readSimpleObject(obj);
					
					/// Replace tcUrl
					if(obj.has("tcUrl"))
						obj.setString("tcUrl",_queryUrl);
					
					writer.writeSimpleObject(obj);

				} else {

					out.writeRaw(content.current(),3);content.next(3);
					UInt16 netGroupHeader = content.read16();out.write16(netGroupHeader);
					if(netGroupHeader==0x4752) {

						map<string,string>::const_iterator it = peer.properties.find("groupspec");
						if(it!=peer.properties.end()) {
							out.writeRaw(content.current(),71);content.next(71);
							UInt8 result1[AES_KEY_SIZE];
							UInt8 result2[AES_KEY_SIZE];
							HMAC(EVP_sha256(),&_sharedSecret[0],_sharedSecret.size(),&_targetNonce[0],_targetNonce.size(),result1,NULL);
							HMAC(EVP_sha256(),it->second.c_str(),it->second.size(),result1,AES_KEY_SIZE,result2,NULL);
							out.writeRaw(result2,AES_KEY_SIZE);content.next(AES_KEY_SIZE);
							out.writeRaw(content.current(),4);content.next(4);
							out.writeRaw(_target.peerId,ID_SIZE);content.next(ID_SIZE);
						} else
							WARN("No groupspec client property indicated to make working the 'man-in-the-middle' mode between peers in a NetGroup case");
						
					}
				}
			}

		}  else if(type == 0x4C) {
			 kill();
			 return;
		}  else if(type == 0x51) {
			//printf("%s\n",Util::FormatHex(content.current(),content.available()).c_str());
		}
		out.writeRaw(content.current(),content.available());

		packet.next(size);

		if(out.length()>=3) {
			request<<type;
			size = out.length()-3;
			request.write16(size);request.next(size);
		}


		type = packet.available()>0 ? packet.read8() : 0xFF;
	}

	if(request.length()>pos)
		sendToTarget();
}
Esempio n. 4
0
void FlowConnection::messageHandler(const std::string& name,AMFReader& message) {
	if(name=="connect") {
		message.stopReferencing();
		AMFSimpleObject obj;
		message.readSimpleObject(obj);
		message.startReferencing();
		((URI&)peer.swfUrl) = obj.getString("swfUrl","");
		((URI&)peer.pageUrl) = obj.getString("pageUrl","");
		((string&)peer.flashVersion) = obj.getString("flashVer","");

		// Don't support AMF0 forced on NetConnection object because AMFWriter writes in AMF3 format
		// But it's not a pb because NetConnection RTMFP works since flash player 10.0 only (which supports AMF3)
		if(obj.getNumber("objectEncoding",0)==0) {
			writer.writeErrorResponse("Connect.Rejected","ObjectEncoding client must be in a AMF3 format (not AMF0)");
			return;
		}

		// Check if the client is authorized
		peer.setFlowWriter(&writer);
		writer.beginTransaction();
		bool accept=true;
		{
			AMFObjectWriter response(writer.writeSuccessResponse("Connect.Success","Connection succeeded"));
			response.write("objectEncoding",3.0);
			accept = peer.onConnection(message,response);
		}
		if(!accept) {
			writer.endTransaction(1);
			writer.writeAMFMessage("close");
			writer.close();
		} else
			writer.endTransaction();

	} else if(name == "setPeerInfo") {

		peer.addresses.resize(1);
		string addr;
		while(message.available()) {
			message.read(addr); // private host
			peer.addresses.push_back(addr);
		}
		
		BinaryWriter& response(writer.writeRawMessage());
		response.write16(0x29); // Unknown!
		response.write32(invoker.keepAliveServer);
		response.write32(invoker.keepAlivePeer);

	} else if(name == "initStream") {
		// TODO?
	} else if(name == "createStream") {

		AMFWriter& response(writer.writeAMFResult());
		response.writeInteger(*_streamIndex.insert(invoker._streams.create()).first);

	} else if(name == "deleteStream") {
		UInt32 index = (UInt32)message.readNumber();
		_streamIndex.erase(index);
		invoker._streams.destroy(index);
	} else {
		if(!peer.onMessage(name,message))
			writer.writeErrorResponse("Call.Failed","Method '" + name + "' not found");
	}
}