Example #1
0
File: server.go Project: CPSSD/MDFS
func newUser(conn net.Conn, r *bufio.Reader, w *bufio.Writer, md *MDService) (err error) {

	// get the uuid for the new user

	var newUser utils.User
	err = md.userDB.Update(func(tx *bolt.Tx) (err error) {

		// Retrieve the users bucket.
		// This should be created when the DB is first opened.
		b := tx.Bucket([]byte("users"))

		// Generate ID for the user.
		// This returns an error only if the Tx is closed or not writeable.
		// That can't happen in an Update() call so I ignore the error check.
		id, _ := b.NextSequence()
		newUser.Uuid = uint64(id)
		idStr := strconv.FormatUint(id, 10)

		// receive the username	and public key for the new user
		uname, _ := r.ReadString('\n')
		pubKN, _ := r.ReadString('\n')
		pubKE, _ := r.ReadString('\n')

		newUser.Uname = strings.TrimSpace(uname)
		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))

		fmt.Println("\tNew user: "******"\tRecieved " + newUser.Uname + "'s public key")

		// Marshal user data into bytes.
		buf, err := json.Marshal(newUser)
		if err != nil {
			return err
		}

		fmt.Println("\tSending UUID " + idStr + " to " + newUser.Uname)
		w.WriteString(idStr + "\n")
		w.Flush()

		// Persist bytes to users bucket.
		return b.Put(itob(newUser.Uuid), buf)
	})

	return err
}
Example #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
}
Example #3
0
func setup(r *bufio.Reader, w *bufio.Writer, thisUser *utils.User) (err error) {

	fmt.Println("Please enter your username:\n")
	fmt.Print("Username: "******"/.mdfs/client/" + uname + "/.user_data")
	if exists != nil { // not exist

		// Make sure the local user dir exists
		err := os.MkdirAll(utils.GetUserHome()+"/.mdfs/client/"+uname+"/files", 0777)
		if err != nil {
			return err
		}

		// notify mdservice that this is a new user (SENDCODE 10)
		err = w.WriteByte(10) //
		if err != nil {
			return err
		}
		w.Flush()

		// local user setup
		utils.GenUserKeys(utils.GetUserHome() + "/.mdfs/client/" + uname + "/.private_key")

		err = utils.FileToStruct(utils.GetUserHome()+"/.mdfs/client/"+uname+"/.private_key", &thisUser.Privkey)
		if err != nil {
			return err
		}
		thisUser.Pubkey = &thisUser.Privkey.PublicKey

		// send username and keys
		w.WriteString(uname + "\n")
		w.Write([]byte(thisUser.Pubkey.N.String() + "\n"))
		w.Write([]byte(strconv.Itoa(thisUser.Pubkey.E) + "\n"))
		w.Flush()

		uuid, _ := r.ReadString('\n')
		thisUser.Uuid, err = strconv.ParseUint(strings.TrimSpace(uuid), 10, 64)
		if err != nil {
			return err
		}

		err = utils.StructToFile(*thisUser, utils.GetUserHome()+"/.mdfs/client/"+uname+"/.user_data")
		if err != nil {
			return err
		}

		//NOTE: NOT COMPLETE

	} else {

		err = utils.FileToStruct(utils.GetUserHome()+"/.mdfs/client/"+uname+"/.user_data", &thisUser)
		w.WriteByte(9)
		w.Flush()

	}

	return err

	// if none exist, will send a code to mdserv to notify as new user,
	// and get a uuid, create userkeys, send pubkey to mdserv

}