def handler_timeout(self): self.tout.cancel() if self.pgdebug > 0: print("in handler_timeout %s" % self.name) #print( "handler_timeout log %d", self.pglog) if self.pglog > 0: pysyslog.syslog("Timeout on " + " " + str(self.par.client_address)) #print(dir(self)) #print(dir(self.par)) rrr = ["ERR", "Timeout occured, disconnecting."] #print( self.par.client_address, self.par.server.socket) try: #print("ekey", self.par.ekey) self.putencode(rrr, self.par.ekey) except: support.put_exception("putdata") # Force closing connection time.sleep(1) try: self.par.request.shutdown(socket.SHUT_RDWR) except: support.put_exception("on sending timeout shutdown")
def handle(self): if conf.mem: tracemalloc.start() try: while 1: ret = self.datahandler.handle_one(self) if not ret: break ret2 = self.statehandler.run_state(ret) if ret2: response2 = ["err", "Too many tries, disconnecting."] self.datahandler.putencode(response2, self.statehandler.resp.ekey) break except: #print( sys.exc_info()) support.put_exception("state handler") if self.verbose: print("Connection closed on", self.name) if conf.mem: #print( "Memory trace") snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno') print("[ Top 10 ]") for stat in top_stats[:10]: print(stat)
def get_stat_func(self, strx): fname = "" aaa = " " #print("stat_func", strx[1]) dname = support.unescape(strx[1]) #print("stat_func", strx[1], dname) dname2 = self.resp.cwd + "/" + self.resp.dir + "/" + dname dname2 = support.dirclean(dname2) response = ["OK"] response.append(strx[1]) try: sss = os.stat(dname2) for aa in sss: response.append(str(aa)) except OSError: support.put_exception("stat") #print( sys.exc_info()) response = ["ERR", str(sys.exc_info()[1])] except: response = ["ERR", "Must specify file name"] #print( sys.exc_info()) self.resp.datahandler.putencode(response, self.resp.ekey)
def get_ls_func(self, strx): dname = "" sss = "" if len(strx) < 2: strx.append(".") try: dname = support.unescape(strx[1]) except: pass dname2 = self.resp.cwd + "/" + self.resp.dir + "/" + dname dname2 = support.dirclean(dname2) #print("dname2", dname2) response = ["OK"] try: ddd = os.listdir(dname2) for aa in ddd: try: aaa = dname2 + "/" + aa if not stat.S_ISDIR(os.stat(aaa)[stat.ST_MODE]): # Escape spaces response.append(aa) #support.escape(aa)) except: print("Cannot stat ", aaa, str(sys.exc_info()[1])) except: support.put_exception("ls ") response = ["ERR", "No such directory."] #print("response", response) self.resp.datahandler.putencode(response, self.resp.ekey)
def putdata(self, response, key="", rand=True): ret = "" response2 = "" rstr = Random.new().read(random.randint(14, 24)) xstr = Random.new().read(random.randint(24, 36)) datax = [rstr, response, xstr] #print ("server key reply:", key[:16]) #print ("server dats:", datax[:16]) dstr = self.wr.wrap_data(key, datax) if self.pgdebug > 5: print("server reply:", dstr) pass try: #print ("putdata type:", type(dstr)) if type(dstr) == type(""): response2 = bytes(dstr, "cp437") else: response2 = dstr #if self.pgdebug > 2: # print ("assemble:", type(response2), response2 ) # Send out our special buffer (short)len + (str)message if sys.version_info[0] < 3: strx = struct.pack("!h", len(response2)) + response2 else: strx = struct.pack("!h", len(response2)) + response2 #if self.pgdebug > 2: # print ("sending: '", strx ) # + strx.decode("cp437") + "'") ret = self.par.request.send(strx) if self.tout: self.tout.cancel() self.tout = threading.Timer(self.timeout, self.handler_timeout) self.tout.start() except: sss = "While in Put Data: " + str(response)[:24] support.put_exception(sss) #self.resp.datahandler.putdata(sss, self.statehand.resp.ekey) if self.tout: self.tout.cancel() ret = -1 raise return ret
def get_fget_func(self, strx): dname = "" if len(strx) == 1: response = ["ERR", "Must specify file name."] self.resp.datahandler.putencode(response, self.resp.ekey) return dname = support.unescape(strx[1]) dname2 = self.resp.cwd + "/" + self.resp.dir + "/" + dname dname2 = support.dirclean(dname2) if not os.path.isfile(dname2): response = ["ERR", "File does not exist.", dname] self.resp.datahandler.putencode(response, self.resp.ekey) return flen = 0 try: flen = os.stat(dname2)[stat.ST_SIZE] fh = open(dname2, "rb") except: support.put_exception("fget") response = ["ERR", "Cannot open file.", dname] self.resp.datahandler.putencode(response, self.resp.ekey) return response = ["OK", str(flen)] self.resp.datahandler.putencode(response, self.resp.ekey) # Loop, break when file end or transmission error while 1: try: buff = fh.read(pyservsup.buffsize) blen = len(buff) except: print("Cannot read local file", sys.exc_info()) break try: ret = self.resp.datahandler.putencode([ str(blen), buff, ], self.resp.ekey, False) except: break if ret == 0: break if blen == 0: break # Lof and set state to IDLE xstr = "Sent file: '" + dname + \ "' " + str(flen) + " bytes" #print(xstr) pysyslog.syslog(xstr)
def run_state(self, strx): ret = None if self.pgdebug > 5: print("Run state data: '" + strx + "'") try: ret = self._run_state(strx) except: support.put_exception("While in run state(): " + str(self.curr_state)) sss = "ERR on processing request." self.resp.datahandler.putdata(sss, self.resp.ekey) ret = False return ret
def handle_one(self, par): #print("Handle_one", par, par.ekey[:16]) self.par = par try: cur_thread = threading.currentThread() self.name = cur_thread.getName() state = 0 xlen = [] newdata = "" ldata = "" while 1: if state == 0: xdata = self.getdata(max(2 - len(ldata), 0)) if len(xdata) == 0: break ldata += xdata if len(ldata) == 2: state = 1 xlen = struct.unpack("!h", ldata.encode("cp437")) #if self.pgdebug > 7: # print( "db got len =", xlen) elif state == 1: data2 = self.getdata(max(xlen[0] - len(newdata), 0)) if len(data2) == 0: break newdata += data2 #if self.pgdebug > 7: # print( "db got data, len =", len(data2)) if len(newdata) == xlen[0]: state = 3 elif state == 3: # Done, return buffer state = 0 break else: if self.pgdebug > 0: print("Unkown state") if self.tout: self.tout.cancel() except: support.put_exception("While in Handshake: ") #if self.pgdebug > 8: # print("got data: '" + newdata + "'") #return newdata.encode("cp437") #return bytes(newdata, "cp437") return newdata
def get_lsd_func(self, strx): sss = "" dname2 = self.resp.cwd + "/" + self.resp.dir + "/" dname2 = support.dirclean(dname2) response = ["OK"] try: ddd = os.listdir(dname2) for aa in ddd: if stat.S_ISDIR(os.stat(aa)[stat.ST_MODE]): # Escape spaces response.append(aa) # += support.escape(aa) + " " #response = ["OK" + sss] except: support.put_exception("lsd") response = ["ERR" + str(sys.exc_info()[1])] self.resp.datahandler.putencode(response, self.resp.ekey)
def get_cd_func(self, strx): org = self.resp.dir try: dname = support.unescape(strx[1]) if dname == "..": self.resp.dir = support.chup(self.resp.dir) elif dname[0] == "/": self.resp.dir = dname else: self.resp.dir += "/" + dname self.resp.dir = support.dirclean(self.resp.dir) dname2 = self.resp.cwd + "/" + self.resp.dir dname2 = support.dirclean(dname2) if os.path.isdir(dname2): response = ["OK ", self.resp.dir] else: # Back out self.resp.dir = org response = ["ERR", "Directory does not exist"] except: support.put_exception("cd") response = ["ERR", "Must specify directory name"] self.resp.datahandler.putencode(response, self.resp.ekey)
def hexdump(strin, llen=16): if type(strin) != str and type(strin) != bytes: print("Cannot dump ", type(strin), "printing instead") return str(strin) if sys.version_info[0] < 3: #strx = strin.decode("cp437") strx = strin else: if type(strin) == str: strx = bytes(strin, "cp437") else: strx = strin outx = "" lenx = len(strx) try: for aa in range(int(lenx / 16)): outx += " " for bb in range(16): try: if sys.version_info[0] < 3: outx += "%02x " % ord(strx[aa * 16 + bb]) else: outx += "%02x " % strx[aa * 16 + bb] except: support.put_exception("hex ??") outx += "?? " outx += " | " for cc in range(16): if sys.version_info[0] < 3: chh = chr(ord(strx[aa * 16 + cc])) else: chh = chr(strx[aa * 16 + cc]) if isprint(chh): outx += "%c" % chh else: outx += "." outx += " | \n" # Print remainder on last line remn = lenx % 16 divi = int(lenx / 16) if remn: outx += " " for dd in range(remn): try: if sys.version_info[0] < 3: outx += "%02x " % ord(strx[divi * 16 + dd]) else: outx += "%02x " % strx[divi * 16 + dd] pass except: support.put_exception("hexnum ??") outx += "?? " outx += " " * ((16 - remn) * 3) outx += " | " for cc in range(remn): if sys.version_info[0] < 3: chh = chr(ord(strx[divi * 16 + cc])) else: chh = chr(strx[divi * 16 + cc]) if isprint(chh): outx += "%c" % chh else: outx += "." outx += " " * ((16 - remn)) outx += " | \n" except: print("Error on hexdump", sys.exc_info()) support.put_exception("hexdump") return (outx)
print(hand.pkey) if conf.pgdebug > 2: print("Server response:", "'" + hhh.hexdigest() + "'") if conf.showkey or conf.pgdebug > 5: #print("Key:") print(hand.pkey) try: hand.pubkey = RSA.importKey(hand.pkey) if conf.pgdebug > 4: print(hand.pubkey) except: print("Cannot import public key.") support.put_exception("import key") hand.client(["quit"]) hand.close() sys.exit(0) #if conf.pgdebug > 1: print("Got pub key", hand.pubkey, "size =", hand.pubkey.size()) # Generate communication key conf.sess_key = Random.new().read(512) sss = SHA512.new() sss.update(conf.sess_key) cipher = PKCS1_v1_5.new(hand.pubkey) #print ("cipher", cipher.can_encrypt())
# args = conf.comline(sys.argv[1:]) if len(args) == 0: ip = '127.0.0.1' else: ip = args[0] hand = pyclisup.CliSup() hand.verbose = conf.verbose hand.pgdebug = conf.pgdebug try: resp2 = hand.connect(ip, conf.port) except: support.put_exception("On connect") print( "Cannot connect to:", ip + ":" + str(conf.port), sys.exc_info()[1]) sys.exit(1) #if conf.quiet == False: # print ("Server initial:", resp2) resp = hand.client(["ver"]) if conf.quiet == False: print ("Server response:", resp) hand.client(["quit"]) hand.close() sys.exit(0)
def get_akey_func(self, strx): if pgdebug > 1: print("get_akey_func() called") ddd = os.path.abspath("keys") try: self.keyfroot = pyservsup.pickkey(ddd) except: print("No keys generated yet.", sys.exc_info()[1]) support.put_exception("no keys key") rrr = ["ERR", "No keys yet. Run keygen"] self.resp.datahandler.putencode(rrr, self.resp.ekey) return if pgdebug > 2: print("self.keyfroot", self.keyfroot) try: # Do public import fp = open(ddd + "/" + self.keyfroot + ".pub", "rb") self.keyx = fp.read() fp.close() try: self.pubkey = RSA.importKey(self.keyx) except: print("Cannot read key:", self.keyx[:12], sys.exc_info()[1]) support.put_exception("import key") rrr = ["ERR", "Cannot read public key"] self.resp.datahandler.putencode(rrr, self.resp.ekey) return if pgdebug > 5: print("Key read: \n'" + self.keyx.decode("cp437") + "'\n") # Do private import; we are handleing it here, so key signals errors fp2 = open(ddd + "/" + self.keyfroot + ".pem", "rb") self.keyx2 = fp2.read() fp2.close() try: self.privkey = RSA.importKey(self.keyx2) self.priv_cipher = PKCS1_v1_5.new(self.privkey) except: print("Cannot create private key:", self.keyx2[:12], sys.exc_info()[1]) support.put_exception("import private key") rrr = ["ERR", "Cannot create private key"] self.resp.datahandler.putencode(rrr, self.resp.ekey) return if pgdebug > 5: print("Key read: \n'" + self.keyx.decode("cp437") + "'\n") hh = SHA512.new() hh.update(self.keyx) if pgdebug > 3: print("Key digest: \n'" + hh.hexdigest() + "'\n") # Deliver the answer in two parts: rrr = ["OK", "%s" % hh.hexdigest(), self.keyx] self.resp.datahandler.putencode(rrr, self.resp.ekey) except: print("Cannot read key:", self.keyfroot, sys.exc_info()[1]) support.put_exception("read key") rrr = ["ERR", "cannot open keyfile."] self.resp.datahandler.putencode(rrr, self.resp.ekey)
def start_session(self, conf): resp = self.client(["akey"]) if resp[0] != "OK": print("Error on getting key:", resp[1]) self.client(["quit"]) self.close() sys.exit(0) if conf.verbose: print("Got hash:", "'" + resp[1] + "'") pass hhh = SHA512.new() hhh.update(resp[2]) if conf.pgdebug > 3: print("Hash1: '" + resp[1] + "'") print("Hash2: '" + hhh.hexdigest() + "'") # Remember key if hhh.hexdigest() != resp[1]: print("Tainted key, aborting.") self.client(["quit"]) self.close() sys.exit(0) self.pkey = resp[2] #print("Key response:", resp[0], resp[2][:32], "...") if conf.pgdebug > 4: print(self.pkey) if conf.pgdebug > 2: print("Server response:", "'" + hhh.hexdigest() + "'") try: self.pubkey = RSA.importKey(self.pkey) if conf.pgdebug > 4: print(self.pubkey) except: print("Cannot import public key.") support.put_exception("import key") self.client(["quit"]) self.close() sys.exit(0) if conf.pgdebug > 1: print("Got ", self.pubkey, "size =", self.pubkey.size()) # Generate communication key conf.sess_key = Random.new().read(512) sss = SHA512.new() sss.update(conf.sess_key) cipher = PKCS1_v1_5.new(self.pubkey) #print ("cipher", cipher.can_encrypt()) if conf.pgdebug > 2: support.shortdump("conf.sess_key", conf.sess_key) if conf.sess_key: sess_keyx = cipher.encrypt(conf.sess_key) ttt = SHA512.new() ttt.update(sess_keyx) if conf.pgdebug > 2: support.shortdump("sess_keyx", sess_keyx) else: session_keyx = "" #print("Key Hexdigest", ttt.hexdigest()[:16]) resp3 = self.client( ["sess", sss.hexdigest(), ttt.hexdigest(), sess_keyx], "", False) #print("Sess Response:", resp3[1]) if resp3[0] != "OK": print("Error on setting session:", resp3[1]) self.client(["quit"]) self.close() return None #self.session return resp3 # EOF