From d4a86ca206bd2002f3763f8b67d12d56ba1036d2 Mon Sep 17 00:00:00 2001 From: lijun0326 Date: Wed, 18 Oct 2017 23:37:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AC=A1=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 70 +++++ README.md | 11 + files/luci/controller/jlu-drcom.lua | 15 + files/luci/i18n/jlu-drcom.zh-cn.po | 39 +++ files/luci/model/cbi/jlu-drcom.lua | 60 ++++ files/root/etc/init.d/drcom | 20 ++ files/root/lib/jlu-drcom/daemon.py | 33 ++ files/root/lib/jlu-drcom/newclient.py | 427 ++++++++++++++++++++++++++ 8 files changed, 675 insertions(+) create mode 100644 Makefile create mode 100644 README.md create mode 100644 files/luci/controller/jlu-drcom.lua create mode 100644 files/luci/i18n/jlu-drcom.zh-cn.po create mode 100644 files/luci/model/cbi/jlu-drcom.lua create mode 100644 files/root/etc/init.d/drcom create mode 100644 files/root/lib/jlu-drcom/daemon.py create mode 100644 files/root/lib/jlu-drcom/newclient.py diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..11f93e1 --- /dev/null +++ b/Makefile @@ -0,0 +1,70 @@ +# +# Copyright (C) 2017 scsz +# +# This is free software, licensed under the GNU Affero General Public License v3.0 +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-jlu-drcom +PKG_VERSION:=0.1.0 +PKG_RELEASE:=0 + +PKG_LICENSE:=AGPLv3 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=scsz + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=LuCI Support for jlu drcom + PKGARCH:=all + DEPENDS:=+python-light +endef + +define Package/$(PKG_NAME)/description + LuCI Support for jlu-drcom. +endef + +define Build/Prepare + $(foreach po,$(wildcard ${CURDIR}/files/luci/i18n/*.po), \ + po2lmo $(po) $(PKG_BUILD_DIR)/$(patsubst %.po,%.lmo,$(notdir $(po)));) +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/jlu-drcom +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/postinst +#!/bin/sh +chmod 755 /etc/init.d/drcom +exit 0 +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller + $(INSTALL_DATA) ./files/luci/controller/jlu-drcom.lua $(1)/usr/lib/lua/luci/controller/ + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n + $(INSTALL_DATA) $(PKG_BUILD_DIR)/jlu-drcom.*.lmo $(1)/usr/lib/lua/luci/i18n/ + $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi + $(INSTALL_DATA) ./files/luci/model/cbi/jlu-drcom.lua $(1)/usr/lib/lua/luci/model/cbi/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DATA) ./files/root/etc/init.d/drcom $(1)/etc/init.d/ + $(INSTALL_DIR) $(1)/lib/jlu-drcom + $(INSTALL_DATA) ./files/root/lib/jlu-drcom/newclient.py $(1)/lib/jlu-drcom + $(INSTALL_DATA) ./files/root/lib/jlu-drcom/daemon.py $(1)/lib/jlu-drcom +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/README.md b/README.md new file mode 100644 index 0000000..df0854f --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# luci-app-jlu-drcom +# 简介 +本软件包是基于 [jlu-drcom-client](https://github.com/drcoms/jlu-drcom-client) 开发的吉大Dr.com工具的LuCI界面。方便使用OpenWrt的同学使用。 +# 编译 +将该项目复制到OpenWrt源码的`package`目录下,执行 +``` +make V=s package/luci-app-jlu-drcom/compile +``` +即可编译出软件包。你也可以从本项目的release页面下载预编译软件包。 +# 依赖 +本项目的依赖项为python-light,Python内需包含`subprocess socket hashlib struct`等库。 \ No newline at end of file diff --git a/files/luci/controller/jlu-drcom.lua b/files/luci/controller/jlu-drcom.lua new file mode 100644 index 0000000..c9cb7d6 --- /dev/null +++ b/files/luci/controller/jlu-drcom.lua @@ -0,0 +1,15 @@ +-- +-- Copyright (C) 2017 scsz +-- +-- This is free software, licensed under the GNU Affero General Public License v3.0 +-- See /LICENSE for more information. +-- + +module("luci.controller.jlu-drcom", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/jlu-drcom") then + return + end + entry({"admin","services","jlu-drcom"}, cbi("jlu-drcom"), _("Dr.com"), 60) +end diff --git a/files/luci/i18n/jlu-drcom.zh-cn.po b/files/luci/i18n/jlu-drcom.zh-cn.po new file mode 100644 index 0000000..65754d5 --- /dev/null +++ b/files/luci/i18n/jlu-drcom.zh-cn.po @@ -0,0 +1,39 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "Username" +msgstr "用户名" + +msgid "Password" +msgstr "密码" + +msgid "Dr.com Client for JLU" +msgstr "吉林大学Dr.com认证模块" + +msgid "General Setting" +msgstr "通用设置" + +msgid "MAC adress" +msgstr "MAC地址" + +msgid "Computer name" +msgstr "计算机名" + +msgid "Operating system" +msgstr "操作系统" + +msgid "IP adress" +msgstr "IP地址" + +msgid "The static adress used in WAN." +msgstr "学校分配的静态IP" + +msgid "Reconnect on error" +msgstr "断线重连" + +msgid "Log" +msgstr "日志" + +msgid "Daemon log" +msgstr "守护进程日志" + diff --git a/files/luci/model/cbi/jlu-drcom.lua b/files/luci/model/cbi/jlu-drcom.lua new file mode 100644 index 0000000..2cd648f --- /dev/null +++ b/files/luci/model/cbi/jlu-drcom.lua @@ -0,0 +1,60 @@ +-- +-- Copyright (C) 2017 scsz +-- +-- This is free software, licensed under the GNU Affero General Public License v3.0 +-- See /LICENSE for more information. +-- + +local m, s ,o + +m = Map("jlu-drcom", translate("Dr.com"), translate("Dr.com Client for JLU")) + +s = m:section(TypedSection, "general", translate("General Setting") ) +s.anonymous = true + +o = s:option(Value, "mac", translate("MAC adress")) +o.datatype = "macaddr" + +o = s:option(Value, "name", translate("Computer name")) +o.default = "My Computer" + +o = s:option(Value, "os", translate("Operating system")) +o.default = "Windows 10" + +o = s:option(Value, "ip", translate("IP adress")) +o.datatype = "ipaddr" +o.placeholder = translate("The static adress used in WAN.") + +o = s:option(Value, "username", translate("Username")) + +o = s:option(Value, "password", translate("Password")) +o.password = true + +o = s:option(Flag, "reconnect", translate("Reconnect on error")) +o.default = 1 + +local apply = luci.http.formvalue("cbi.apply") +if apply then + io.popen("/etc/init.d/drcom stop") + io.popen("/etc/init.d/drcom start") +end + +s = m:section(TypedSection, "general", translate("Log")) +s.anonymous = true +o = s:option(TextValue,"log") +o.readonly = true +o.rows = 30 +o.cfgvalue = function() + return luci.sys.exec("tail -n 100 /tmp/drcom.log") +end + +s = m:section(TypedSection, "general", translate("Daemon log")) +s.anonymous = true +o = s:option(TextValue,"daemon_log") +o.readonly = true +o.rows = 15 +o.cfgvalue = function() + return luci.sys.exec("tail -n 100 /tmp/drdaemon.log") +end + +return m diff --git a/files/root/etc/init.d/drcom b/files/root/etc/init.d/drcom new file mode 100644 index 0000000..ddcbb76 --- /dev/null +++ b/files/root/etc/init.d/drcom @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2017 scsz +# +# This is free software, licensed under the GNU Affero General Public License v3.0 +# See /LICENSE for more information. +# +# + +START=99 +STOP=99 + +start() { + python -u /lib/jlu-drcom/daemon.py >/tmp/drdaemon.log & +} + +stop() { + kill -s 9 `pgrep -f newclient.py` + kill -s 9 `pgrep -f daemon.py` +} \ No newline at end of file diff --git a/files/root/lib/jlu-drcom/daemon.py b/files/root/lib/jlu-drcom/daemon.py new file mode 100644 index 0000000..3a8659a --- /dev/null +++ b/files/root/lib/jlu-drcom/daemon.py @@ -0,0 +1,33 @@ +#coding=utf8 +# +# Copyright (C) 2017 scsz +# +# This is free software, licensed under the GNU Affero General Public License v3.0 +# See /LICENSE for more information. +# + +import subprocess +import time + +#load config from /etc/config/jlu-drcom +confile = open("/etc/config/jlu-drcom", "r") +conf = confile.read() +confile.close() +confs = conf.split("\n") +for i in confs: + if i.find("reconnect") > 0: + s = i.find("'") + reconnect = int(i[s+1:-1]) + +f = open("/tmp/drcom.log", "w") +process = subprocess.Popen(["python", "-u", "/lib/jlu-drcom/newclient.py"], stdout=f, stderr=f) +while True: + time.sleep(5) + print(time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())) + "Process running...") + if process.poll() != None: + if reconnect: + print(time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())) + "Restarting process...") + process = subprocess.Popen(["python", "-u", "/lib/jlu-drcom/newclient.py"], stdout=f, stderr=f) + else: + print(time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())) + "Dr.com down! Do nothing.") + break \ No newline at end of file diff --git a/files/root/lib/jlu-drcom/newclient.py b/files/root/lib/jlu-drcom/newclient.py new file mode 100644 index 0000000..87d3618 --- /dev/null +++ b/files/root/lib/jlu-drcom/newclient.py @@ -0,0 +1,427 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import socket, struct, time +from hashlib import md5 +import sys +import os +import random +import time + +# CONFIG +#load config from /etc/config/jlu-drcom +confile = open("/etc/config/jlu-drcom", "r") +conf = confile.read() +confile.close() +confs = conf.split("\n") +for i in confs: + if i.find("mac") > 0: + s = i.find("'") + mac = i[s+1:s+18] + mac = mac.split(":") + mac = int("".join(mac), 16) + if i.find("name") > 0: + s = i.find("'") + host_name = i[s+1:-1] + if i.find("os") > 0: + s = i.find("'") + host_os = i[s+1:-1] + if i.find("ip") > 0: + s = i.find("'") + host_ip = i[s+1:-1] + if i.find("username") > 0: + s = i.find("'") + username = i[s+1:-1] + if i.find("password") > 0: + s = i.find("'") + password = i[s+1:-1] + if i.find("reconnect") > 0: + s = i.find("'") + reconnect = i[s+1:-1] + +server = '10.100.61.3' +#username=''#用户名 +#password=''#密码 +#host_ip = ''#ip地址 +#mac = 0x000000000000#mac地址 +#host_name = 'Computer'#计算机名 +#host_os = 'Windows 10'#操作系统 +CONTROLCHECKSTATUS = '\x20' +ADAPTERNUM = '\x03' +IPDOG = '\x01' +PRIMARY_DNS = '10.10.10.10' +dhcp_server = '0.0.0.0' +AUTH_VERSION = '\x68\x00' +KEEP_ALIVE_VERSION = '\xdc\x02' +# CONFIG_END + +nic_name = '' #Indicate your nic, e.g. 'eth0.2'.nic_name +bind_ip = '0.0.0.0' +#print("Waiting router to boot...") +#time.sleep(10) + +class ChallengeException (Exception): + def __init__(self): + pass + +class LoginException (Exception): + def __init__(self): + pass + +def bind_nic(): + try: + import fcntl + def get_ip_address(ifname): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + return socket.inet_ntoa(fcntl.ioctl( + s.fileno(), + 0x8915, # SIOCGIFADDR + struct.pack('256s', ifname[:15]) + )[20:24]) + return get_ip_address(nic_name) + except ImportError as e: + print('Indicate nic feature need to be run under Unix based system.') + return '0.0.0.0' + except IOError as e: + print(nic_name + 'is unacceptable !') + return '0.0.0.0' + finally: + return '0.0.0.0' + +if nic_name != '': + bind_ip = bind_nic() + +s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +# s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +s.bind((bind_ip, 61440)) + +s.settimeout(3) +SALT = '' +IS_TEST = True +# specified fields based on version +CONF = "/etc/drcom.conf" +UNLIMITED_RETRY = True +EXCEPTION = False +DEBUG = True #log saves to file +LOG_PATH = '/var/log/drcom_client.log' +if IS_TEST: + DEBUG = True + LOG_PATH = 'drcom_client.log' + + +def log(*args, **kwargs): + s = ' '.join(args) + print(s) + if DEBUG: + with open(LOG_PATH,'a') as f: + f.write(s + '\n') + +def challenge(svr,ran): + while True: + t = struct.pack(">5)) + return ret + +def keep_alive_package_builder(number,random,tail,type=1,first=False): + data = '\x07'+ chr(number) + '\x28\x00\x0b' + chr(type) + if first : + data += '\x0f\x27' + else: + data += KEEP_ALIVE_VERSION + data += '\x2f\x12' + '\x00' * 6 + data += tail + data += '\x00' * 4 + #data += struct.pack("!H",0xdc02) + if type == 3: + foo = ''.join([chr(int(i)) for i in host_ip.split('.')]) # host_ip + #CRC + # edited on 2014/5/12, filled zeros to checksum + # crc = packet_CRC(data+foo) + crc = '\x00' * 4 + #data += struct.pack("!I",crc) + foo + '\x00' * 8 + data += crc + foo + '\x00' * 8 + else: #packet type = 1 + data += '\x00' * 16 + return data + +# def packet_CRC(s): +# ret = 0 +# for i in re.findall('..', s): +# ret ^= struct.unpack('>h', i)[0] +# ret &= 0xFFFF +# ret = ret * 0x2c7 +# return ret + +def keep_alive2(*args): + #first keep_alive: + #number = number (mod 7) + #status = 1: first packet user sended + # 2: first packet user recieved + # 3: 2nd packet user sended + # 4: 2nd packet user recieved + # Codes for test + tail = '' + packet = '' + svr = server + ran = random.randint(0,0xFFFF) + ran += random.randint(1,10) + # 2014/10/15 add by latyas, maybe svr sends back a file packet + svr_num = 0 + packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1,True) + while True: + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' send1',packet.encode('hex')) + s.sendto(packet, (svr, 61440)) + data, address = s.recvfrom(1024) + log('[keep-alive2] recv1',data.encode('hex')) + if data.startswith('\x07\x00\x28\x00') or data.startswith('\x07' + chr(svr_num) + '\x28\x00'): + break + elif data[0] == '\x07' and data[2] == '\x10': + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv file, resending..') + svr_num = svr_num + 1 + packet = keep_alive_package_builder(svr_num,dump(ran),'\x00'*4,1, False) + else: + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv1/unexpected',data.encode('hex')) + #log('[keep-alive2] recv1',data.encode('hex')) + + ran += random.randint(1,10) + packet = keep_alive_package_builder(svr_num, dump(ran),'\x00'*4,1,False) + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' send2',packet.encode('hex')) + s.sendto(packet, (svr, 61440)) + while True: + data, address = s.recvfrom(1024) + if data[0] == '\x07': + svr_num = svr_num + 1 + break + else: + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv2/unexpected',data.encode('hex')) + log('[keep-alive2] recv2',data.encode('hex')) + tail = data[16:20] + + + ran += random.randint(1,10) + packet = keep_alive_package_builder(svr_num,dump(ran),tail,3,False) + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' send3',packet.encode('hex')) + s.sendto(packet, (svr, 61440)) + while True: + data, address = s.recvfrom(1024) + if data[0] == '\x07': + svr_num = svr_num + 1 + break + else: + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv3/unexpected',data.encode('hex')) + log('[keep-alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv3',data.encode('hex')) + tail = data[16:20] + log("[keep-alive2]",time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), " keep-alive2 loop was in daemon.") + + i = svr_num + err_count = 0 + while True: + try: + ran += random.randint(1,10) + packet = keep_alive_package_builder(i,dump(ran),tail,1,False) + #log('DEBUG: keep_alive2,packet 4\n',packet.encode('hex')) + log('[keep_alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' send',str(i),packet.encode('hex')) + s.sendto(packet, (svr, 61440)) + data, address = s.recvfrom(1024) + log('[keep_alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv',data.encode('hex')) + tail = data[16:20] + #log('DEBUG: keep_alive2,packet 4 return\n',data.encode('hex')) + + ran += random.randint(1,10) + packet = keep_alive_package_builder(i+1,dump(ran),tail,3,False) + #log('DEBUG: keep_alive2,packet 5\n',packet.encode('hex')) + s.sendto(packet, (svr, 61440)) + log('[keep_alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' send',str(i+1),packet.encode('hex')) + data, address = s.recvfrom(1024) + log('[keep_alive2]',time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), ' recv',data.encode('hex')) + tail = data[16:20] + #log('DEBUG: keep_alive2,packet 5 return\n',data.encode('hex')) + i = (i+2) % 0xFF + time.sleep(20) + keep_alive1(*args) + err_count = 0 + except: + err_count += 1 + if err_count >= 5: + log('[keep_alive2]', time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time())), "FATAL ERROR: CONNECTION ERROR.") + exit() + + +import re +def checksum(s): + ret = 1234 + for i in re.findall('....', s): + ret ^= int(i[::-1].encode('hex'), 16) + ret = (1968 * ret) & 0xffffffff + return struct.pack(' + data += '\00'*4 #your ipaddress 2 + data += '\00'*4 #your ipaddress 3 + data += '\00'*4 #your ipaddress 4 + data += md5sum(data + '\x14\x00\x07\x0b')[:8] #md53 + data += IPDOG + data += '\x00'*4 #delimeter + data += host_name.ljust(32, '\x00') + data += ''.join([chr(int(i)) for i in PRIMARY_DNS.split('.')]) #primary dns + data += ''.join([chr(int(i)) for i in dhcp_server.split('.')]) #DHCP server + data += '\x00\x00\x00\x00' #secondary dns:0.0.0.0 + data += '\x00' * 8 #delimeter + data += '\x94\x00\x00\x00' # unknow + data += '\x06\x00\x00\x00' # os major + data += '\x02\x00\x00\x00' # os minor + data += '\xf0\x23\x00\x00' # OS build + data += '\x02\x00\x00\x00' #os unknown + data += '\x44\x72\x43\x4f\x4d\x00\xcf\x07\x68' + data += '\x00' * 55#unknown string + data += '\x33\x64\x63\x37\x39\x66\x35\x32\x31\x32\x65\x38\x31\x37\x30\x61\x63\x66\x61\x39\x65\x63\x39\x35\x66\x31\x64\x37\x34\x39\x31\x36\x35\x34\x32\x62\x65\x37\x62\x31' + data += '\x00' * 24 + data += AUTH_VERSION + data += '\x00' + chr(len(pwd)) + data += ror(md5sum('\x03\x01'+salt+pwd), pwd) + data += '\x02\x0c' + data += checksum(data+'\x01\x26\x07\x11\x00\x00'+dump(mac)) + data += '\x00\x00' #delimeter + data += dump(mac) + if (len(pwd) / 4) != 4: + data += '\x00' * (len(pwd) / 4)#strange。。。 + data += '\x60\xa2' #unknown, filled numbers randomly =w= + data += '\x00' * 28 + log('[mkpkt]',data.encode('hex')) + return data + +def login(usr, pwd, svr): + import random + global SALT + + i = 0 + while True: + salt = challenge(svr,time.time()+random.randint(0xF,0xFF)) + SALT = salt + packet = mkpkt(salt, usr, pwd, mac) + log('[login] send',packet.encode('hex')) + s.sendto(packet, (svr, 61440)) + data, address = s.recvfrom(1024) + log('[login] recv',data.encode('hex')) + log('[login] packet sent.') + if address == (svr, 61440): + if data[0] == '\x04': + log('[login] loged in') + break + else: + log('[login] login failed.') + exit() + if IS_TEST: + time.sleep(3) + else: + time.sleep(30) + continue + else: + if i >= 5 and UNLIMITED_RETRY == False : + log('[login] exception occured.') + sys.exit(1) + else: + continue + + log('[login] login sent') + #0.8 changed: + return data[23:39] + #return data[-22:-6] + +def keep_alive1(salt,tail,pwd,svr): + foo = struct.pack('!H',int(time.time())%0xFFFF) + data = '\xff' + md5sum('\x03\x01'+salt+pwd) + '\x00\x00\x00' + data += tail + data += foo + '\x00\x00\x00\x00' + log('[keep_alive1] send',data.encode('hex')) + + s.sendto(data, (svr, 61440)) + while True: + data, address = s.recvfrom(1024) + print data.encode('hex') + if data[0] == '\x07': + break + else: + log('[keep-alive1]recv/not expected',data.encode('hex')) + log('[keep-alive1] recv',data.encode('hex')) + +def empty_socket_buffer(): +#empty buffer for some fucking schools + log('starting to empty socket buffer') + try: + while True: + data, address = s.recvfrom(1024) + log('recived sth unexpected',data.encode('hex')) + if s == '': + break + except: + # get exception means it has done. + log('exception in empty_socket_buffer') + pass + log('emptyed') +def daemon(): + with open('/var/run/jludrcom.pid','w') as f: + f.write(str(os.getpid())) + +def main(): + if not IS_TEST: + daemon() + execfile(CONF, globals()) + log("auth svr:"+server+"\nusername:"+username+"\npassword:"+password+"\nmac:"+str(hex(mac))) + log(bind_ip) + while True: + try: + package_tail = login(username, password, server) + except LoginException: + continue + log('package_tail',package_tail.encode('hex')) + #keep_alive1 is fucking bullshit! + empty_socket_buffer() + keep_alive1(SALT,package_tail,password,server) + keep_alive2(SALT,package_tail,password,server) + +if __name__ == "__main__": + main()