diff options
author | sjtufs <[email protected]> | 2013-09-01 07:31:07 +0800 |
---|---|---|
committer | sjtufs <[email protected]> | 2013-09-01 07:31:07 +0800 |
commit | cd5d54a80a157ca816546e2af3a04a1cff14b5cc (patch) | |
tree | a4e41f60ff5bb023874cf712f102d743bf2ded51 | |
parent | 46dad6a4660d968a4806b108659fad1e43548294 (diff) | |
parent | c2ac1f73431bbcef437aac017465865e5fb086d9 (diff) |
Merge branch 'master' of github.com:Determinant/piztor
-rw-r--r-- | server/piztor/easy_import.py | 82 | ||||
-rw-r--r-- | server/piztor/gen_users.py | 3 | ||||
-rw-r--r-- | server/piztor/mesg_sender.py | 11 | ||||
-rw-r--r-- | server/piztor/prober.py | 17 | ||||
-rw-r--r-- | server/piztor/ptp.rst | 30 | ||||
-rw-r--r-- | server/piztor/ptp_send.py | 35 | ||||
-rw-r--r-- | server/piztor/server.py | 138 |
7 files changed, 249 insertions, 67 deletions
diff --git a/server/piztor/easy_import.py b/server/piztor/easy_import.py new file mode 100644 index 0000000..e103de7 --- /dev/null +++ b/server/piztor/easy_import.py @@ -0,0 +1,82 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from model import * + +path = "root:helloworld@localhost/piztor" + +class UserData: + def __init__(self, username, nickname, password, + comp_no, sec_no, sex, perm, sub): + self.username = username + self.nickname = nickname + self.password = password + self.comp_no = int(comp_no) + self.sec_no = int(sec_no) + self.sex = int(sex) + self.perm = perm + self.sub = sub + +def create_database(): + engine = create_engine('mysql://' + path, echo = True) + Base.metadata.drop_all(engine) + Base.metadata.create_all(engine) + +def find_or_create_group(comp_no, sec_no, session): + gid = UserModel.to_gid(comp_no, sec_no) + q = session.query(GroupInfo).filter(GroupInfo.id == gid) + entry = q.first() + if not entry: + entry = GroupInfo(gid = gid) + return entry + + +def import_user_data(data): + engine = create_engine('mysql://' + path, echo = True) + Session = sessionmaker(bind = engine) + session = Session() + + for user in data: + um = UserModel(username = user.username, + nickname = user.nickname, + sex = user.sex, + comp_no = user.comp_no, + sec_no = user.sec_no, + perm = user.perm) + + for cn, sn in user.sub: + print cn, sn + g = find_or_create_group(int(cn), int(sn), session) + um.sub.append(g) + um.auth = UserAuth(user.password) + um.location = LocationInfo(lat = 0, lng = 0) + session.add(um) + session.commit() + +if __name__ == '__main__': + + from sys import argv, exit + if len(argv) != 2: + print "Usage: " + argv[0] + " FILE" + exit(0) + + data = list() + with open(argv[1], 'r') as f: + while True: + line = f.readline().split() + if len(line) == 0: break + idx = 0 + comp_no = line[3] + sec_no = line[4] + sub = [ (comp_no, sec_no), (comp_no, 0xff) ] + data.append(UserData(username = line[0], + nickname = line[1], + password = line[0], + comp_no = comp_no, + sec_no = sec_no, + sex = line[2], + perm = line[5], + sub = sub)) + + + create_database() + import_user_data(data) diff --git a/server/piztor/gen_users.py b/server/piztor/gen_users.py index 2d4d67b..2fd57b5 100644 --- a/server/piztor/gen_users.py +++ b/server/piztor/gen_users.py @@ -7,4 +7,5 @@ def get_rand_sex(): return randint(0, 1) for i in xrange(100): - print i, i, get_rand_gid(), get_rand_sex() + print i, i, i, 23, 15, get_rand_sex(), 0 + print "23 15" diff --git a/server/piztor/mesg_sender.py b/server/piztor/mesg_sender.py index fb9b5a5..f7df236 100644 --- a/server/piztor/mesg_sender.py +++ b/server/piztor/mesg_sender.py @@ -4,8 +4,8 @@ from time import sleep from sys import argv from ptp_send import * -username = "hello" -password = "world" +username = "yg" +password = "yg" mesg = "niu x push!" #username = "1234567890123456789012" #password = "world12345678901234567890" @@ -20,10 +20,11 @@ if len(argv) == 4: token = user_auth(username, password) -set_marker(token, username, 123.456, 456.123, 0x7fffffff) -#send_text_mesg(token, username, mesg) +update_location(token, username, 31.028616, 121.434661) +update_location(token, username, 31.028616, 121.434661) +set_marker(token, username, 10.028716, 121.545661, 0x7fffffff) +send_text_mesg(token, username, mesg) #send_text_mesg(token, username, "a") #send_text_mesg(token, username, "the last") -#update_location(token, username, 31.028616, 121.434661) logout(token, username) diff --git a/server/piztor/prober.py b/server/piztor/prober.py index 5f57a94..bb2bcd3 100644 --- a/server/piztor/prober.py +++ b/server/piztor/prober.py @@ -18,13 +18,10 @@ if len(argv) == 3: token = user_auth(username, password) - -update_sub(token, username, - [ - (23, 15), (23, 15), (23, 255), (23, 255), - (23, 15), (23, 15), (23, 255), (23, 255), - (23, 15), (23, 15), (23, 255), (23, 255), - (23, 15), (23, 15), (23, 255), (23, 255), - (23, 15), (23, 15), - ]) -user_info(token, username, 23, 15) +change_password(token, username, "ddd", "haha") +#print "Client: " + username + "logged in" +#open_push_tunnel(token, username) +#for i in xrange(100): +# print "Client: " + username + " updateing" +# update_location(token, username, 123.456, 123.456) +## sleep(5) diff --git a/server/piztor/ptp.rst b/server/piztor/ptp.rst index 6d8ff30..4473e5c 100644 --- a/server/piztor/ptp.rst +++ b/server/piztor/ptp.rst @@ -1,4 +1,4 @@ -Piztor Transmission Protocol v2.0a +Piztor Transmission Protocol v2.0c ---------------------------------- - Pull @@ -255,6 +255,28 @@ Piztor Transmission Protocol v2.0a - ``0x01`` for invalid token - ``0x02`` for insufficient level + - Change Password ``0x08`` + + - Request + + :: + + +-------------+-------?b-------+-------?b-------+ + | AUTH_HEAD | OLD_PASSWORD | NEW_PASSWORD | + +-------------+-----string-----+-----string-----+ + + - Response + + :: + + +--------+ + | STATUS | + +--------+ + + - ``0x00`` for success + - ``0x01`` for invalid token + - ``0x03`` for wrong password + - Push Notification - General Request @@ -293,7 +315,7 @@ Piztor Transmission Protocol v2.0a :: - ----+----8b----+----8b-----+----4b----+ - ... | LATITUDE | LONGITUDE | DEADLINE | - ----+----------+-----------+----int---+ + ----+--1b---+----8b----+----8b-----+----4b----+ + ... | LEVEL | LATITUDE | LONGITUDE | DEADLINE | + ----+-uchar-+----------+-----------+----int---+ diff --git a/server/piztor/ptp_send.py b/server/piztor/ptp_send.py index 22f9842..6c3b476 100644 --- a/server/piztor/ptp_send.py +++ b/server/piztor/ptp_send.py @@ -24,7 +24,8 @@ class _SectionSize: LOCATION_ENTRY = USER_ID + LATITUDE + LONGITUDE PADDING = 1 -host = "localhost" #"localhost" +host = "202.120.7.4" +#host = "localhost" port = 2223 def pack_data(optcode, data): @@ -86,14 +87,26 @@ def gen_set_marker(token, username, lat, lng, deadline): data += pack("!ddL", lat, lng, deadline) return pack_data(0x07, data) +def gen_change_password(token, username, old_pass, new_pass): + data = pack("!32s", token) + data += username + data += chr(0) + data += old_pass + data += chr(0) + data += new_pass + data += chr(0) + return pack_data(0x08, data) + def send(data): received = bytes() + from time import time + begin = time() try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) sock.sendall(data) while True: - rd, wr, err = select([sock], [], [], 10) + rd, wr, err = select([sock], [], []) if rd: buff = sock.recv(4096) if len(buff) == 0: @@ -102,7 +115,10 @@ def send(data): else: break finally: + print "closing" + sock.shutdown(1) sock.close() + print "Waited for {} seconds".format(str(time() - begin)) return received def user_auth(username, password): @@ -112,16 +128,15 @@ def user_auth(username, password): if pl != len(resp): logger.error("User authentication: incorrect packet length") print "status: " + str(status) - print "token: " + get_hex(token) - print get_hex(resp[38:]) +# print "token: " + get_hex(token) except error: logger.error("User authentication: can not parse the response") + print get_hex(resp) return token def update_location(token, username, lat, lng): resp = send(gen_update_location(token, username, lat, lng)) - print get_hex(resp) try: pl, optcode, status = unpack("!LBB", resp[:6]) if pl != len(resp): @@ -183,6 +198,16 @@ def set_marker(token, username, lat, lng, deadline): except error: logger.error("Set marker: can not parse the response") +def change_password(token, username, old_pass, new_pass): + resp = send(gen_change_password(token, username, old_pass, new_pass)) + try: + pl, optcode, status = unpack("!LBB", resp) + if pl != len(resp): + logger.error("Change password: incorrect packet length") + print "status: " + str(status) + except error: + logger.error("Change password: can not pase the response") + def open_push_tunnel(token, username): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, port)) diff --git a/server/piztor/server.py b/server/piztor/server.py index 26ccc4b..9435ccc 100644 --- a/server/piztor/server.py +++ b/server/piztor/server.py @@ -63,11 +63,13 @@ class _OptCode: open_push_tunnel = 0x05 send_text_mesg = 0x06 set_marker = 0x07 + change_password = 0x08 class _StatusCode: sucess = 0x00 auth_fail = 0x01 insuf_lvl = 0x02 + wrong_pass = 0x03 class PushData(object): from hashlib import sha256 @@ -87,8 +89,8 @@ class PushLocationData(PushData): self.pack(0x01, struct.pack("!Ldd", uid, lat, lng)) class PushMarkerData(PushData): - def __init__(self, lat, lng, deadline): - self.pack(0x02, struct.pack("!ddl", lat, lng, deadline)) + def __init__(self, perm, lat, lng, deadline): + self.pack(0x02, struct.pack("!Bddl", perm, lat, lng, deadline)) class PushTunnel(object): def __init__(self, uid): @@ -113,7 +115,7 @@ class PushTunnel(object): length, optcode, fingerprint = struct.unpack("!LB32s", data) if front.finger_print != fingerprint: raise PiztorError - logger.info("-- Push data confirmed by client --") + logger.info("-- Push data confirmed by client %s --", str(self.uid)) self.blocked = False self.push() @@ -345,9 +347,9 @@ class UpdateLocationHandler(RequestHandler): except struct.error: raise BadReqError("Update location: Malformed request body") - logger.info("Trying to update location with " - "(token = {0}, username = {1}, lat = {2}, lng = {3})"\ - .format(get_hex(token), username, lat, lng)) +# logger.info("Trying to update location with " +# "(token = {0}, username = {1}, lat = {2}, lng = {3})"\ +# .format(get_hex(token), username, lat, lng)) uauth = RequestHandler.get_uauth(token, username, self.session) # Authentication failure @@ -411,9 +413,9 @@ class UserInfoHandler(RequestHandler): except struct.error: raise BadReqError("User info request: Malformed request body") - logger.info("Trying to get user info with " \ - "(token = {0}, gid = {1})" \ - .format(get_hex(token), gid)) +# logger.info("Trying to get user info with " \ +# "(token = {0}, gid = {1})" \ +# .format(get_hex(token), gid)) uauth = RequestHandler.get_uauth(token, username, self.session) # Auth failure @@ -464,9 +466,9 @@ class UpdateSubscription(RequestHandler): except struct.error: raise BadReqError("Update Subscription: Malformed request body") - logger.info("Trying to update subscription with " - "(token = {0}, username = {1}, grps = {2})"\ - .format(get_hex(token), username, str(sub_list))) +# logger.info("Trying to update subscription with " +# "(token = {0}, username = {1}, grps = {2})"\ +# .format(get_hex(token), username, str(sub_list))) uauth = RequestHandler.get_uauth(token, username, self.session) # Authentication failure @@ -496,9 +498,9 @@ class UserLogoutHandler(RequestHandler): except struct.error: raise BadReqError("User logout: Malformed request body") - logger.info("Trying to logout with " - "(token = {0}, username = {1})"\ - .format(get_hex(token), username)) +# logger.info("Trying to logout with " +# "(token = {0}, username = {1})"\ +# .format(get_hex(token), username)) uauth = RequestHandler.get_uauth(token, username, self.session) # Authentication failure @@ -530,9 +532,9 @@ class OpenPushTunnelHandler(RequestHandler): except struct.error: raise BadReqError("Open push tunnel: Malformed request body") - logger.info("Trying to open push tunnel with " - "(token = {0}, username = {1})"\ - .format(get_hex(token), username)) +# logger.info("Trying to open push tunnel with " +# "(token = {0}, username = {1})"\ +# .format(get_hex(token), username)) uauth = RequestHandler.get_uauth(token, username, self.session) # Authentication failure @@ -565,9 +567,9 @@ class SendTextMessageHandler(RequestHandler): except struct.error: raise BadReqError("Send text mesg: Malformed request body") - logger.info("Trying to send text mesg with " - "(token = {0}, username = {1})"\ - .format(get_hex(token), username)) +# logger.info("Trying to send text mesg with " +# "(token = {0}, username = {1})"\ +# .format(get_hex(token), username)) uauth = RequestHandler.get_uauth(token, username, self.session) # Authentication failure @@ -610,9 +612,9 @@ class SetMarkerHandler(RequestHandler): except struct.error: raise BadReqError("Set marker: Malformed request body") - logger.info("Trying to set marker with " - "(token = {0}, username = {1})"\ - .format(get_hex(token), username)) +# logger.info("Trying to set marker with " +# "(token = {0}, username = {1})"\ +# .format(get_hex(token), username)) uauth = RequestHandler.get_uauth(token, username, self.session) # Authentication failure @@ -636,11 +638,56 @@ class SetMarkerHandler(RequestHandler): if uid == uauth.uid: continue if pt.has_key(uid): tunnel = pt[uid] - tunnel.add(PushMarkerData(lat, lng, deadline)) + tunnel.add(PushMarkerData(u.perm, lat, lng, deadline)) tunnel.push() logger.info("Set marker successfully!") return self.pack(struct.pack("!B", _StatusCode.sucess)) +class ChangePasswordHandler(RequestHandler): + + _optcode = _OptCode.change_password + _max_tr_data_size = _MAX_AUTH_HEAD_SIZE + \ + MAX_PASSWORD_SIZE + \ + _SectionSize.PADDING + \ + MAX_PASSWORD_SIZE + \ + _SectionSize.PADDING + + def handle(self, tr_data, conn): + self.check_size(tr_data) + logger.info("Reading change password data...") + try: + token, = struct.unpack("!32s", tr_data[:32]) + username, tail = RequestHandler.trunc_padding(tr_data[32:]) + if username is None: + raise struct.error + old_pass, tail = RequestHandler.trunc_padding(tail) + new_pass = tail[:-1] + except struct.error: + raise BadReqError("User logout: Malformed request body") + + logger.info("Trying to change password with " + "(token = {0}, username = {1}, old_pass = {2}, new_pass = {3})"\ + .format(get_hex(token), username, old_pass, new_pass)) + + uauth = RequestHandler.get_uauth(token, username, self.session) + # Authentication failure + if uauth is None: + logger.warning("Authentication failure") + return self.pack(struct.pack("!B", _StatusCode.auth_fail)) + if not uauth.check_password(old_pass): + return self.pack(struct.pack("!B", _StatusCode.wrong_pass)) + uauth.set_password(new_pass) + self.session.commit() + logger.info("Password changed successfully!") + + pt = RequestHandler.push_tunnels + uid = uauth.uid + pt[uid].close() + del pt[uid] + uauth.regen_token() + + return self.pack(struct.pack("!B", _StatusCode.sucess)) + class PTP(Protocol, TimeoutMixin): @@ -651,7 +698,8 @@ class PTP(Protocol, TimeoutMixin): UserLogoutHandler, OpenPushTunnelHandler, SendTextMessageHandler, - SetMarkerHandler] + SetMarkerHandler, + ChangePasswordHandler] handler_num = len(handlers) @@ -676,6 +724,25 @@ class PTP(Protocol, TimeoutMixin): logger.info("A new connection is made") self.setTimeout(self.factory.timeout) + def response(self, buff): + try: + h = PTP.handlers[self.optcode]() + reply = h.handle(buff[5:], self) +# logger.info("Wrote: %s", get_hex(reply)) + self.transport.write(reply) + if self.tunnel: + logger.info("Blocking the client...") + self.tunnel.push() + self.length = -1 + return + self.transport.loseConnection() + except BadReqError as e: + logger.warn("Rejected a bad request: %s", str(e)) + self.transport.loseConnection() + except DBCorruptionError: + logger.error("*** Database corruption ***") + + def dataReceived(self, data): self.buff += data self.resetTimeout() @@ -701,25 +768,12 @@ class PTP(Protocol, TimeoutMixin): self.tunnel.on_receive(buff) self.length = -1 return - h = PTP.handlers[self.optcode]() - reply = h.handle(buff[5:], self) - logger.info("Wrote: %s", get_hex(reply)) - self.transport.write(reply) - if self.tunnel: - logger.info("Blocking the client...") - self.tunnel.push() - self.length = -1 - self.setTimeout(None) - return - self.transport.loseConnection() + self.setTimeout(None) + reactor.callFromThread(self.response, buff) + #self.response(buff) except BadReqError as e: logger.warn("Rejected a bad request: %s", str(e)) self.transport.loseConnection() - except DBCorruptionError: - logger.error("*** Database corruption ***") - self.transport.loseConnection() - if self.tunnel is None: - self.transport.loseConnection() def connectionLost(self, reason): if self.tunnel: |