示例#1
0
def get_handler(arg):
    public = None
    uri = ""
    if arg.cap:
        cap = arg.cap.split(":")
    else:
        # TODO this should read the current dir to find out the URI for the file
        with open('private/files.txt', "r") as f:
            for line in f:
                ind = line.find(arg.name)
                # here assumes the files have different names
                # TODO check for the same names that are substring of the other
                if ind != -1:
                    key_ind = line.find("|")+1
                    line = line[key_ind:] 
                    cap = line.split(":")
                    file_name = arg.name
                    abs_path = os.path.abspath(pjoin('private/keys/', file_name))
                    # check if this file was created by the user
                    # TODO the public key should be in the file we get
                    if os.path.exists(abs_path):
                        with open('private/keys/'+arg.name+"public", "r") as f:
                            public = f.read() 
                    break
    
    if cap[0] == FILE_WRITE_CAP or cap[0] == DIR_WRITE_CAP:
        h = crypto.my_hash(cap[1])[:16]
        h = crypto.my_hash(h)
        uri = capToString((cap[0], h, cap[2]))
    elif cap[0] == DIR_READ_CAP or cap[0] == FILE_WRITE_CAP:
        h = crypto.my_hash(cap[1])
        uri = capToString((cap[0], h, cap[2]))
    else:
        uri = ""
    # access the file via the write-cap
    cipher = get_data(uri) 
    data_ar = cipher.split(SPLIT_SYMBOL)
    sign = data_ar[1]
    data = data_ar[0]
    public = data_ar[2]
    try:
        assert(data_ar[3] == crypto.my_hash(public))
        valid = crypto.verify_RSA(public, sign, data)
        print "Valid: ", valid
        assert(valid)
    except AssertionError  as e:
        print "Data invalid"
        return
    # generate the AES decryption key and decrypt
    salt = "a"*16
    s = str(cap[1] + salt)
    hashed_key = crypto.my_hash(s)
    ptext = crypto.decrypt(data, hashed_key[:16])   
    txt = ptext.find(SPLIT_SYMBOL)
    return ptext[:txt]
 def do_POST(s):
     
     """Respond to a POST request."""
     s.send_response(200)
     s.send_header("Content-type", "text/html")
     s.end_headers()
     
     # before doing post, first check integrity, then check permissions
     # if the file exists, the path must be the write capability
     length = s.headers['content-length']
     data = s.rfile.read(int(length))
     decoded = data[5:]
     decoded = urllib.unquote(decoded).decode("utf8")
     decoded = DecodeAES(decoded)
     data_ar = decoded.split(SPLIT_SYMBOL)
     sign = data_ar[1]
     data = data_ar[0]
     # obtain public key from the data and verify
     public = data_ar[2]
      
     cap = s.path[s.path.rfind("/") + 1:].split(":")
     h = crypto.my_hash(public)
     print cap
     print data_ar
     if h != data_ar[3] or h[:16] != cap[2]:
         send_error(s)
         return
     valid = crypto.verify_RSA(public, sign, data)
     print "Valid: ", valid 
     if not valid:
         send_error(s)
         return
     # allow write if the file does not exist or
     # when you present write cap
     file_name = crypto.my_hash(crypto.my_hash(cap[1]))
     store_path = pjoin(curdir+DATALOCATION, file_name)
     print "STORE PATH: ", store_path
     # TODO with the directory structure, notify the server of the created files
     # so that it can check if this store_path is ever created
     if os.path.exists(store_path):
         print "PATH EXISTS" 
         with open(store_path, 'w') as fh:
             fh.write(decoded)
     else:
         print "NO PATH" 
         with open(store_path, 'w') as fh:
             fh.write(decoded)
