📄 pyfetion1.py.py
字号:
self.__http_tunnel = http_tunnel self.__ssic = ssic guid = str(uuid1()) self.__exheaders = { 'Cookie':'ssic=%s' % self.__ssic, 'Content-Type':'application/oct-stream', 'Pragma':'xz4BBcV%s' % guid, } def init(self,type): self.content = '%s %s %s\r\n' % (type,self.domain,self.ver) self.header = [('F',self.sid), ('I',self.ID), ('Q','1 %s' % type), ] def send(self): content = self.content d_print(('content',),locals()) if self.login_type == "HTTP": #First time t SHOULD SET AS 'i' #Otherwise 405 code get if self.__seq == 1: t = 'i' else: t = 's' url = self.__http_tunnel+"?t=%s&i=%s" % (t,self.__seq) ret = http_send(url,content,self.__exheaders) response = ret.read() self.__seq+=1 response = self.__sendSIPP() #This line will enhance the probablity of success. #Sometimes it will return FetionSIPP twice. #Probably you need add more if response == FetionSIPP: response = self.__sendSIPP() else: if self.__seq == 1: self.__tcp_init() self.__tcp_send(content) response = self.__tcp_recv() d_print(('response',),locals()) self.__seq+=1 code = self.get_code(response) d_print(('code',),locals()) return response def get_code(self,response): try: self.code =int(re.search("%s (\d{3})" % self.ver,response).group(1)) self.msg =re.search("%s \d{3} (.*)\r" % self.ver,response).group(1) d_print(('self.code','self.msg',),locals()) return self.code except AttributeError,e: return None def get(self,cmd,arg,ret="",extra=""): body = ret if cmd == "REG": if self.__see: body = FetionLoginXML % "400" else: body = FetionLoginXML % "0" self.init('R') if arg == 1: pass if arg == 2: nonce = re.search('nonce="(.*)"',ret).group(1) cnonce = self.__get_cnonce() if FetionVer == "2008": response=self.__get_response_sha1(nonce,cnonce) elif FetionVer == "2006": response=self.__get_response_md5(nonce,cnonce) salt = self.__get_salt() d_print(('nonce','cnonce','response','salt'),locals()) #If this step failed try to uncomment this lines #del self.header[2] #self.header.insert(2,('Q','2 R')) if FetionVer == "2008": self.header.insert(3,('A','Digest algorithm="SHA1-sess",response="%s",cnonce="%s",salt="%s"' % (response,cnonce,salt))) elif FetionVer == "2006": self.header.insert(3,('A','Digest response="%s",cnonce="%s"' % (response,cnonce))) #If register successful 200 code get if arg == 3: return self.code if cmd == "SENDMSG": self.init('M') self.header.insert(3,('T',arg)) self.header.insert(4,('C','text/plain')) self.header.insert(5,('K','SaveHistory')) if cmd == "SENDSMS": self.init('M') self.header.append(('T',arg)) self.header.append(('N','SendSMS')) if cmd == "SENDCatSMS": self.init('M') self.header.append(('T',arg)) self.header.append(('N','SendCatSMS')) if cmd == "SSSetScheduleSms": self.init('S') self.header.insert(3,('N',cmd)) body = '<args><schedule-sms send-time="%s"><message>%s</message><receivers><receiver uri="%s" /></receivers></schedule-sms></args>' % (ret,arg,extra) if cmd == "INFO": self.init('S') self.header.insert(3,('N',arg)) if arg == "GetPersonalInfo": body = '<args><personal attributes="all" /><services version="" attributes="all" /><config version="33" attributes="all" /><mobile-device attributes="all" /></args>' elif arg == "GetContactList": body = '<args><contacts><buddy-lists /><buddies attributes="all" /><mobile-buddies attributes="all" /><chat-friends /><blacklist /></contacts></args>' elif arg == "GetContactsInfo": body = '<args><contacts attributes="all"><contact uri="%s" /></contacts></args>' % ret elif arg == "AddBuddy": body = '<args><contacts><buddies><buddy uri="tel:%s" buddy-lists="1" desc="This message is send by PyFetion" expose-mobile-no="1" expose-name="1" /></buddies></contacts></args>' % ret elif arg == "AddMobileBuddy": body = '<args><contacts><mobile-buddies><mobile-buddy uri="tel:%s" buddy-lists="1" desc="THis message is send by PyFetion" invite="0" /></mobile-buddies></contacts></args>' % ret #general SIPC info self.header.append(('L',len(body))) for k in self.header: self.content = self.content + k[0] + ": " + str(k[1]) + "\r\n" self.content+="\r\n" self.content+= body if self.login_type == "HTTP": #IN TCP CONNECTION "SIPP" SHOULD NOT BEEN SEND self.content+= FetionSIPP return self.content def __sendSIPP(self): body = FetionSIPP url = self.__http_tunnel+"?t=s&i=%s" % self.__seq response = http_send(url,body,self.__exheaders).read() d_print(('response',),locals()) self.__seq+=1 return response def __tcp_init(self): try: self.__sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) except socket.error,e: s = None raise PyFetionSocketError(e.read()) (host,port) = tuple(self.__sipc_proxy.split(":")) port = int(port) try: self.__sock.connect((host,port)) except socket.error,e: self.__sock.close() raise PyFetionSocketError(e.read()) def __tcp_send(self,msg): try: self.__sock.send(msg) except socket.error,e: self.__sock.close() raise PyFetionSocketError(e.read()) def __tcp_recv(self): """read 1024 bytes first, if there's still more data, read left data. get length from header : L: 1022 """ total_data = [] size = 1024 try: while True: data = self.__sock.recv(size) total_data.append(data) if "\r\n\r\n" == data[-4:]: break elif re.search("L: (\d+)",data): match = re.search("L: (\d+)",data) body_len = int(match.group(1)) header_len = match.end() + 4 if len(data) == body_len + header_len: break else: size = body_len + header_len - len(data) self.__sock.settimeout(2) data = self.__sock.recv(size) total_data.append(data) break else: raise PyFetionSocketError("SHOULD NOT happened.") except socket.error,e: self.__sock.close() raise PyFetionSocketError(e.read()) return "".join(total_data) def __get_salt(self): return self.__hash_passwd()[:8] def __get_cnonce(self): return md5(str(uuid1())).hexdigest().upper() def __get_response_md5(self,nonce,cnonce): #nonce = "3D8348924962579418512B8B3966294E" #cnonce= "9E169DCA9CBD85F1D1A89A893E00917E" key = md5("%s:%s:%s" % (self.sid,self.domain,self.passwd)).digest() h1 = md5("%s:%s:%s" % (key,nonce,cnonce)).hexdigest().upper() h2 = md5("REGISTER:%s" % self.sid).hexdigest().upper() response = md5("%s:%s:%s" % (h1,nonce,h2)).hexdigest().upper() #d_print(('nonce','cnonce','key','h1','h2','response'),locals()) return response def __get_response_sha1(self,nonce,cnonce): #nonce = "3D8348924962579418512B8B3966294E" #cnonce= "9E169DCA9CBD85F1D1A89A893E00917E" hash_passwd = self.__hash_passwd() hash_passwd_str = binascii.unhexlify(hash_passwd[8:]) key = sha1("%s:%s:%s" % (self.sid,self.domain,hash_passwd_str)).digest() h1 = md5("%s:%s:%s" % (key,nonce,cnonce)).hexdigest().upper() h2 = md5("REGISTER:%s" % self.sid).hexdigest().upper() response = md5("%s:%s:%s" % (h1,nonce,h2)).hexdigest().upper() return response def __hash_passwd(self): #salt = '%s%s%s%s' % (chr(0x77), chr(0x7A), chr(0x6D), chr(0x03)) salt = 'wzm\x03' src = salt+sha1(self.passwd).digest() return "777A6D03"+sha1(src).hexdigest().upper()def http_send(url,body="",exheaders="",login=False): global proxy_info headers = { 'User-Agent':'IIC2.0/PC 3.2.0540', } headers.update(exheaders) if proxy_info: proxy_support = urllib2.ProxyHandler(\ {"http":"http://%(user)s:%(pass)s@%(host)s:%(port)d" % proxy_info}) opener = urllib2.build_opener(proxy_support) else: opener = urllib2.build_opener() urllib2.install_opener(opener) request = urllib2.Request(url,headers=headers,data=body) #add retry for GAE. #PyFetion will get 405 code sometimes, we should re-send the request. retry = 5 while retry: try: conn = urllib2.urlopen(request) except urllib2.URLError, e: if hasattr(e,'code'): code = e.code msg = e.read() else: code = e.errno msg = e.reason d_print(('code','msg'),locals()) if code == 401: if login: raise PyFetionAuthError(code,msg) if code == 404: raise PyFetionSupportError(code,msg) if code == 405: retry = retry - 1 continue raise PyFetionSocketError(msg) break return conndef d_print(vars=(),namespace=[],msg=""): """if only sigle variable use like this ('var',)""" global debug if not debug: return if debug == "file": log_file = file("pyfetion.log","a") stdout_old = sys.stdout sys.stdout = log_file if vars and not namespace and not msg: msg = vars if vars and namespace: for var in vars: if var in namespace: print "[PyFetion]:%s%s%s[" % (COL_RED,var,COL_NONE), print str(namespace[var]).decode('utf-8').encode(sys_encoding)+"]" if msg: print "[PyFetion]:%s %s %s" % (COL_RED,msg,COL_NONE) if debug == "file" and log_file: log_file.close() sys.stdout = stdout_olddef main(argv=None): phone = PyFetion("13514329211","123456","TCP") try: phone.login() except PyFetionSupportError,e: print u"鎵嬫満鍙锋湭寮
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -