Beispiel #1
0
    def handle_ticket(self):
	if "service" in self.jdata:
		if "name" in self.jdata:
			#Note the is_server part, if the request comes from one its own servers.
			if (self.jdata["name"] in names or is_server(self.jdata["name"])) and self.jdata["service"] in services:
				session_key = generate_session_key()
				#Cache the users ip address and session key.
				users[str(self.client_address[0])] = (session_key)
				ticket = [session_key]
				#Randomly choose a server for the request service
				server_id = random.choice(services[self.jdata["service"]])
				server_key = server_id[2]
				server_id = (server_id[0], server_id[1])	
				ticket = secure.encrypt_with_key(json.dumps(ticket), server_key)
				jsonresult = {
					"ticket": ticket,
					"session": session_key,
					"server_id": server_id
				}
				#if a known client
				if(self.jdata["name"] in names):
					data = secure.encrypt_with_key(json.dumps(jsonresult), names[self.jdata["name"]])
				else:
					#we have already checked that its a valid server.
					#Just need to extract its password from the config file.
					pwd = extract_password_from_server(self.jdata["name"])
					data = secure.encrypt_with_key(json.dumps(jsonresult), pwd)
				self.request.send(data)
				return

	self.request.send("[]")
Beispiel #2
0
	def handle(self):
		self.data = self.request.recv(1024).strip()
		self.jdata = json.loads(self.data)
		#Ping check
		if "type" in self.jdata:
			if self.jdata["type"] == "ping":
				self.request.send("[]")
				return
		ticket = json.loads(secure.decrypt_with_key(self.jdata["ticket"], password))
		message = secure.decrypt_with_key(self.jdata["message"], ticket[0]).strip()
		#Note that there are all the file server which service that file
		#being returned, this allows the client to keep trying them until it finds
		#one which is live. It also allows the file server to push changes to each of the fileserver
		#when a change is detected.
		self.directory_data = dir_lookup(message)
		#Some weird list comprehensions, too much haskell on the brain.
		server_id = [ [host, port, file_name] for host, port, file_name, pwd in self.directory_data ]
		server_tickets = [ pwd for _,_,_,pwd in self.directory_data ]
		encrypted_ticket = [ secure.encrypt_with_key(json.dumps([ticket[0]]), pwd) for pwd in server_tickets ] 
		client_msg = json.dumps(server_id)
		data = {
				"ticket":encrypted_ticket,
				"message":client_msg
		}
		#Encrypt response with session key
		self.request.send(secure.encrypt_with_key(json.dumps(data), ticket[0]))
Beispiel #3
0
 def handle_open(self, message, session_key):
     data = {"payload": ""}
     newfile = False
     try:
         file_name = message["message"]
         print "Received open request from {0}.".format(file_name)
         f = open(file_name, "rb")
     except IOError:
         # Equivalent of touching a file
         print "{0} doesn't exist".format(file_name)
         if not os.path.exists(os.path.dirname(file_name)):
             os.makedirs(os.path.dirname(file_name))
         open(file_name, "w").close()
         f = open(file_name, "rb")
         newfile = True
     except ValueError:
         print "No Message object on json message"
         data["error"] = "no message type"
     except OSError as e:
         print e
         data["error"] = "io"
     finally:
         b64_text = base64.b64encode(f.read())
         data["payload"] = b64_text
         f.close()
         data["type"] = "read"
         self.request.send(secure.encrypt_with_key(json.dumps(data), session_key))
         if newfile and "relative" in message:
             self.replicate_changes(message["relative"], "")
Beispiel #4
0
 def close(self):
     file.close(self)
     if not self._mode == "r":
         command = "diff {0} {1} | tee {2} ".format(hidden_file_path(self.path), self.path, self.path + ".diff")
         r = os.popen(command)
         server_id, ticket, self.session = self.get_tickets()
         diff_contents = r.read()
         data = {
             "ticket": ticket,
             "request": {
                 "type": "write",
                 "message": os.path.join(server_id[2], self.rpath),
                 "relative": self.rpath,
                 "payload": base64.b64encode(diff_contents),
             },
         }
         data["request"] = secure.encrypt_with_key(json.dumps(data["request"]), self.session)
         result = lookup_fs(data, "", server_id, self.session)
         if result == None:
             raise IOError("Could not write to remote server: filename:%s" % (self.rpath))
         else:
             # Keeps mirrored local copy up to date.
             command = "cp {0} {1}".format(self.path, hidden_file_path(self.path))
             r = os.popen(command)
     unlock_file(self.rpath, self._name, self.password)
