diff --git a/mrim-bot/mmpbase.py b/mrim-bot/mmpbase.py index e617543..54f2450 100644 --- a/mrim-bot/mmpbase.py +++ b/mrim-bot/mmpbase.py @@ -7,7 +7,7 @@ class MMPWrongHeaderData(Exception): class MMPHeader(object): size = 44 # usual MMP header size as stated in # protocol specification - format = '7L16B' + format = '7I16B' def __init__(self, magic = CS_MAGIC, proto = PROTO_VERSION, seq = 0, msg = 0, dlen = 0): self.magic = magic self.proto = proto @@ -16,7 +16,8 @@ def __init__(self, magic = CS_MAGIC, proto = PROTO_VERSION, seq = 0, msg = 0, dl self.dlen = dlen def __str__(self): - return "{proto: %d, seq: %d, msg: %d, dlen: %d}"%( + return "{magic: %d, proto: %d, seq: %d, msg: %d, dlen: %d}"%( + self.magic, self.proto, self.seq, self.msg, @@ -28,9 +29,10 @@ def __repr__(self): @classmethod def from_binary_data(cls,data): if len(data) < cls.size: - raise MMPWrongHeaderDatai, "%d is minimum header size"%cls.size - # skipping last 16 reserved bytes - (magic,proto,seq,msg,dlen,fromip,fromport) = struct.unpack(cls.format,data[:-16]) + raise MMPWrongHeaderDatai, "%d is minimum header size (%d given)"%(cls.size,len(data)) + + # just skip 'reserved' 16 bytes + (magic,proto,seq,msg,dlen,fromip,fromport) = struct.unpack(cls.format,data)[:-16] header = cls(magic,proto,seq,msg,dlen) header.fromip = fromip @@ -39,12 +41,12 @@ def from_binary_data(cls,data): return header def binary_data(self): - return struct.pack(format, self.magic, - self.proto, - self.seq, - self.msg, - self.dlen, - *([0]*18)) + return struct.pack(MMPHeader.format, self.magic, + self.proto, + self.seq, + self.msg, + self.dlen, + *([0]*18)) class MMPClientHelloPacket(object): msg = MRIM_CS_HELLO @@ -53,7 +55,7 @@ def __init__(self,header): self.header.msg = self.__class__.msg self.header.dlen = 0 def binary_data(self): - return header.binary_data() + return self.header.binary_data() class MMPServerHelloAckPacket(object): msg = MRIM_CS_HELLO_ACK diff --git a/mrim-bot/mmptypes.py b/mrim-bot/mmptypes.py index 1250c5d..d86bcba 100644 --- a/mrim-bot/mmptypes.py +++ b/mrim-bot/mmptypes.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- +# Got from https://github.com/zinid/mrim/blob/master/src/mmptypes.py PROTO_VERSION_MAJOR = 1L PROTO_VERSION_MINOR = 9L PROTO_VERSION = (PROTO_VERSION_MAJOR << 16) | (PROTO_VERSION_MINOR) -CS_MAGIC = 0xDEADBEEFL # Клиентский Magic ( C <-> S ) +CS_MAGIC = 0xDEADBEEFL MRIM_CS_HELLO = 0x1001 # C -> S MRIM_CS_HELLO_ACK = 0x1002 # S -> C @@ -272,7 +273,6 @@ LPS client description //max 256 ''' -# Not described in protocol! (mail.ru sucks) #MRIM_CS_FILE_TRANSFER = 0x1026 # S -> C MRIM_CS_SMS = 0x1039 ''' diff --git a/mrim-bot/mrim_bot.py b/mrim-bot/mrim_bot.py index caf0251..1dc59f3 100644 --- a/mrim-bot/mrim_bot.py +++ b/mrim-bot/mrim_bot.py @@ -1,18 +1,34 @@ +from twisted.internet import reactor import mrim_protocol import telnetlib +import sys -def main(): +def server_to_connect(): telnet = telnetlib.Telnet("mrim.mail.ru",2042) address = telnet.read_all() telnet.close() host,port = address.split(":") + + if host == None or port == None or \ + len(port) < 2 or port[-1] != '\n': + return None,None + + port = port[:-1] #trim '\n' + if not port.isdigit(): return None,None + + return host,int(port) + +def main(): + host, port = server_to_connect() + if host==None or port==None: + print "[-] Error: can't receive mrim server to connect" + sys.exit(-1) - if !host or !port: - print "Can't receive mrim server to connect" - die - - print "host = %s, port = %d"%(host,int(port)) + print "[+] Host = %s; Port = %d"%(host,int(port)) + + reactor.connectTCP(host, port, mrim_protocol.MRIMClientFactory()) + reactor.run() if __name__ == "__main__": main() diff --git a/mrim-bot/mrim_protocol.py b/mrim-bot/mrim_protocol.py index 5f7bb33..6496276 100644 --- a/mrim-bot/mrim_protocol.py +++ b/mrim-bot/mrim_protocol.py @@ -19,25 +19,26 @@ class MRIMProtocol(protocol.Protocol,MRIMDispatcherMixin): """ def __init__(self): + self.buffer = "" self.mode = MRIMMode.Header self.seq = 1 self.supportedPackets = [MMPServerHelloAckPacket] def connectionMade(self): - log.msg("connected") + print "[+] Connected" packet = MMPClientHelloPacket(self.createHeader()) self.transport.write(packet.binary_data()) - def connectionLost(self): + def connectionLost(self,reason): pass def dataReceived(self,data): self.buffer += data handlers = { - MRIMMode.Header: extractHeader, - MRIMMode.Body: extractBody + MRIMMode.Header: self.extractHeader, + MRIMMode.Body: self.extractBody } - handlers[self.mode](self) + handlers[self.mode]() def createHeader(self): header = MMPHeader(seq = self.seq) @@ -51,8 +52,17 @@ def extractHeader(self): self.buffer = self.buffer[MMPHeader.size:] self.header = MMPHeader.from_binary_data(header_data) self.mode = MRIMMode.Body - log.msg("header received %s"%header) + print "[+] Header received %s"%self.header + self.extractBody() def extractBody(self): if len(self.buffer) < self.header.dlen: return + print "[+] Body received, len = %d"%self.header.dlen + self.buffer = self.buffer[self.header.dlen:] + self.mode = MRIMMode.Header + self.extractHeader() + +class MRIMClientFactory(protocol.ClientFactory): + def buildProtocol(self, address): + return MRIMProtocol()