Beispiel #1
0
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
}
Beispiel #2
0
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
}