Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

login works

  • Loading branch information...
commit 6e25bc3f8c03e6b8e69c1eaf658353e00d1dfa7d 1 parent b9c59cd
@smirn0v authored
Showing with 137 additions and 16 deletions.
  1. +52 −4 mrim-bot/mmpbase.py
  2. +85 −12 mrim-bot/mrim_protocol.py
View
56 mrim-bot/mmpbase.py
@@ -1,9 +1,26 @@
from mmptypes import *
import struct
+MMP_CLIENT_STRING = "MRIM Johann Bot v0.1"
+
class MMPWrongHeaderData(Exception):
pass
+class MMPMalformedPacket(Exception):
+ pass
+
+def unpack_lps(data):
+ size_length = struct.calcsize('I')
+ if len(data) < size_length:
+ raise MMPMalformedPacket,"Can't extract string from data"
+ string_length = struct.unpack('I',data[:size_length])[0]
+ data = data[size_length:]
+ if len(data) < string_length:
+ raise MMPMalformedPacket("Incorrect string length received (string length = %d data length = %d)"%(string_length,len(data)))
+ string = struct.unpack("%ds"%string_length,data[:string_length])
+ data = data[string_length:]
+ return string
+
class MMPHeader(object):
size = 44 # usual MMP header size as stated in
# protocol specification
@@ -16,7 +33,7 @@ def __init__(self, magic = CS_MAGIC, proto = PROTO_VERSION, seq = 0, msg = 0, dl
self.dlen = dlen
def __str__(self):
- return "{magic: %d, proto: %d, seq: %d, msg: %d, dlen: %d}"%(
+ return "{magic: 0x%X, proto: 0x%X, seq: %d, msg: 0x%X, dlen: %d}"%(
self.magic,
self.proto,
self.seq,
@@ -29,7 +46,7 @@ def __repr__(self):
@classmethod
def from_binary_data(cls,data):
if len(data) < cls.size:
- raise MMPWrongHeaderDatai, "%d is minimum header size (%d given)"%(cls.size,len(data))
+ raise MMPWrongHeaderData, "%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]
@@ -57,7 +74,38 @@ def __init__(self,header):
def binary_data(self):
return self.header.binary_data()
+class MMPClientLogin2Packet(object):
+ msg = MRIM_CS_LOGIN2
+ def __init__(self,header,email,password):
+ self.header = header
+ self.header.msg = self.__class__.msg
+ self.email = email
+ self.password = password
+ self.header.dlen = struct.calcsize('4I')+len(email)+len(password)+len(MMP_CLIENT_STRING)
+ def binary_data(self):
+ header_data = self.header.binary_data()
+ payload = ""
+ payload += struct.pack('I',len(self.email)) + self.email
+ payload += struct.pack('I',len(self.password)) + self.password
+ payload += struct.pack('I',STATUS_ONLINE)
+ payload += struct.pack('I',len(MMP_CLIENT_STRING)) + MMP_CLIENT_STRING
+ return header_data+payload
+
class MMPServerHelloAckPacket(object):
msg = MRIM_CS_HELLO_ACK
- def __init__(self, binary_data):
- pass
+ def __init__(self, header, binary_data):
+ self.header = header
+ if len(binary_data) != struct.calcsize('I'):
+ raise MMPMalformedPacket, "Wrong size of HelloAck payload"
+ self.interval = struct.unpack('I',binary_data)
+
+class MMPServerLoginAckPacket(object):
+ msg = MRIM_CS_LOGIN_ACK
+ def __init__(self, header, binary_data):
+ self.header = header
+
+class MMPServerLoginRejPacket(object):
+ msg = MRIM_CS_LOGIN_REJ
+ def __init__(self, header, binary_data):
+ self.header = header
+ self.reason = unpack_lps(binary_data)
View
97 mrim-bot/mrim_protocol.py
@@ -3,12 +3,73 @@
from twisted.persisted import styles
from twisted.protocols import basic
-class MRIMHelloAckHandler(object):
- pass
+class MRIMBaseHandler(object):
+ def __init__(self, protocol):
+ self.auto_remove_handler = True
+ self.protocol = protocol
-class MRIMDispatcherMixin(object):
- pass
+class MRIMLogin2AckHandler(MRIMBaseHandler):
+ def __init__(self, protocol, seq):
+ super(MRIMLogin2AckHandler,self).__init__(protocol)
+ self.seq = seq
+
+ def canHandlePacket(self,packet):
+ return packet.header.seq == self.seq and isinstance(packet,MMPServerLoginAckPacket)
+
+ def handlePacket(self,packet):
+ print "Login ack received"
+
+class MRIMLogin2RejHandler(MRIMBaseHandler):
+ def __init__(self,protocol,seq):
+ super(MRIMLogin2RejHandler,self).__init__(protocol)
+ self.seq = seq
+
+ def canHandlePacket(self,packet):
+ return packet.header.seq == self.seq and isinstance(packet,MMPServerLoginRejPacket)
+
+ def handlePacket(self,packet):
+ print "[-] Login rejected: %s"%packet.reason
+
+class MRIMHelloAckHandler(MRIMBaseHandler):
+ def __init__(self, protocol, seq):
+ super(MRIMHelloAckHandler,self).__init__(protocol)
+ self.seq = seq
+ def canHandlePacket(self,packet):
+ return packet.header.seq == self.seq and isinstance(packet,MMPServerHelloAckPacket)
+
+ def handlePacket(self,packet):
+ header = self.protocol.createHeader()
+ packet = MMPClientLogin2Packet(header,"johann-the-builder@mail.ru","buildpleasemail")
+ self.protocol.addHandler(MRIMLogin2RejHandler(self.protocol,header.seq))
+ self.protocol.addHandler(MRIMLogin2AckHandler(self.protocol,header.seq))
+ self.protocol.sendPacket(packet)
+
+class MRIMDispatcherMixin(object):
+
+ def addHandler(self,handler):
+ self.handlers += [handler]
+
+ def formPacket(self,header,payload):
+ for packet_class in self.supported_server_packets:
+ if packet_class.msg == header.msg:
+ return packet_class(header,payload)
+ return None
+
+ def handlePacket(self,header,payload):
+ packet = self.formPacket(header,payload)
+
+ if not packet: return
+
+ print "[+] Packet parsed"
+
+ packetHandlers = [h for h in self.handlers if h.canHandlePacket(packet)]
+
+ for handler in packetHandlers:
+ handler.handlePacket(packet)
+ if handler.auto_remove_handler:
+ self.handlers.remove(handler)
+
class MRIMMode:
Header= 1
Body= 2
@@ -19,15 +80,19 @@ class MRIMProtocol(protocol.Protocol,MRIMDispatcherMixin):
"""
def __init__(self):
+ self.handlers = []
+ self.supported_server_packets = [MMPServerHelloAckPacket,
+ MMPServerLoginAckPacket,
+ MMPServerLoginRejPacket]
self.buffer = ""
self.mode = MRIMMode.Header
self.seq = 1
- self.supportedPackets = [MMPServerHelloAckPacket]
def connectionMade(self):
print "[+] Connected"
packet = MMPClientHelloPacket(self.createHeader())
- self.transport.write(packet.binary_data())
+ self.addHandler(MRIMHelloAckHandler(self,packet.header.seq))
+ self.sendPacket(packet)
def connectionLost(self,reason):
pass
@@ -35,8 +100,8 @@ def connectionLost(self,reason):
def dataReceived(self,data):
self.buffer += data
handlers = {
- MRIMMode.Header: self.extractHeader,
- MRIMMode.Body: self.extractBody
+ MRIMMode.Header: self._extractHeader,
+ MRIMMode.Body: self._extractBody
}
handlers[self.mode]()
@@ -45,7 +110,13 @@ def createHeader(self):
self.seq+=1
return header
- def extractHeader(self):
+ def sendPacket(self,packet):
+ self.transport.write(packet.binary_data())
+
+ def startHeartBeat(self,interval):
+ pass
+
+ def _extractHeader(self):
if len(self.buffer) < MMPHeader.size:
return
header_data = self.buffer[:MMPHeader.size]
@@ -53,15 +124,17 @@ def extractHeader(self):
self.header = MMPHeader.from_binary_data(header_data)
self.mode = MRIMMode.Body
print "[+] Header received %s"%self.header
- self.extractBody()
+ self._extractBody()
- def extractBody(self):
+ def _extractBody(self):
if len(self.buffer) < self.header.dlen:
return
print "[+] Body received, len = %d"%self.header.dlen
+ payload = self.buffer[:self.header.dlen]
self.buffer = self.buffer[self.header.dlen:]
self.mode = MRIMMode.Header
- self.extractHeader()
+ self.handlePacket(self.header,payload)
+ self._extractHeader()
class MRIMClientFactory(protocol.ClientFactory):
def buildProtocol(self, address):
Please sign in to comment.
Something went wrong with that request. Please try again.