Beispiel #5
0
 def handle_ping(self, message, session_key):
     file_name = message["message"]
     if os.path.exists(file_name):
         data = {"type": "ping", "mtime": os.path.getmtime(file_name)}
     else:
         data = {"type": "ping", "error": "The file you requested doesn't exist"}
     self.request.send(secure.encrypt_with_key(json.dumps(data), session_key))
Beispiel #6
0
	def handle(self):
		resp = {"status_code" : 0}
		self.data = self.request.recv(1024).strip()
		try:
			self.jdata = json.loads(self.data)
			#This ping message is for servers trying to
			#make sure its live.
			if "type" in self.jdata:
				if self.jdata["type"] == "ping":
					self.request.send("[]")
					session = None
					return
			session = secure.decrypt_with_key(self.jdata["ticket"], password).strip()
			session = json.loads(session)[0]
			filename = secure.decrypt_with_key(self.jdata["filename"], session).strip()
			filename = secure.decrypt_with_key(self.jdata["filename"], session).strip()
			if "type" in self.jdata:
				if self.jdata["type"] == "ping":
					self.request.send("[]")
					return
				elif self.jdata["type"] == "unlock":
					if filename in locked_files:
						if locked_files[filename] == str(self.client_address[0]) + self.jdata["name"]:
							del locked_files[filename]
							resp["message"] = "Successfully unlocked {0}".format(filename)
							resp["status_code"] = 1
						else:
							resp["message"] = "You don't have the correct permission to unlock this file."
					else:
						resp["message"] = "File is not locked so an unlock is not possible."
				elif self.jdata["type"] == "lock":
					if filename in locked_files:
						if locked_files[filename] == str(self.client_address[0]) + self.jdata["name"]:
							resp["message"] = "You already have the lock for {0}".format(filename)
							resp["status_code"] = 1
						else:
							resp["message"] = "Filename {0} is locked. Unable to access.".format(filename)	
					else:
						locked_files[filename] = str(self.client_address[0]) + self.jdata["name"]
						resp["message"] = "Filename {0} successfully locked.".format(filename)
						resp["status_code"] = 1
			else:
				resp["message"] = "Incorrect message parameters."
		except ValueError:
			resp["message"] = "Incorrect incoming json message."
		except KeyError:
			resp["message"] = "Incorrect incoming json parameters."
		finally:
			if session:
				jdata= secure.encrypt_with_key(json.dumps(resp), session)
			else:
				jdata = json.dumps(resp)
			self.request.send(jdata)
Beispiel #7
0
 def get_file_from_server(self):
     server_id, ticket, self.session = self.get_tickets()
     data = {
         "ticket": ticket,
         "request": {"type": "open", "relative": self.rpath, "message": os.path.join(server_id[2], self.rpath)},
     }
     data["request"] = secure.encrypt_with_key(json.dumps(data["request"]), self.session)
     check = lookup_fs(data, self.path, server_id, self.session)
     if check == None:
         self.get_file_from_server()
         return
     file.__init__(self, self.path, self._mode)
Beispiel #8
0
 def look_for_changes(self):
     server_id, ticket, self.session = self.get_tickets()
     data = {"ticket": ticket, "request": {"type": "changed", "message": os.path.join(server_id[2], self.rpath)}}
     data["request"] = secure.encrypt_with_key(json.dumps(data["request"]), self.session)
     check = lookup_fs(data, self.path, server_id, self.session)
     # Some server socket error
     if check == None:
         self.look_for_changes()
         return
     local_m_time = os.path.getmtime(self.path)
     if local_m_time < float(check):
         return True
     else:
         return False
