bool PyCachedCall::Decode(PySubStream **in_ss) { PySubStream *ss = *in_ss; //consume *in_ss = NULL; PySafeDecRef( result ); ss->DecodeData(); if(ss->decoded() == NULL) { SysLog::Error("PyCachedCall","Unable to decode initial stream for PyCachedCall"); PyDecRef( ss ); return false; } if(!ss->decoded()->IsDict()) { SysLog::Error("PyCachedCall","Cached call substream does not contain a dict: %s", ss->decoded()->TypeString()); PyDecRef( ss ); return false; } PyDict *po = (PyDict *) ss->decoded(); PyDict::const_iterator cur, end; cur = po->begin(); end = po->end(); for(; cur != end; cur++) { if(!cur->first->IsString()) continue; PyString *key = (PyString *) cur->first; if( key->content() == "lret" ) result = cur->second->Clone(); } PyDecRef( ss ); return(result != NULL); }
bool PyCachedObjectDecoder::Decode(PySubStream **in_ss) { PySubStream *ss = *in_ss; //consume *in_ss = NULL; PySafeDecRef( cache ); PySafeDecRef( objectID ); ss->DecodeData(); if(ss->decoded() == NULL) { sLog.Error("PyCachedObjectDecoder","Unable to decode initial stream for PycachedObject"); PyDecRef( ss ); return false; } if(!ss->decoded()->IsObject()) { sLog.Error("PyCachedObjectDecoder","Cache substream does not contain an object: %s", ss->decoded()->TypeString()); PyDecRef( ss ); return false; } PyObject *po = (PyObject *) ss->decoded(); //TODO: could check type string, dont care... (should be objectCaching.CachedObject) if(!po->arguments()->IsTuple()) { sLog.Error("PyCachedObjectDecoder","Cache object's args is not a tuple: %s", po->arguments()->TypeString()); PyDecRef( ss ); return false; } PyTuple *args = (PyTuple *) po->arguments(); if(args->items.size() != 7) { sLog.Error("PyCachedObjectDecoder","Cache object's args tuple has %lu elements instead of 7", args->items.size()); PyDecRef( ss ); return false; } if(!args->items[0]->IsTuple()) { sLog.Error("PyCachedObjectDecoder","Cache object's arg %d is not a Tuple: %s", 0, args->items[0]->TypeString()); PyDecRef( ss ); return false; } //ignore unknown [1] /*if(!args->items[1]->IsInt()) { _log(CLIENT__ERROR, "Cache object's arg %d is not a None: %s", 1, args->items[1]->TypeString()); PyDecRef( ss ); return false; }*/ if(!args->items[2]->IsInt()) { sLog.Error("PyCachedObjectDecoder","Cache object's arg %d is not an Integer: %s", 2, args->items[2]->TypeString()); PyDecRef( ss ); return false; } if(!args->items[3]->IsInt()) { sLog.Error("PyCachedObjectDecoder","Cache object's arg %d is not an Integer: %s", 3, args->items[3]->TypeString()); PyDecRef( ss ); return false; } if(!args->items[5]->IsInt()) { sLog.Error("PyCachedObjectDecoder","Cache object's arg %d is not a : %s", 5, args->items[5]->TypeString()); PyDecRef( ss ); return false; } PyTuple *objVt = (PyTuple *) args->items[0]; if(!objVt->items[0]->IsInt()) { sLog.Error("PyCachedObjectDecoder","Cache object's version tuple %d is not an Integer: %s", 0, objVt->items[0]->TypeString()); PyDecRef( ss ); return false; } if(!objVt->items[1]->IsInt()) { sLog.Error("PyCachedObjectDecoder","Cache object's version tuple %d is not an Integer: %s", 1, objVt->items[1]->TypeString()); PyDecRef( ss ); return false; } PyInt *nodeidr = (PyInt *) args->items[2]; PyInt *sharedr = (PyInt *) args->items[3]; PyInt *compressedr = (PyInt *) args->items[5]; PyInt *timer = (PyInt *) objVt->items[0]; PyInt *versionr = (PyInt *) objVt->items[1]; timestamp = timer->value(); version = versionr->value(); nodeID = nodeidr->value(); shared = ( sharedr->value() != 0 ); compressed = ( compressedr->value() != 0 ); //content (do this as the last thing, since its the heavy lifting): if(args->items[4]->IsSubStream()) { cache = (PySubStream *) args->items[4]; //take it args->items[4] = NULL; } else if(args->items[4]->IsBuffer()) { //this is a data buffer, likely compressed. PyBuffer* buf = args->items[4]->AsBuffer(); PyIncRef( buf ); cache = new PySubStream( buf ); } else if(args->items[4]->IsString()) { //this is a data buffer, likely compressed, not sure why it comes through as a string... PyString* str = args->items[4]->AsString(); cache = new PySubStream( new PyBuffer( *str ) ); } else { sLog.Error("PyCachedObjectMgr", "Cache object's arg %d is not a substream or buffer: %s", 4, args->items[4]->TypeString()); PyDecRef( ss ); return false; } objectID = args->items[6]; PyIncRef(objectID); PyDecRef( ss ); return true; }
bool EVENotificationStream::Decode(const std::string &pkt_type, const std::string ¬ify_type, PyTuple *&in_payload) { PyTuple *payload = in_payload; //consume in_payload = NULL; PySafeDecRef(args); args = NULL; if(pkt_type != "macho.Notification") { codelog(NET__PACKET_ERROR, "notification payload has unknown string type %s", pkt_type.c_str()); PyDecRef(payload); return false; } //decode payload tuple if(payload->items.size() != 2) { codelog(NET__PACKET_ERROR, "invalid tuple length %lu", payload->items.size()); PyDecRef(payload); return false; } if(!payload->items[0]->IsTuple()) { codelog(NET__PACKET_ERROR, "non-tuple payload[0]"); PyDecRef(payload); return false; } PyTuple *payload2 = (PyTuple *) payload->items[0]; if(payload2->items.size() != 2) { codelog(NET__PACKET_ERROR, "invalid tuple2 length %lu", payload2->items.size()); PyDecRef(payload); return false; } //decode inner payload tuple //ignore tuple 0, it should be an int, dont know what it is if(!payload2->items[1]->IsSubStream()) { codelog(NET__PACKET_ERROR, "non-substream type"); PyDecRef(payload); return false; } PySubStream *ss = (PySubStream *) payload2->items[1]; ss->DecodeData(); if(ss->decoded() == NULL) { codelog(NET__PACKET_ERROR, "Unable to decode call stream"); PyDecRef(payload); return false; } if(!ss->decoded()->IsTuple()) { codelog(NET__PACKET_ERROR, "packet body does not contain a tuple"); PyDecRef(payload); return false; } PyTuple *robjt = (PyTuple *) ss->decoded(); if(robjt->items.size() != 2) { codelog(NET__PACKET_ERROR, "packet body has %lu elements, expected %d", robjt->items.size(), 2); PyDecRef(payload); return false; } //parse first tuple element, remote object if(robjt->items[0]->IsInt()) { PyInt *tuple0 = (PyInt *) robjt->items[0]; remoteObject = tuple0->value(); remoteObjectStr = ""; } else if(robjt->items[0]->IsString()) { PyString *tuple0 = (PyString *) robjt->items[0]; remoteObject = 0; remoteObjectStr = tuple0->content(); } else { codelog(NET__PACKET_ERROR, "main tuple[0] has invalid type %s", robjt->items[0]->TypeString()); _log(NET__PACKET_ERROR, " in:"); payload->Dump( NET__PACKET_ERROR, "" ); PyDecRef(payload); return false; } if(!robjt->items[1]->IsTuple()) { codelog(NET__PACKET_ERROR, "main tuple[1] has non-tuple type %s", robjt->items[0]->TypeString()); _log(NET__PACKET_ERROR, " it is:"); payload->Dump( NET__PACKET_ERROR, "" ); PyDecRef(payload); return false; } PyTuple *subt = (PyTuple *) robjt->items[1]; if(subt->items.size() != 2) { codelog(NET__PACKET_ERROR, "packet body has %lu elements, expected %d", subt->items.size(), 2); PyDecRef(payload); return false; } //parse first tuple element, remote object if(subt->items[0]->IsInt()) { //PyInt *tuple0 = (PyInt *) maint->items[0]; //no idea what this is. } else { codelog(NET__PACKET_ERROR, "sub tuple[0] has invalid type %s", subt->items[0]->TypeString()); _log(NET__PACKET_ERROR, " in:"); payload->Dump( NET__PACKET_ERROR, "" ); PyDecRef(payload); return false; } if(!subt->items[1]->IsTuple()) { codelog(NET__PACKET_ERROR, "subt tuple[1] has non-tuple type %s", robjt->items[0]->TypeString()); _log(NET__PACKET_ERROR, " it is:"); payload->Dump( NET__PACKET_ERROR, "" ); PyDecRef(payload); return false; } args = (PyTuple *) subt->items[1]; subt->items[1] = NULL; notifyType = notify_type; PyDecRef(payload); return true; }
bool PyCallStream::Decode(const std::string &type, PyTuple *&in_payload) { PyTuple *payload = in_payload; //consume in_payload = NULL; PySafeDecRef(arg_tuple); PySafeDecRef(arg_dict); arg_tuple = NULL; arg_dict = NULL; if(type != "macho.CallReq") { codelog(NET__PACKET_ERROR, "failed: packet payload has unknown string type '%s'", type.c_str()); PyDecRef(payload); return false; } if (payload->items.size() != 1) { codelog(NET__PACKET_ERROR, "invalid tuple length %lu", payload->items.size()); PyDecRef(payload); return false; } if (!payload->items[0]->IsTuple()) { codelog(NET__PACKET_ERROR, "non tuple payload[0]"); PyDecRef(payload); return false; } PyTuple *payload2 = (PyTuple *) payload->items[0]; if(payload2->items.size() != 2) { codelog(NET__PACKET_ERROR, "invalid tuple2 length %lu", payload2->items.size()); PyDecRef(payload); return false; } //decode inner payload tuple //ignore tuple 0, it should be an int, dont know what it is if(!payload2->items[1]->IsSubStream()) { codelog(NET__PACKET_ERROR, "non-substream type"); PyDecRef(payload); return false; } PySubStream *ss = (PySubStream *) payload2->items[1]; ss->DecodeData(); if(ss->decoded() == NULL) { codelog(NET__PACKET_ERROR, "Unable to decode call stream"); PyDecRef(payload); return false; } if(!ss->decoded()->IsTuple()) { codelog(NET__PACKET_ERROR, "packet body does not contain a tuple"); PyDecRef(payload); return false; } PyTuple *maint = (PyTuple *) ss->decoded(); if(maint->items.size() != 4) { codelog(NET__PACKET_ERROR, "packet body has %lu elements, expected %d", maint->items.size(), 4); PyDecRef(payload); return false; } //parse first tuple element, unknown if(maint->items[0]->IsInt()) { PyInt *tuple0 = (PyInt *) maint->items[0]; remoteObject = tuple0->value(); remoteObjectStr = ""; } else if(maint->items[0]->IsString()) { PyString *tuple0 = (PyString *) maint->items[0]; remoteObject = 0; remoteObjectStr = tuple0->content(); } else { codelog(NET__PACKET_ERROR, "tuple[0] has invalid type %s", maint->items[0]->TypeString()); codelog(NET__PACKET_ERROR, " in:"); payload->Dump(NET__PACKET_ERROR, " "); PyDecRef(payload); return false; } //parse tuple[1]: method name if(maint->items[1]->IsString()) { PyString *i = (PyString *) maint->items[1]; method = i->content(); } else { codelog(NET__PACKET_ERROR, "tuple[1] has non-string type"); maint->items[1]->Dump(NET__PACKET_ERROR, " --> "); codelog(NET__PACKET_ERROR, " in:"); payload->Dump(NET__PACKET_ERROR, " "); PyDecRef(payload); return false; } //grab argument list. if(!maint->items[2]->IsTuple()) { codelog(NET__PACKET_ERROR, "argument list has non-tuple type"); maint->items[2]->Dump(NET__PACKET_ERROR, " --> "); codelog(NET__PACKET_ERROR, "in:"); payload->Dump(NET__PACKET_ERROR, " "); PyDecRef(payload); return false; } arg_tuple = (PyTuple *) maint->items[2]; maint->items[2] = NULL; //we keep this one //options dict if(maint->items[3]->IsNone()) { arg_dict = NULL; } else if(maint->items[3]->IsDict()) { arg_dict = (PyDict *) maint->items[3]; maint->items[3] = NULL; //we keep this too. } else { codelog(NET__PACKET_ERROR, "tuple[3] has non-dict type"); maint->items[3]->Dump(NET__PACKET_ERROR, " --> "); codelog(NET__PACKET_ERROR, "in:"); payload->Dump(NET__PACKET_ERROR, " "); PyDecRef(payload); return false; } PyDecRef(payload); return true; }
bool PyPacket::Decode(PyRep **in_packet) { PyRep *packet = *in_packet; //consume *in_packet = NULL; PySafeDecRef(payload); PySafeDecRef(named_payload); if(packet->IsChecksumedStream()) { PyChecksumedStream* cs = packet->AsChecksumedStream(); //TODO: check cs->checksum packet = cs->stream(); PyIncRef( packet ); PyDecRef( cs ); } //Dragon nuance... it gets wrapped again if(packet->IsSubStream()) { PySubStream* ss = packet->AsSubStream(); ss->DecodeData(); if(ss->decoded() == NULL) { codelog(NET__PACKET_ERROR, "failed: unable to decode initial packet substream."); PyDecRef(packet); return false; } packet = ss->decoded(); PyIncRef( packet ); PyDecRef( ss ); } if(!packet->IsObject()) { codelog(NET__PACKET_ERROR, "failed: packet body is not an 'Object': %s", packet->TypeString()); PyDecRef(packet); return false; } PyObject *packeto = (PyObject *) packet; type_string = packeto->type()->content(); if(!packeto->arguments()->IsTuple()) { codelog(NET__PACKET_ERROR, "failed: packet body does not contain a tuple"); PyDecRef(packet); return false; } PyTuple *tuple = (PyTuple *) packeto->arguments(); if(tuple->items.size() != 7) { codelog(NET__PACKET_ERROR, "failed: packet body does not contain a tuple of length 7"); PyDecRef(packet); return false; } if(!tuple->items[0]->IsInt()) { codelog(NET__PACKET_ERROR, "failed: First main tuple element is not an integer"); PyDecRef(packet); return false; } PyInt *typer = (PyInt *) tuple->items[0]; switch(typer->value()) { case AUTHENTICATION_REQ: case AUTHENTICATION_RSP: case IDENTIFICATION_REQ: case IDENTIFICATION_RSP: case CALL_REQ: case CALL_RSP: case TRANSPORTCLOSED: case RESOLVE_REQ: case RESOLVE_RSP: case NOTIFICATION: case ERRORRESPONSE: case SESSIONCHANGENOTIFICATION: case SESSIONINITIALSTATENOTIFICATION: case PING_REQ: case PING_RSP: type = (MACHONETMSG_TYPE) typer->value(); break; default: codelog(NET__PACKET_ERROR, "failed: Unknown message type %"PRIu64, typer->value()); PyDecRef(packet); return false; break; } //source address if(!source.Decode(tuple->items[1])) { //error printed in decoder PyDecRef(packet); return false; } //dest address if(!dest.Decode(tuple->items[2])) { //error printed in decoder PyDecRef(packet); return false; } if(tuple->items[3]->IsInt()) { PyInt *i = (PyInt *) tuple->items[3]; userid = i->value(); } else if(tuple->items[3]->IsNone()) { userid = 0; } else { codelog(NET__PACKET_ERROR, "failed: User ID has invalid type"); PyDecRef(packet); return false; } //payload if(!(tuple->items[4]->IsBuffer() || tuple->items[4]->IsTuple())) { codelog(NET__PACKET_ERROR, "failed: Fifth main tuple element is not a tuple"); PyDecRef(packet); return false; } payload = (PyTuple *) tuple->items[4]; tuple->items[4] = NULL; //we keep this one //options dict if(tuple->items[5]->IsNone()) { named_payload = NULL; } else if(tuple->items[5]->IsDict()) { named_payload = (PyDict *) tuple->items[5]; tuple->items[5] = NULL; //we keep this too. } else { codelog(NET__PACKET_ERROR, "failed: Sixth main tuple element is not a dict"); PyDecRef(packet); return false; } PyDecRef(packet); return true; }