示例#3
0
def put_handler(arg):
    if arg.writecap:
        # putting with a cap requires
        # 1) Getting the encrypted private key
        # 2) Decrypting it, and using it to sign the updated data
        # 3) Signing the encryption of the updated data with the private key
        cap = arg.writecap.split(":")
        cipher = get_data(arg.writecap) 
        
        (data, private, public) = crypto.unpackage_data(cap, cipher)
    
    else:
        with open("private/root_dir.cap", 'r') as f:
            line = f.read()
            if line and line != "\n":
                line = line[line.find("|")+1:].strip("\n")
                root_cap = line.split(":")
                cipher = get_data(line)
                (data, root_private, root_public)= crypto.unpackage_data(root_cap, cipher) 
                data = json.loads(data)
 
        # here cap is (my_hash(private_key), my_hash(public_key))
        (private, public, cap) = crypto.generate_RSA()
        cap = [FILE_WRITE_CAP, cap[0], cap[1]]
        # put name in dir
        data[arg.name] = capToString(cap)         
        # update root dir data 
        data = json.dumps(data) 
        data = crypto.package_data(data, root_cap, root_private, root_public)
        print_capabilities(root_cap)
        post_data(data, capToString(root_cap))
        # save the cap in a private file 
        with open('private/files.txt', "a") as f:
            c = arg.name+ "|" + capToString(cap)+ "\n"
            f.write(c)
        # TODO get rid of key storage by making get to the server via URI after createion
        # save the private key in a file 
        with open('private/keys/'+arg.name+"public", "w") as f:
            f.write(public)
        with open('private/keys/'+arg.name+"private", "w") as f:
            f.write(private)
    data = arg.data
    data = crypto.package_data(data, cap, private, public)
    print_capabilities(cap)
    h = crypto.my_hash(cap[1])[:16]
    cap[1] = crypto.my_hash(h)
    post_data(data, capToString(cap))
 def do_GET(s):
     # TODO different responses to write, read, none
     """Respond to a GET request."""
     s.send_response(200)
     s.send_header("Content-type", "text/html")
     s.end_headers()
     # determine the capability: write, read, or none
     name = s.path[s.path.rfind("/")+1:]
     cap = name.split(":") 
     file_name = crypto.my_hash(cap[1])
     print "kar server file name: ", file_name
     print "cap: ", cap
     abs_path = os.path.abspath(pjoin(curdir+DATALOCATION, file_name))
     if os.path.exists(abs_path):
         # it is read cap
         print "READ"
         s.wfile.write("<html><head><title>READ CAP PRESENTED</title></head>")
         s.wfile.write("<body><p>You do not have write privileges.</p>")
         s.wfile.write("<p>You accessed path: %s</p>" % s.path)
         s.wfile.write("<p>File exists: %s</p>" % pjoin(curdir+DATALOCATION, s.path))
         content = ""
         with open(abs_path, 'r') as fh:
             content =  fh.read()  
         s.wfile.write("<p>File content: data=%s</p>" % EncodeAES(content))
         s.wfile.write("</body></html>")
     else:
         file_name = crypto.my_hash(file_name)
         abs_path = os.path.abspath(pjoin(curdir+DATALOCATION, file_name))
         if os.path.exists(abs_path):
             # it is a write cap
             print "WRITE"
             s.wfile.write("<html><head><title>WRITE CAP PRESENTED</title></head>")
             s.wfile.write("<body><p>Thanks for updating the file</p>")
             s.wfile.write("<p>You accessed path: %s</p>" % s.path)
             s.wfile.write("<p>File exists: %s</p>" % pjoin(curdir+DATALOCATION, s.path))
             content = ""
             with open(abs_path, 'r') as fh:
                 content =  fh.read()  
             s.wfile.write("<p>File content: data=%s</p>" % EncodeAES(content))
             s.wfile.write("</body></html>")
         else:
             # it is nothing
             print "NOTHING"
             s.wfile.write("<html><head><title> ERROR </title></head>")
             s.wfile.write("<body><p>Can't access</p>")
             s.wfile.write("</body></html>")
示例#5
0
def print_capabilities(cap):
    if cap[0] == FILE_WRITE_CAP:
        t = "file"
        r = FILE_READ_CAP
    elif cap[0] == DIR_WRITE_CAP:
        t = "directory"
        r = DIR_READ_CAP
    else:
        t = "unknown"
        r = "unknown"
    # double hash the key to get the file name
    h = crypto.my_hash(cap[1])[:16]
    file_name = crypto.my_hash(h)
    write = capToString(cap) 
    print "Write cap for the %s is: %s" % (t, write)
    read = capToString(cap)
    print "Read cap for the %s is: %s" % (t, capToString((r, h, cap[2])))
