func request(r *bufio.Reader, w *bufio.Writer, currentDir string, args []string, thisUser *utils.User) (err error) { // should have args format: // request [remote filename] [local filename] // currently: // request [remote filename] // Local filename can be a relative or absolute path if len(args) < 2 { return err } // START SENDCODE BLOCK err = w.WriteByte(5) w.Flush() if err != nil { panic(err) } // END SENDCODE BLOCK // Send current dir w.WriteString(currentDir + "\n") w.Flush() // Format the file to send w.WriteString(args[1] + "\n") w.Flush() fmt.Println("Requesting: " + path.Join(currentDir, args[1])) success, _ := r.ReadByte() if success == 3 { fmt.Println("You do not have permission to request this file") return nil } else if success != 4 { fmt.Println("Invalid file request") return nil } protected := false enc, _ := r.ReadByte() if enc == 1 { protected = true } success, _ = r.ReadByte() if success != 2 { fmt.Println("No stnodes for your file") return nil } hash, _ := r.ReadString('\n') protocol, _ := r.ReadString('\n') nAddress, _ := r.ReadString('\n') hash = strings.TrimSpace(hash) protocol = strings.TrimSpace(protocol) nAddress = strings.TrimSpace(nAddress) conn, err := net.Dial(protocol, nAddress) if err != nil { fmt.Println("Error connecting to stnode") } ws := bufio.NewWriter(conn) rs := bufio.NewReader(conn) ws.WriteByte(1) bytehash, err := hex.DecodeString(hash) if err != nil { return err } err = utils.WriteHash(ws, bytehash) if err != nil { return err } success, _ = rs.ReadByte() if success != 3 { fmt.Println("File cannot be found on stnode") return err } output := utils.GetUserHome() + "/.mdfs/client/" + thisUser.Uname + "/files/" + path.Base(args[1]) if protected { encrypFile := os.TempDir() + "/" + path.Base(args[1]) utils.ReceiveFile(conn, rs, encrypFile) err = utils.DecryptFile(encrypFile, output, *thisUser) if err != nil { fmt.Println("Your key does not match the lock for this file") return nil } fmt.Println("Protected file successfully unlocked") } else { utils.ReceiveFile(conn, rs, output) } fmt.Println("Successfully received file") fmt.Println("File stored at: " + output) return }
func send(r *bufio.Reader, w *bufio.Writer, currentDir string, args []string, thisUser *utils.User) (err error) { if len(args) < 2 { return err } // Format the file to send (absolute or relative) filepath := "" if path.IsAbs(args[1]) { // if we are trying to send an absolute filepath filepath = args[1] } else { // we must be sending a relative filepath, so calculate the path wd, err := os.Getwd() if err != nil { return err } filepath = path.Join(wd, args[1]) } // ensure the file is existant locally src, err := os.Stat(filepath) if err != nil { fmt.Println("\"" + filepath + "\" does not exist") return nil } else if src.IsDir() { fmt.Println("\"" + filepath + "\" is a directory, not a file") return nil } else { fmt.Println("Sending: \"" + filepath + "\"") } // START SENDCODE BLOCK - tell mdserv we are sending a file err = w.WriteByte(6) w.Flush() if err != nil { panic(err) } // END SENDCODE BLOCK // Send current dir w.WriteString(currentDir + "\n") // Send filename to mdserv w.WriteString(path.Base(filepath) + "\n") w.Flush() // Get fail if file exists already exists, _ := r.ReadByte() if exists == 1 { fmt.Println("Bad send request, check file name again") return nil } else if exists == 3 { fmt.Println("Permission denied") return nil } else if exists != 2 { fmt.Println("Bad reponse from metadata service") return nil } // Encryption or not? if len(args) >= 3 { if args[2] != "--protect" && args[2] != "-p" { fmt.Println("Invalid argument option: \"" + args[2] + "\"") w.WriteByte(2) w.Flush() return nil } w.WriteByte(1) // tell mdserv we are encrypting w.Flush() users := []utils.User{*thisUser} // send len of args w.WriteByte(uint8(len(args) - 3)) w.Flush() for i := 3; i < len(args); i++ { w.WriteString(args[i] + "\n") w.Flush() uuid, _ := r.ReadString('\n') uuid = strings.TrimSpace(uuid) if uuid != "INV" { var newUser utils.User newUser.Uuid, _ = strconv.ParseUint(uuid, 10, 64) // receive the public key for the new user pubKN, _ := r.ReadString('\n') pubKE, _ := r.ReadString('\n') newUser.Pubkey = &rsa.PublicKey{N: big.NewInt(0)} newUser.Pubkey.N.SetString(strings.TrimSpace(pubKN), 10) newUser.Pubkey.E, err = strconv.Atoi(strings.TrimSpace(pubKE)) users = append(users, newUser) } } encrypFile := os.TempDir() + "/" + path.Base(filepath) err = utils.EncryptFile(filepath, encrypFile, users...) if err != nil { return err } filepath = encrypFile fmt.Println("File successfully protected") } else { w.WriteByte(3) // normal continue w.Flush() } // get hash of the file to send to the stnode and mdserv hash, err := utils.ComputeMd5(filepath) if err != nil { panic(err) } //checksum := hex.EncodeToString(hash) // Send hash to mdserv err = utils.WriteHash(w, hash) if err != nil { return err } // See are there stnodes available avail, _ := r.ReadByte() var conns net.Conn for avail != 2 { // Get details of a storage node if file not exists protocol, _ := r.ReadString('\n') nAddress, _ := r.ReadString('\n') protocol = strings.TrimSpace(protocol) nAddress = strings.TrimSpace(nAddress) // connect to stnode conns, err = net.Dial(protocol, nAddress) if err != nil { w.WriteByte(1) w.Flush() } else { // successful connection avail = 3 w.WriteByte(2) w.Flush() break } avail, _ = r.ReadByte() } if avail != 3 { fmt.Println("There were no stnodes available") return nil } defer conns.Close() // create a read and write buffer for the connection ws := bufio.NewWriter(conns) // tell the stnode we are sending a file err = ws.WriteByte(2) if err != nil { return err } // send hash to stnode err = utils.WriteHash(ws, hash) if err != nil { return err } // send file to stnode utils.SendFile(conns, ws, filepath) // Send success/fail to mdserv to log the file send or not w.WriteByte(1) w.Flush() fmt.Println("Successfully sent file") // on failure to send a file, print err return err }