Beispiel #9
0
def lookup_ds(message, server_id, ticket, session):
    data = {"message": secure.encrypt_with_key(message, session), "ticket": ticket}
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    received = None
    try:
        sock.connect((server_id[0], int(server_id[1])))
        sock.send(json.dumps(data))
        received = sock.recv(1024)
        received = secure.decrypt_with_key(received, session)
    finally:
        sock.close()
        if received:
            return received
        else:
            return None
Beispiel #10
0
def lookup_ls(filename, request, server_id, ticket, session, name):
    data = {"ticket": ticket, "filename": secure.encrypt_with_key(filename, session), "type": request, "name": name}
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    received = None
    try:
        sock.connect((server_id[0], int(server_id[1])))
        sock.send(json.dumps(data))
        received = sock.recv(1024)
        received = secure.decrypt_with_key(received, session)
    finally:
        sock.close()
        if received:
            # print received
            return json.loads(received)
        else:
            return None
Beispiel #11
0
 def handle_write(self, message, session_key):
     data = {"status": "Received Diff File"}
     try:
         file_name = message["message"]
         print "Writing changes to {0}".format(file_name)
         diff = base64.b64decode(message["payload"])
         if not diff == "":
             patch_output = patch_file(file_name, diff)
             print "Patch output:{0}".format(patch_output)
         else:
             open(file_name, "w").close()
     except ValueError:
         print "Ugh message from user doesn't have the required fields"
         data["error"] = "Input"
     finally:
         data["type"] = "write"
         self.request.send(secure.encrypt_with_key(json.dumps(data), session_key))
         # This server is master, tell the slaves...
         if "relative" in message:
             self.replicate_changes(message["relative"], message["payload"])
Beispiel #12
0
def file_write(file_to_lookup, diff_file_name, name, password, session=None):
	results = get_ticket_for_file(file_to_lookup, name, password)
	if(results == None):
		return None
	tickets, session, servers_id = results
	server_choice = random.randint(0, len(servers_id)-1)
	server_id = servers_id[server_choice]
	ticket = tickets[server_choice]
	contents = open(diff_file_name, "rb").read()
	data = {
		"ticket": ticket,
		"request": {
			"type":"write",
			"message": os.path.join(server_id[2], file_to_lookup),
			"relative": file_to_lookup,
			"payload":base64.b64encode(contents)
		}
	}
	data["request"] = secure.encrypt_with_key(json.dumps(data["request"]), session)
	print lookup_fs(data, "", server_id, session)
	return session
Beispiel #13
0
def file_open(file_to_lookup,  name, password,local_file=None, session=None):
	results = get_ticket_for_file(file_to_lookup, name, password)
	if(results == None):
		return None
	tickets, session, servers_id = results
	server_choice = random.randint(0, len(servers_id)-1)
	server_id = servers_id[server_choice]
	ticket = tickets[server_choice]
	data = {
		"ticket": ticket,
		"request": {
			"type": "open",
			"message":  os.path.join(server_id[2], file_to_lookup)
		}
	}
	data["request"] = secure.encrypt_with_key(json.dumps(data["request"]), session)
	local_file = os.path.join("cached", file_to_lookup)
	try:
		os.makedirs(os.path.dirname(local_file))
	except OSError:
		pass
	print lookup_fs(data, local_file, server_id, session)
	return session
Beispiel #14
0
 def replicate_changes(self, relative, body):
     print "I Am Replicating The Update"
     # Replicate changes. First must get ds entry from
     name = "fs/{0}:{1}".format(HOST, PORT)
     print "Connection AS at {0}:{1}".format(ASHOST, ASPORT)
     results = get_ticket_for_file(relative, name, password, ls_needed=False)
     if results == None:
         return None
     tickets, session, servers_id = results
     print results
     servers_id = [[h, p, f] for h, p, f in servers_id if not (h == HOST and p == str(PORT))]
     for i in range(0, len(servers_id)):
         # Note relative left out to let the file server know that
         # This is being replicated by a file server and doesnt need
         # further replication.
         ticket = tickets[i]
         server_id = servers_id[i]
         data = {
             "ticket": ticket,
             "request": {"type": "write", "message": os.path.join(server_id[2], relative), "payload": body},
         }
         data["request"] = secure.encrypt_with_key(json.dumps(data["request"]), session)
         print lookup_fs(data, "", server_id, session)