def get_handler(arg):
    public = None
    uri = ""
    if arg.cap:
        uri = arg.cap
        cap = uri.split(":")
    else:
        # TODO this should read the current dir to find out the URI for the file
        with open('private/files.txt', "r") as f:
            for line in f:
                ind = line.find(arg.name)
                # here assumes the files have different names
                # TODO check for the same names that are substring of the other
                if ind != -1:
                    key_ind = line.find("|")+1
                    line = line[key_ind:] #splitting the file name from cap
                    cap = line.split(":")
                    uri = cap[0]+":"+cap[1]+":"+cap[2]
                    file_name = arg.name
                    abs_path = os.path.abspath(pjoin('private/keys/', file_name))
                    # check if this file was created by the user
                    # the public key should be in the file we get
                    if os.path.exists(abs_path):
                        with open('private/keys/'+arg.name+"public", "r") as f:
                            public = f.read() 
                    break  #creating the public private keys
    # access the file via the write-cap
    cipher = get_data(uri) 
    data_ar = cipher.split(SPLIT_SYMBOL)
    sign = data_ar[1]
    data = data_ar[0]
    public = data_ar[2]
    
    assert(data_ar[3] == crypto.my_hash(public))

    valid = crypto.verify_RSA(public, sign, data)
    print "Valid: ", valid
    if valid:
        # generate the AES decryption key and decrypt
        salt = "a"*16
        s = str(cap[1] + salt)
        hashed_key = crypto.my_hash(s)
        ptext = crypto.decrypt(data, hashed_key[:16])   
        txt = ptext.find(SPLIT_SYMBOL)
        return ptext[:txt]
    return None
def put_handler(arg):
    if arg.writecap:
        # putting with a cap requires
        # 1) Getting the encrypted private key
        # 2) Decrypting it, and using it to sign the updated data same signature fro authenticity
        # 3) Signing the encryption of the updated data with the private key
        cap = arg.writecap.split(":")
        cipher = get_data(arg.writecap) 
        data_ar = cipher.split(SPLIT_SYMBOL)
        sign = data_ar[1]
        data = data_ar[0]
        public = data_ar[2]
        assert(data_ar[3] == crypto.my_hash(public))

        valid = crypto.verify_RSA(public, sign, data)
        print "Valid: ", valid
        if valid:
            # generate the AES decryption key and decrypt
            salt = "a"*16
            s = str(cap[1] + salt)
            hashed_key = crypto.my_hash(s)
            ptext = crypto.decrypt(data, hashed_key[:16])   
            splitted = ptext.split(SPLIT_SYMBOL)
            raw_data = splitted[0]
            enc_pk = splitted[1]
            private = crypto.decrypt(enc_pk, cap[1])
            data = arg.data
    else:
        # here cap is (my_hash(private_key), my_hash(public_key))
        (private, public, cap) = crypto.generate_RSA()
        cap = [FILE_WRITE_CAP, cap[0], cap[1]]
        # save the cap in a private file 
        with open('private/files.txt', "a") as f:
            c = arg.name+ "|" + cap[0] + ":" + cap[1] + ":" + cap[2] + "\n"
            f.write(c)
        # save the private key in a file 
        with open('private/keys/'+arg.name+"public", "w") as f:
            f.write(public)
        with open('private/keys/'+arg.name+"private", "w") as f:
            f.write(private)
        data = arg.data
    # store the encrypted private key in the data
    data = data + SPLIT_SYMBOL + crypto.encrypt(private, cap[1], False)
    # use the read key as an encryption key for the concatted data
    salt = "a"*16
    s = str(cap[1] + salt)
    hashed_key = crypto.my_hash(s)
    # encrypt the data
    data = crypto.encrypt(data, hashed_key[:16], False)
    # sign it with private key
    signature = crypto.sign_data(private, data)
    # FINAL DATA IS
    # enc_data | signature | public_key | hash(public_key)
    data = data +SPLIT_SYMBOL+ signature + SPLIT_SYMBOL + public + SPLIT_SYMBOL + crypto.my_hash(public)

    # double hash the key to get the file name
    file_name = crypto.my_hash(crypto.my_hash(cap[1]))
    write = ":".join(map(str, cap)) 
    print "Write cap for the file is: %s" % write
    cap[0] = FILE_READ_CAP
    cap[1] = crypto.my_hash(cap[1])[:16]
    read = ":".join(map(str, cap)) 
    print "Read cap for the file is: %s" % read
    print "You can access the capability in private/files.txt"
    post_data(data, write)